C/C++ מדריכי
C הקדמה לתכנות ב
C++ הקדמה להיררכית מחלקות ב הצגה מזורזת :C++ הבנת דף הבית

שיעור 10: שימוש במצביעים לפרמטרים שהם משתנים

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

program samp;  
var  
    a,b:integer; 
 
procedure swap(var i,j:integer);    
var t:integer;    
begin      
    t:=i;      
    i:=j;      
    j:=t;    
end; 
  
begin    
    a:=5;    
    b:=10;    
    writeln(a,b);    
    swap(a,b);    
    writeln(a,b);  
end.

כיוון שקוד זה משתמש בפרמטרים שהם משתנים, הוא מחליף את הערך של a ו b בצורה נכונה. ל C אין מנגנון פורמלי להעברת פרמטרים שהם משתנים: היא מעבירה הכל by value. הכנס והרץ את הקוד הבא ובדוק מה קורה:

#include <stdio.h>   
 
void swap(int i, int j)    
{    
    int t; 
    
    t=i;    
    i=j;    
    j=t;  
} 
 
void main()  
{    
    int a,b; 
    
    a=5;  
    b=10;    
    printf("%d %d\n",a,b);    
    swap(a,b);    
    printf("%d %d\n",a,b);  
}

לא מתבצעת כל החלפה. הערכים של a ו b מועברים להחלפה, אבל לא מוחזרים ערכים.

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

#include <stdio.h>   
 
void swap(int *i, int *j)    
{    
    int t; 
    t = *i;    
    *i = *j;    
    *j = t;  
} 
 
void main()  
{    
    int a,b; 
    a=5;    
    b=10;    
    printf("%d %d\n",a,b);    
    swap(&a,&b);    
    printf("%d %d\n",a,b);  
}

כדי לקבל מושג על מה שהקוד עושה, הדפס אותו, שרטט את שני המספרים השלמים a ו b, והכנס לתוכם 5 ו 10. כעת שרטט את שני המצביעים i ו j, ביחד עם המספר השלם t.

כאשר מתבצעת הקריאה ל swap, היא מעבירה את הכתובת של a ו b. לכן, i מצביע ל a (צייר חץ מ i ל a) ו j מצביע ל b (צייר חץ נוסף מ b ל j). כיוון שהמצביעים נוצרו , i* הוא שם נוסף ל a, ו j* הוא שם נוסף ל b. כעת הרץ את הקוד ב swap. כאשר הקוד משתמש ב i* ו j*, הוא למעשה מתכוון ל a ו b. כאשר הפונקציה מסתיימת, a ו b הוחלפו.

נניח שבטעות שכחת את ה & בקריאה לפונקציה swap, וששורת ה swap בטעות נראית כך : swap(a,b); . דבר זה גורם לשגיאת סגמנטציה. כאשר משמיטים את ה &, הערך של a מועבר במקום הכתובת שלו. לכן, i מצביע למיקום לא חוקי בזיכרון והמערכת מתרסקת כאשר משתמשים ב i*.

מסיבה זו scanf מתרסקת אם שוכחים & --- scanf משתמשת במצביעים כדי לשים את הערך שהיא קוראת בתוך המשתנה שהעברת אליה. בלי &, ל scanf מועברת כתובת לא טובה והיא מתרסקת.




לדף הראשון

<< לדף הקודם

לדף הבא >>