PDA

View Full Version : سوال: خطا در تعریف یک تابع با چند خروجی



SokooteShab1
دوشنبه 24 مرداد 1390, 15:58 عصر
سلام دوستان یک تابع دارم با چند خروجی از نوع string نمی دونم چرا وقتی تابع را از نوع static تعریف نمی کنم با Error زیر مواجه می شم .
Error 97 The out parameter 'Name' must be assigned to before control leaves the current method

این هم کدهام

public void FillClient(int Co, out string Name, out string Family, out string Father)
{
for (int i = 0; i < Co; i++)
{
DataTable dt= ...
if(dt.Rows.Count>0)
{
Name = dt.Rows[0]["Name"].ToString();
Family = dt.Rows[0]["Family"].ToString();
Father = dt.Rows[0]["FatherName"].ToString();
}
}
}


اگه کمکم کنید ممنون می شم ..

Esmail Solhkhah
دوشنبه 24 مرداد 1390, 17:15 عصر
سلام دوستان یک تابع دارم با چند خروجی از نوع string نمی دونم چرا وقتی تابع را از نوع static تعریف نمی کنم با Error زیر مواجه می شم .
Error 97 The out parameter 'Name' must be assigned to before control leaves the current method

این هم کدهام

public void FillClient(int Co, out string Name, out string Family, out string Father)
{
for (int i = 0; i < Co; i++)
{
DataTable dt= ...
if(dt.Rows.Count>0)
{
Name = dt.Rows[0]["Name"].ToString();
Family = dt.Rows[0]["Family"].ToString();
Father = dt.Rows[0]["FatherName"].ToString();
}
}
}


اگه کمکم کنید ممنون می شم ..


بجای out از ref استفاده کنید.

موفق باشید.

Reza_Yarahmadi
دوشنبه 24 مرداد 1390, 17:43 عصر
به متغیرهای ورودیتون مقدار اولیه بدید مشکل برطرف میشه
public static void FillClient(int Co, out string Name, out string Family, out string Father)
{
Name = "";
Family = "";
Father = "";
for (int i = 0; i < Co; i++)
{
DataTable dt = new DataTable();
if (dt.Rows.Count > 0)
{
Name = dt.Rows[0]["Name"].ToString();
Family = dt.Rows[0]["Family"].ToString();
Father = dt.Rows[0]["FatherName"].ToString();
}
}
}

linux
دوشنبه 24 مرداد 1390, 23:29 عصر
تابع با چند خروجی کلا نداریم، یعنی با مفهوم ریاضی تابع در تضاد هست، هر تابع به ازای یک یا چند ورودی یک خروجی معین بر می گرداند. برای این کاری که در نظر دارید یک کلاس یا ساختار تعریف کنید که شامل خواص دلخواه شما باشد در این تابع هم خروجی خودتان را از نوع همان کلاس بگیرید.

SokooteShab1
سه شنبه 25 مرداد 1390, 08:50 صبح
بجای out از ref استفاده کنید. زمانی از ref استفاده می شود که خروجی ها دارای مقدار اولیه بوده و بخواهیم این مقادیر داخل تابع حفظ شود.


به متغیرهای ورودیتون مقدار اولیه بدید مشکل برطرف میشه


public static void FillClient(int Co, out string Name, out string Family, out string Father){Name = "";Family = "";for (int i = 0; i < Co; i++){DataTable dt = new DataTable();if (dt.Rows.Count > 0){Name = dt.Rows[0]["Name"].ToString();Family = dt.Rows[0]["Family"].ToStringFather = dt.Rows[0]["FatherName"].ToString();}}}();

حق با شما بود چون خروجی هام داخل شرط مقدار می گرفتند باید قبل از for مقدار دهی اولیه می شدند. متشکرم.:تشویق:

Esmail Solhkhah
سه شنبه 25 مرداد 1390, 14:32 عصر
زمانی از ref استفاده می شود که خروجی ها دارای مقدار اولیه بوده و بخواهیم این مقادیر داخل تابع حفظ شود.خروجی ها دارای مقدار اولیه بوده و بخواهیم این مقادیر داخل تابع حفظ شود !!!؟؟؟ :متفکر:

