× מי אנו? התוכנית הראשונה משתנים קלט ופלט אופרטורים חשבוניים משפטי בקרה לולאות לולאות דו ממדיות casting sizeof typedef פונקציות רקורסיות מצביעים מצביע כפול מערכים מערכים דינאמיים מערכים דו ממדים מחרוזות חיפוש בינארי מיון בועות מיון בחירה מיון הכנסה מיון מהיר מיון מיזוג

Let's learn C

מצביע כפול

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

הצהרה של מצביע כפול / דאבל-פוינטר

אם בשביל מצביע למשתנה היינו צריכים כוכבית אחת אז בשביל דאבל-פוינטר (שהוא בעצם מצביע למצביע) אנו צריכים שתי כוכביות מה שאומר שנוצרת לנו מעין חוקיות שקשורה לכוכביות. החוקיות אומרת שבשביל ליצור משתנה שיצביע למשתנה אחר, על המשתנה המצביע להיות בעל כוכבית אחת יותר מאשר המשתנה שאליו אנו מצביעים.
למשל, אם היינו מצביעים למשתנה מסוג int היינו נדרשים להשתמש בכוכבית אחת.
אם היינו רוצים להצביע למשתנה מסוג int* היינו משתמשים בשתי כוכביות (דאבל-פוינטר).
אם היינו רוצים להצביע למשתנה מסוג int** היינו משתמשים בשלושה כוכביות (טריפל-פוינטר).
וכך הלאה.
הצהרה של מצביע כפול תהיה בדרך הבאה:
type ** name;

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

שורה 5 – ptr מצביע על הכתובת של number.
שורה 6 – double_ptr מצביע על ptr שהוא מצביע

CODE 1:
#include <stdio.h>
void main()
{
  int number = 10, *ptr, **double_ptr;
  ptr = &number;
  double_ptr =&ptr;
}

ישנם כמה דברים שונים בין מצביע למצביע לבין מצביע רגיל:
כאשר אנו רושמים רק את השם של המצביע למצביע printf(“%d”, double_ptr) דבר זה ידפיס את הכתובת של המצביע.

כאשר אנו נרשום printf(“%d”,*double_ptr) הוא ידפיס את התוכן שנמצא בכתובת שאליו אנו מצביעים.
לכן, אם אנו מצביעים לכתובת של ptr אז כאשר נרשום *double_ptr נקבל את הכתובת של המשתנה המקורי.
כפי שכבר ציינו במצביעים הערכים היחידים שמצביעים יכולים לשמור הם כתובות.

כאשר אנו נרשום printf(“%d”,*(*double_ptr)) אנו נקבל כאן את הערך של המשתנה המקורי (כלומר הערך המספרי שנמצא בפנים ולא הכתובת).

דוגמא שנייה למצביע כפול:

inc_by_one(&ptr) – שליחה של פוינטר כפול מתבצעת בצורה הזו (בתוך ה main).
(*(*double_ptr))++ – שינוי ערך של מצביע כפול תתבצע בצורה הזו.

CODE 2:
#include <stdio.h>
void inc_by_one(int **double_ptr);

void main()
{
  int number = 10 , *ptr;
  ptr = &number;
  inc_by_one(&ptr);
}

void inc_by_one(int **double_ptr)
{
  (*(*double_ptr))++;
}