Pointers: &, *, and pass-by-pointer · איורים: &, *, ומעבר באמצעות איור
A problem from last lesson
- Last lesson, a function got a copy of your number. Changing the copy did not change the original.
- C copies every argument you pass to a function. So a normal function cannot change your variable.
- To change it, the function needs the variable's address — where it lives in memory.
בעיה מהשיעור הקודם
- בשיעור הקודם, פונקציה קיבלה עתיקה של המספר שלך. שינוי העתיקה לא שינה את המקורי.
- C מעתיקה כל ארגומנט שמעביר לפונקציה. לכן פונקציה רגילה לא יכולה לשנות משתנה שלך.
- כדי לשנות אותו, הפונקציה צריכה את כתובת המשתנה — היכן שהוא נמצא בזיכרון.
Every variable has an address
- Think of a variable as a box in memory. The value is kept inside the box.
- Every box has an address: a number that says where the box is.
- The
&operator gives you that address.&xmeans "the address ofx".
לכל משתנה יש כתובת
- חשב על משתנה כ-תיבה בזיכרון. הערך מוחזר בתוך התיבה.
- לכל תיבה יש כתובת: מספר שמציין איפה התיבה נמצאת.
- המופע
&מספק לך את הכתובת הזו.&xפירושו "הכתובת שלx".
A pointer holds an address
- A pointer is a variable that stores an address, not a normal value.
- You declare one with a
*:int *p = &x;reads as "ppoints tox". - To reach the value at that address, put
*in front:*p. This is called dereference. - Changing
*pchanges the original variable.*p = 5;puts5intoxitself.
נרשם מחזיק כתובת
- נרשם הוא משתנה שמאחסן כתובת, ולא ערך רגיל.
- מציגים אותו עם
*:int *p = &x;קוראים "pמצביע עלx". - כדי לגשת לערך בכתובת זו, שמים
*לפניו:*p. פעולה זו נקראת פירוק נרשם (dereference). - שינוי
*pמשנה את המשתנה המקורי.*p = 5;מכניס את5ישירות לתוךx.
#include <stdio.h>
void set_to_five(int *p) {
*p = 5; // change the value at the address
}
int main(void) {
int x = 0;
set_to_five(&x); // pass the ADDRESS of x
printf("%d\n", x); // 5 — the original changed!
return 0;
}
Out-pointers: giving back more than one answer
- A function can
returnonly one value. But it can change several variables through pointers. - You pass the address of each answer, like
find(&min, &max). The function writes into them with*. - These extra pointer parameters are called out-pointers. The caller reads the answers after the call.
- A pointer that points to nothing is
NULL. Never dereference aNULLpointer.
נרשמי יציאה: החזרת יותר מתשובה אחת
- פונקציה יכולה להחזיר
returnרק ערך אחד. אך היא יכולה לשנות מספר משתנים דרך מציינים. - מעבירים את הכתובת של כל תשובה, כמו
find(&min, &max). הפונקציה כותבת בהם באמצעות*. - פרמטרי הנרשמים הנוספים הללו נקראים נרשמי יציאה. הקורא קורא את התשובות לאחר הביקור בפונקציה.
- נרשם שמצביע על כלום הוא
NULL. לעולם אל תפרק נרשםNULL.
Common mistakes
&xis the address ofx;*pis the value stored atp.- Never use
*pon an uninitialised orNULLpointer.
טעויות נפוצות
&xהיא הכתובת שלx;*pהוא הערך הארוז בp.- לעולם אל תשתמש ב
*pעל נרשם לא-מוגדר אוNULL.
Now you try
- Each task gives you a function to complete. Use
*to read or change the value the pointer points to. - When a value comes in through a pointer (like
int *p), write your answer through it — do notreturnit. - Do not write a
main— the checker provides one. Press Run, then Check answer.
כעת תנסו בעצמכם
- בכל משימה תקבל פונקציה למילוי. השתמש ב
*לקריאה או לשינוי הערך עליו מצביע הנרשם. - כאשר ערך נכנס דרך מציין (כמו
int *p), כתוב את התשובה שלך דרכו — אל תשתמש ב-returnשלו. - אל תכתוב
main— הבוחן מספק אותו. לחץ על הפעל, ואז על בדוק תשובה.
Complete void add_one(int *p) so it adds 1 to the int that p points at. Use *p. Do not write a main — the checker provides one. · השלם את void add_one(int *p) כך שתוסיף 1 למשתנה מספר שלם עליו מצביע p. השתמש ב*p. אל תכתוב פקודת main — הבוקר מספק אחת כזו.
Click Run to see the output here. · לחץ על הרץ כדי לראות את התוצא כאן.
Complete void swap(int *a, int *b) so it exchanges the two ints. Use a temporary variable. Do not write a main. · השלם את void swap(int *a, int *b) כדי להחליף בין שני המשתנים מספר שלם. השתמש במשתנה זמני. אל תכתוב פקודת main.
Click Run to see the output here. · לחץ על הרץ כדי לראות את התוצא כאן.
Complete void min_max(const int a[], int n, int *min_out, int *max_out). Scan the array, then write the smallest value through min_out and the largest through max_out. Assume n >= 1. Do not write a main. · השלם את void min_max(const int a[], int n, int *min_out, int *max_out). סרוק את המערך, ולאחר מכן כתוב את הערך הקטן ביותר דרך min_out ואת הגדול ביותר דרך max_out. הנח that n >= 1. אל תכתוב פקודת main.
Click Run to see the output here. · לחץ על הרץ כדי לראות את התוצא כאן.