וובמאסטר - תיכנות ובניית אתרים

מדריך C# – פרמטרי ref ופרמטרי out

arikp ,‏ מכללת סלע‏ ‏/‏ 12 ינואר, 2011
F+
F-

בחלק הקודם למדנו כיצד להעביר פרמטרים לפונקציה וכיצד לקבל מפונקציה ערך החזרה.
בחלק זה נלמד על שני סוגים נוספים של פרמטרים לפונקציה.

הקדמה

כדי להבין את השימוש של פרמטרים מסוג ref נתבונן בדוגמא הבא:

static void swap(int x, int y)
{
   
int z = x;
    x = y;
    y = z;
}

פונקציה זו מקבלת שני פרמטרים מטיפוס int בשם x ו y ומבצעת החלפה בערכים שלהם בעזרת משתנה עזר z.
כעת נכתוב תוכנית שקוראת לפונקציה swap על שני משתנים בשם a ו b ומדפיסה את הערכים שלהם לפני ואחרי הקריאה:

static void Main(string[] args)
{
   
int
a = 5;
   
int
b = 7;
   
   
Console.WriteLine("a = "
+ a.ToString());
   
Console.WriteLine("b = "
+ b.ToString());
    swap(a, b);
   
Console.WriteLine("a = "
+ a.ToString());
   
Console.WriteLine("b = " + b.ToString());
}

תוצאת הרצת התוכנית הזו היא:

מדריך #C – פרמטרי ref ופרמטרי out

כלומר, למרות שהפעלנו את הפונקציה swap המשתנים לא הוחלפו!

אז מה קורה כאן?

הסיבה שלא ראינו שינוי בערכים של a ו b היא שכאשר מעבירים לפונקציה ערכים בשפת C#, הערכים מועתקים לתוך הפרמטרים.
אם נזכור שמאחורי כל משתנה יש איזשהו תא בזיכרון שמכיל את הערך שלו, אז במקרה שלנו יצרנו 2 תאים נוספים שמכילים העתקים של התאים המקוריים.

הפונקציה swap בעצם עשתה החלפה של הערכים במשתנים החדשים, אבל לא המקוריים! המקוריים נשארו עם אותם ערכים ולכן מציגים אותה תוצאה לאחר הקריאה ל swap.

פרמטר מסוג ref

כדי לגרום לפונקציה swap לעבוד כמו שצריך, נרצה לסמן לפונקציה שהפרמטרים צריכים להשתמש באותם תאים בזיכרון ולא ליצור העתקים בתאים חדשים.

ניתן לבצע זאת ע"י סימון כל פרמטר במילה ref לפני הגדרת הטיפוס שלו.

בדוגמא שלנו ההגדרה צריכה להיות:

static void swap(ref int x, ref int y)
{
   
int z = x;
    x = y;
    y = z;
}

כעת הפונקציה לא תבצע העתקה של הפרמטרים אלא תשתמש באותם תאים של המשתנים המקוריים.

נעיר שכאשר משתמשים בפרמטרים מסוג ref צריך לציין זאת גם בעת הקריאה לפונקציה swap, כלומר כעת התוכנית תראה כך:

static void Main(string[] args)
{
   
int
a = 5;
   
int
b = 7;
   
   
Console.WriteLine("a = "
+ a.ToString());
   
Console.WriteLine("b = "
+ b.ToString());
    swap(
ref a, ref
b);
   
Console.WriteLine("a = "
+ a.ToString());
   
Console.WriteLine("b = " + b.ToString());
}

והרצת התוכנית תיתן את הפלט:

מדריך #C – פרמטרי ref ופרמטרי out

כעת אנו רואים שהערכים של המשתנים a ו b אכן התחלפו כנדרש.

פרמטר מסוג out

פרמטרים מסוג out באים לפתור בעיה שונה.
ראינו בחלק הקודם במדריך כיצד להחזיר ערך מפונקציה ע"י הגדרת ערך החזרה ושימוש בפקודה return.
נשאלת השאלה, מה נעשה אם נרצה שפונקציה תחזיר יותר מערך אחד?

לצורך כך נוכל להגדיר פרמטר של הפונקציה בתור פרמטר out, ע"י הוספת המילה out לפני הגדרת הטיפוס שלו.

פרמטר שמוגדר בתור out הוא פרמטר שמועבר ע"י הפונקציה הקוראת (Main) רק לצורך קבלת ערך החזרה.
לדוגמא, קטע הקוד הבא מגדיר פונקציה שיש לה גם ערך החזרה וגם שני פרמטרים מטיפוס out:

static string GetMultipleValues(out string firstName, out string lastName)
{
   
Console.Write("Enter first name: "
);
    firstName =
Console
.ReadLine();

   
Console.Write("enter last name: "
);
    lastName =
Console
.ReadLine();

   
return firstName + " " + lastName;
}

פונקציה זו קולטת מהמשתמש ערכים לתוך הפרמטרים firstName ו lastName ובנוסף מחזירה ערך שמכיל את השם המלא.

בעת הקריאה לפונקציה עם פרמטר מטיפוס out יש לציין את המילה out לפני שם המשתנה:

static void Main(string[] args)
{
   
string
full, first, last;
    full = GetMultipleValues(
out first, out last);
}

 

בפונקציה זו אנו מגדירים ראשית 3 משתנים מטיפוס string.
לאחר מכן אנו קוראים לפונקציה GetMultipleValues ומעבירים לה את הפרמטרים first ו last תוך הוספת המילה out לפני.
המשתנה full יקבל את ערך ההחזרה הרגיל של הפונקציה ואילו המשתנים first ו last יקבלו את הערכים שיקלטו מהמשתמש.

arikp, מכללת סלע

אריק פוזננסקי הוא יועץ בכיר ומרצה בסלע. הוא השלים שני תארי B.Sc. במתמטיקה ומדעי המחשב בהצטיינות יתרה בטכניון. לאריק ידע נרחב בטכנולוגיות מיקרוסופט, כולל .NET עם C#, WPF, Silverlight, WinForms, Interop, COM/ATL, C++ Win32 ו reverse engineering.
תגיות: C#‏  /  .net‏  /  מדריך‏  /  פיתוח‏  

תגובות בפייסבוק

תגובות למאמר



עוד במדריך

תגיות פופולאריות

X
הצטרף לעמוד שלנו בפייסבוק להישאר מעודכן!
וובמאסטר © כל הזכויות שמורות