دوست عزیز لطف میکنید توضیح بدید منظورتون از خروجی ها چیه ،

اگه در مورد ref و out هم توضیح بدید که لطف کردید

بنده تازه کارم زیاد متوجه منظورتون نشدم:متعجب:

Salar Ashgi
سه شنبه 25 مرداد 1390, 23:55 عصر
برای گرفتن چند خروجی از یک تابع در زبانهای از خانواده C (++ و #) شاید ذخیره کردن خروجی ها در پارامترهای رفرنس پاس داده
شده به تابع روش میانبری برای این کار باشد ولی آنچنان اصولی نیست ، بنده نیز با نظر کاربر گرامی "linux" موافقم !

SokooteShab1
پنج شنبه 27 مرداد 1390, 11:53 صبح
خروجی ها دارای مقدار اولیه بوده و بخواهیم این مقادیر داخل تابع حفظ شود !!!؟؟؟ :متفکر:

دوست عزیز لطف میکنید توضیح بدید منظورتون از خروجی ها چیه ،

اگه در مورد ref و out هم توضیح بدید که لطف کردید

بنده تازه کارم زیاد متوجه منظورتون نشدم:متعجب:
زمانی که یک تابع دارای بیش از یک خروجی باشد از uot یا ref استفاده می شود.
اگر بخواهیم از یک تابع بیش از یک خروجی بگیریم از out و زمانی که یک متغیر از پیش تعریف شده باید برای یک سری تغییرات به تابع فرستاده بشه از ref استفاده می کنیم.
منبع :http://ashiyane.org/forums/showthread.php?t=33254

linux
پنج شنبه 27 مرداد 1390, 12:04 عصر
کتاب حسابان سال اول دبیرستان را باز کنید و تعریف تابع را دوباره نگاه کنید! تابع با بیش از یک خروجی معنا ندارد!

Salar Ashgi
پنج شنبه 27 مرداد 1390, 15:43 عصر
زمانی که یک تابع دارای بیش از یک خروجی باشد از uot یا ref استفاده می شود.
این گفته شما صحیح نیست ، از لحاظ اینکه اصلا فلسفه تولید ref و out به خاطر گرفتن چند خروجی از یک
تابع نبوده است .

گفته دوست عزیزمون "linux' منطقی است !
محدوده قابل تعریف برای ورودی یک تابع میشود : دامنه
محدوده قابل تعریف برای خروجی یک تابع میشود : بُرد
ولی هر تابعی به ازای یک ورودی ، فقط یک خروجی دارد .
اصلا ارتباط بین زبانهای برنامه نویسی و ریاضیات ، کاملا تنگاتنگ است ؛ نمونه اش
همان پشتیبانی نکردن سی شارپ از وراثت چندگانه ./

SokooteShab1
پنج شنبه 27 مرداد 1390, 16:31 عصر
مفهوم تابع در اینجا فرق داره، در این جا منظور از خروجی در واقع همان ورودی هایی است که به تابع فرستاده می شود تا ویرایش و یا مقداردهی شود، تا از آن ورودی هایی که الان (پس از فراخوانی) مقدار جدید گرفته داخل توابع دیگر مورد استفاده قرار گیرد. در واقع یک عملیات مثل جمع یا ضرب بر روی ورودی انجام نمی شود که یک مقدار را به ما برگرداند بلکه مجموعه ای از کارها به عنوان مثال عمل جمع و ضرب را داخل یک تابع انجام می دهیم که قاعدتا به ازای هر عمل یک مقدار داریم. ولی تابع ما 2 خروجی دارد،که می توانیم اسم آن را تابع یا هر چیز دیگه ای بزاریم.

linux
پنج شنبه 27 مرداد 1390, 21:42 عصر
مفهوم تابع در اینجا فرق داره، در این جا منظور از خروجی در واقع همان ورودی هایی است که به تابع فرستاده می شود تا ویرایش و یا مقداردهی شود، تا از آن ورودی هایی که الان (پس از فراخوانی) مقدار جدید گرفته داخل توابع دیگر مورد استفاده قرار گیرد. در واقع یک عملیات مثل جمع یا ضرب بر روی ورودی انجام نمی شود که یک مقدار را به ما برگرداند بلکه مجموعه ای از کارها به عنوان مثال عمل جمع و ضرب را داخل یک تابع انجام می دهیم که قاعدتا به ازای هر عمل یک مقدار داریم. ولی تابع ما 2 خروجی دارد،که می توانیم اسم آن را تابع یا هر چیز دیگه ای بزاریم.
مفهوم تابع یک چیز کاملا روشن و واضحی هست. یک تعریف ریاضی مشخص هم دارد.. شما این متنی که خودت نوشتی را دوباره بخوان! منظور از خروجی همان ورودی هست؟!! مثل این می ماند که من خدمت شما عرض کنم منظور از رستوان همان W.C هست. و خلق خدا را بجای فرستان به رستوان راهی جای دیگری کنم.

یک تابع از مجموعه (http://fa.wikipedia.org/wiki/%D9%85%D8%AC%D9%85%D9%88%D8%B9%D9%87) X به مجموعه Y رابطه‌ای (http://fa.wikipedia.org/wiki/%D8%B1%D8%A7%D8%A8%D8%B7%D9%87) چون f از مجموعه X به مجموعه Y است که دارای شرایط زیر باشد:
دامنه (http://fa.wikipedia.org/w/index.php?title=%D8%AF%D8%A7%D9%85%D9%86%D9%87_(%D 8%AA%D8%A7%D8%A8%D8%B9)&action=edit&redlink=1&preload=%D8%A7%D9%84%DA%AF%D9%88:%D8%A7%DB%8C%D8%A C%D8%A7%D8%AF+%D9%85%D9%82%D8%A7%D9%84%D9%87/%D8%A7%D8%B3%D8%AA%D8%AE%D9%88%D8%A7%D9%86%E2%80%8 C%D8%A8%D9%86%D8%AF%DB%8C&editintro=%D8%A7%D9%84%DA%AF%D9%88:%D8%A7%DB%8C%D8 %AC%D8%A7%D8%AF+%D9%85%D9%82%D8%A7%D9%84%D9%87/%D8%A7%D8%AF%DB%8C%D8%AA%E2%80%8C%D9%86%D9%88%D8%A A%DB%8C%D8%B3&summary=%D8%A7%DB%8C%D8%AC%D8%A7%D8%AF+%DB%8C%DA%A 9+%D9%85%D9%82%D8%A7%D9%84%D9%87+%D9%86%D9%88+%D8% A7%D8%B2+%D8%B7%D8%B1%DB%8C%D9%82+%D8%A7%DB%8C%D8% AC%D8%A7%D8%AF%DA%AF%D8%B1&nosummary=&prefix=&minor=&create=%D8%AF%D8%B1%D8%B3%D8%AA+%DA%A9%D8%B1%D8%AF %D9%86+%D9%85%D9%82%D8%A7%D9%84%D9%87+%D8%AC%D8%AF %DB%8C%D8%AF) f مجموعه (http://fa.wikipedia.org/wiki/%D9%85%D8%AC%D9%85%D9%88%D8%B9%D9%87) X باشد، یعنی domf = X.
برای هر http://upload.wikimedia.org/math/7/3/5/735b05e6097f98da56f2ca14b8005d36.png عنصر یگانه http://upload.wikimedia.org/math/4/3/7/437f7046cb463518a28b277a85b47a5c.png موجود باشد که (x,y)inf یا به عبارتی هیچ دو زوج مرتب متمایزی متعلق به f دارای مولفه اول یکسان نباشند. شرط یگانگی را به طور صریح می‌توان یه این صورت فرمول بندی کرد که اگر http://upload.wikimedia.org/math/7/d/e/7de2b945fd9eb44d0fd9d1e380321460.png و http://upload.wikimedia.org/math/e/f/d/efd648b4224e912885d6f32451e4f018.png آنگاه الزاماً y = z.
این تعریف ریاضی تابع هست.
در این تابعی که شما نوشته این خروجی تابع از نوع void هست. یعنی تابع شما یک خروجی بیشتر ندارد آن هم هیچ هست. شما بجای اینکه دنبال طرحی برای خروجی تابع باشید دنبال این هستید که چه بلایی بر سر ورودی های شما خواهد آمد.
تا جایی که من از کد شما فهیمدن هدف شما این هست یک شماره پرسنلی به تابع بدهید و در خروجی مشخصات دارنده آن شماره پرسنلی را بدست آورید.
راه حل درست به شکل زیر هست
یک کلاس تعریف می کنیم از نوع پرسنل که دارای
1- کد پرسنلی
2- نام
3- نام خانوادگی
4-نام پدر

public class personel
{
public int Id { get; set; }
public string Name { get; set; }
public string LastName { get; set; }
public string FatherName { get; set; }
}

بعد تابع خودتان را به این صورت می نویسید
public personel FillClient(int Id)
{

{DataTable dt= ...
if(dt.Rows.Count>0)
{
personel p = new personel();
p.Id = Id;
p.Name =dt.Rows[0]["Name"].ToString();
p.LastName = dt.Rows[0]["Family"].ToString();
p.FatherName = dt.Rows[0]["FatherName"].ToString();
return p;
}
else
return null;
}
}


تابع شما یک خروجی دارد! و لازم نیست کارهای عجیب و غریب انجام بدهید.

Salar Ashgi
پنج شنبه 27 مرداد 1390, 22:20 عصر
دوست عزیز SokooteShab1 ، دید شما از تابع متاسفانه اشتباه است !



در این جا منظور از خروجی در واقع همان ورودی هایی است که به تابع فرستاده می شود

پس آن وقت چه فرقی بین ورودی و خروجی است ؟!


تا ویرایش و یا مقداردهی شود

مگر متغیر در داخل تابع ویرایش میشود ؟! در داخل تابع استفاده میشود ، نه ویرایش ! و حتی ممکن است تابعی
بدون ورودی باشد !


قاعدتا به ازای هر عمل یک مقدار داریم


خیر دوست عزیز ؛

پیشنهاد میکنم مروری بر بحث Functions در #C داشته باشید ./

ببینید ، یک مثالی براتون میزنم ، مثلا ما میخوایم تابعی داشته باشیم که توان دوم و سوم ، عدد ورودی
را حساب کند :

ابتدا یک ساختار (نوع داده ای جدید) بهمراه تابع مربوطه را تعریف میکنیم :


struct Number
{
public double pow_2;
public double pow_3;

}
//======================
Number my_Func(int num)
{
Number res = new Number();
res.pow_2 = Math.Pow(num, 2);
res.pow_3 = Math.Pow(num, 3);
return res;
}


نحوه استفاده :


private void button1_Click(object sender, EventArgs e)
{

string str = "";
for (int i = 2; i <= 6; i++)
{

Number res = my_Func(i);
str += res.pow_2.ToString() + " , " + res.pow_3.ToString() + "\n";
}
MessageBox.Show(str);
}


خروجی :

74016

موفق باشید ./

mmd2009
جمعه 28 مرداد 1390, 02:05 صبح
با سلام

به این شکل هم میتونید عمل کنید :


private void button1_Click(object sender, EventArgs e)
{
int a; ;
int b; ;
int c; ;
int d; ;
Calculation(out a, out b, out c, out d);

MessageBox.Show(string.Format(" a={0} , b={1} , c={2} , d={3}", a, b, c, d));
}

private void Calculation(out int sum, out int Multiplication, out int Subtraction, out int Division)
{
sum = 2 + 2;
Multiplication = 2 * 2;
Subtraction = 8-2;
Division = 10 / 2;
}

SokooteShab1
یک شنبه 30 مرداد 1390, 12:09 عصر
باید اعتراف کنم که در مورد تابع اشتباه کردم:گیج: امیدوارم که انجمن حمایت از توابع عذر خواهی من را بپذیرند .:خجالت: از تمام دوستان تشکر می کنم ،

تابع شما یک خروجی دارد! و لازم نیست کارهای عجیب و غریب انجام بدهید.
دوست عزیز :linux از این به بعد از تابع با یک خروجی استفاده خواهم کرد.

SokooteShab1
یک شنبه 30 مرداد 1390, 16:30 عصر
این گفته شما صحیح نیست ، از لحاظ اینکه اصلا فلسفه تولید ref و out به خاطر گرفتن چند خروجی از یک
تابع نبوده است .

پس فلسفه تولید ref و out به خاطر چی بوده؟؟؟

spring69
یک شنبه 30 مرداد 1390, 17:38 عصر
پس فلسفه تولید ref و out به خاطر چی بوده؟؟؟
سلام
http://www.persiadevelopers.com/articles/cs-10-years-1.aspx

linux
یک شنبه 30 مرداد 1390, 19:17 عصر
باید اعتراف کنم که در مورد تابع اشتباه کردم:گیج: امیدوارم که انجمن حمایت از توابع عذر خواهی من را بپذیرند .:خجالت: از تمام دوستان تشکر می کنم ،

دوست عزیز :linux از این به بعد از تابع با یک خروجی استفاده خواهم کرد.
اگر تونستی تابع با بیشتر از یک خروجی بنویسی، حتما بقیه را هم خبردار کن. البته به شرط اینکه نگویی ورودی همان خروجی هست، خروجی همان ورودی هست.
out و ref هم کاربرد خودشان را دارند. بعضی وقتها لازم دارید تا بدانید که در یک تابع یا یک روال چه بلایی بر سر آرگومان ورودی می آید. در این حالت بجای ارسال مقدار پارامتر آدرس پارامتر را به تابع ارسال می کنید. اگر سی/سی++ کار کرده باشید این کار معادل استفاده از * هست.
روش درست کار و تعریف درست تابع خدمت شما عرض شد. حالا شما هرجوری دوست داری استفاده کنید.

Salar Ashgi
یک شنبه 30 مرداد 1390, 19:56 عصر
پس فلسفه تولید ref و out به خاطر چی بوده؟؟؟
عموما ما دو روش در زبانهای خانواده C برای پاس دادن متغیر به تابع داریم :



پاس دادن با مقدار => Pass By Value
پاس دادن با آدرس => Pass By Reference

حالا هرکدوم واسه خودش کاربردی داره .

در هر حالت اول همیشه یه کپی اولیه از متغیر گرفته میشه و به تابع ارسال شده و تابع روی آن مقدار
کپی عملیات خود را انجام می دهد .

ولی در حالت دوم متغیر بهمراه آدرسش به تابع پاس داده میشه و هر تغییرات روی متغیر ، در خودش ذخیره میشود .

مثال زیر را در نظر بگیرید :

حالت اول (پاس دادن با مقدار) :

یک تابع دلخواه :


int my_Func(int x)
{
x++;
return (x * x + x + 1);
}


استفاده :


string str = "";
for (int i = 1; i <= 4; i++)
{
str += "Func Output : " + my_Func(i).ToString() + " , " + "Value : " + i.ToString() + "\n";
}
MessageBox.Show(str);


حالت دوم (پاس دادن با آدرس) :

همان تابع با تغییرات زیر در نظر بگیرید :


int my_Func(ref int x)
{
x++;
return (x * x + x + 1);
}


استفاده :


string str = "";
for (int i = 1; i <= 4; i++)
{
str += "Func Output : " + my_Func(ref i).ToString() + " , " + "Value : " + i.ToString() + "\n";
}
MessageBox.Show(str);


**** ) خال می رسیم به خروجی ها ، خوب دقت کنید :

حالت اول :

http://salarcpp.persiangig.com/new_folder_5/out_1.png

حالت دوم :

http://salarcpp.persiangig.com/new_folder_5/out_2.png

کاملا طبق توضیحاتی که دادم ، خروجی های مورد نظر تولید شده ! فکر کنم این مثال ، واسه درک value , reference مثال
خوبی بوده باشه ، باز اگه سوالی بود ، مطرح کنید .

موفق باشید ./

m_gh660
جمعه 20 آبان 1390, 18:10 عصر
تابع در #C با چند خروجی معنا دارد این خروجی میتواند مثلا آرایه باشد که بدین شکل تعریف میگردد:


()public string[] Functionmulti
;[string[] date = new string[2
date[0]="item1"; date[1]="item2";
;return date
{

linux
شنبه 21 آبان 1390, 09:34 صبح
تابع در #C با چند خروجی معنا دارد این خروجی میتواند مثلا آرایه باشد که بدین شکل تعریف میگردد:


()public string[] Functionmulti
;[string[] date = new string[2
date[0]="item1"; date[1]="item2";
;return date
{





دوست عزیز! باز هم شما یک خروجی دارید که همان آرایه هست.
موفق و سلامت باشید

alireza_wills
چهارشنبه 09 آذر 1390, 13:20 عصر
سلام به همگی
آقای linux میبخشید شاید من نمیدونم ولی این کد
public class personel
{
public int Id { get; set; }
public string Name { get; set; }
public string LastName { get; set; }
public string FatherName { get; set; }
}
مشکل نداره؟

کد شما با اصل پنهان سازی متغیرها متناقضه. کتاب ditel:

"در برخی مواقع برای بالا بردن کارائی يک برنامه، لازم
است برخی توابع غير عضو اين امکان را داشته باشند که
به اعضاء خصوصی يک کلاس دسترسی داشته باشند. اين دسترسی
از دو طريق امکان پذير خواهد بود: نخست آنکه اعضاء
خصوصی کلاس را به صورت عمومی تعريف کنيم تا توابع غير
عضو نيز به آن اعضاء دسترسی داشته باشند. روشن است که
اين روش علاوه بر اينکه ناقض اصل مهم و اساسی "پنهان سازی اطلاعات (information hiding) "می باشد، امکان
دسترسی به اعضاء خصوصی را نه تنها برای يک تابع خاص
بلکه برای تمامی توابع غير عضو بوجود خواهد آورد"

من بعید میدونم این راه حل مناسبی باشه.

linux
جمعه 11 آذر 1390, 15:55 عصر
سلام به همگی
آقای linux میبخشید شاید من نمیدونم ولی این کد
......من بعید میدونم این راه حل مناسبی باشه.

شما هر جور راحتی برنامه بنویس. خسته شدم آنقدر که توضیح دادم.

alireza_wills
شنبه 12 آذر 1390, 09:42 صبح
شما هر جور راحتی برنامه بنویس. خسته شدم آنقدر که توضیح دادم.
سلام آقای Linux
من شاید بلد نباشم.
من بدنبال این مطلب بودم که جستجو کردم. ولی کلاً سوال من اینه چه جوری میشه به متغیر های خصوصی یک تابع یا کلاس دسترسی داشت. یکی از اصول شیگرایی تعریف کلاس یا توابع دوست هستش که خیلی کاربرد داره و تو C++‎‎ کلی ازش استفاده میشه. من فکر میکنم تعریف متغیرهای Public مخصوصاً متغیرهایی که ارتباط با بانک میتونن داشته باشن کار درستی نیست. اگر گفته قانع کننده ای دارید بگید شاید من دارم اشتباه می کنم.

Amir Oveisi
شنبه 12 آذر 1390, 10:34 صبح
لطفا مباحث پايه رو مطالعه كنيد.

اون كلاسي كه در مثال بالا ذكر شده، فيلد هاش Property هستند و به همين دليل Public اند. بر خلاف تصور شما، يك متغير در سطح كلاس نيستند كه نبايد public باشند. مفاهيم شي گرايي #C رو با دانسته هاتون از ++C نسنجيد.

در مورد Property ها در دات نت مطالعه كنيد.
اول اين:
http://msdn.microsoft.com/en-us/library/x9fsa0sw.aspx
بعد اين:
http://msdn.microsoft.com/en-us/library/bb384054.aspx


یکی از اصول شیگرایی تعریف کلاس یا توابع دوست هستش
درست نيست. در مورد دليلش هم دوباره توصيه ميكنم در مورد Object Oriented Programming (http://msdn.microsoft.com/en-us/library/dd460654.aspx) مطالعه كنيد.