אבל באמת רואים שלא הבנת את הנושא.
שיש לך מצביעint* f
לדוגמא מסוג int*
הדבר אומר שיש לך משתנה מסוג מצביע שיכול להצביע לטיפוס מסוג int.
כלומר נניח שיש לך את התוכנית הבאה:
int a = 4;
int*f;
f=&a;
printf("%d\n%d\n",a,*f) //will print 4 4
printf("%d\n",f)//will print f's memory address
*f = 5;
printf("%d\n%d\n",a,*f) //will print 5 5
a=7;
printf("%d\n%d\n",a,*f) //will print 7 7
כאן השתמש במצביע f שיצביע לכתובת של המשתנה a.כל שינוי ב a יגרור אוטומטית שינוי של *f מכיוון ששניהם מצויים באותו תא,כנ"ל לגבי שינוי ב *f יגרור שינוי ב a.
זה דרך אחד לראות פוינטר-כמשתנה שלא מקבל שום הקצאה של זכרון אלא מצביע לזכרון שכבר קיים(נותן אופציה לשנות אותו ולעשות דברים אחרים).
עכשיו מכיוון שהמשתנה הוא מסוג int* אז עובד קצת אחרת מ int רגיל.
int a=8;
int *f=&a;
f++;
בהתחלה f מקבל את הכתובת של a ולכן *f ו a הם בעצם אותו "תיבה" בזכרון ושניהם יש אותו ערך ואותו כתובת.
כאשר אתה עושה f++ אתה מקדם את f באחד,אבל f הוא כתובת בזכרון מסוג int ששוקל 4 בתים..כלומר אתה מקדם את f ב 4 בתים בזכרון..דבר רע מאוד לעשות וטעות נפוצה אצל מתחילים.
כרגע עם הפעולה הזאת f לא מצביע ל a והוא מצביע למקום מסויים בזכרון שכנראה מכיל זבל ויגרום לתוכנית שלך לבעיות אם תשתמש במשתנה.
int a=8;
int* f=&a;
(*f)++;
כאן בהתחלה שניהם מצביעים ל 8..אבל כאן אתה מקדם את *f שמצביע לאותה תיבה של a ולכן a=9 וf עדיין מצביע ל a.
עכשיו לשימוש אחר של מצביעים..יצירת מערך דינאמי..
שאתה לומד מחשבים אז מלמדים אותך לעשות מערך רק שאתה יודע את הגודל שלו מראש. בצורה כזאת:
int arr;
מערך בגודל 10 לדוגמא.
מה קורה אם באמצע תוכנית ירצו שתארגן מערך בגודל שאתה לא יודע מראש?
אז הנה דוגמא:
int size=10;
int* arr;//not pointing anywhere!!!!
arr=(int*)malloc(10 * sizeof(int));
נניח שה size הזה הוא 10 ושקיבלנו אותו בזמן התוכנית מפעולה כלשהי.
אתה הכרזת על משתנה מסוג int* שנקרא arr
אתה רוצה עכשיו ליצור מערך ולכן עלייך לבצע את אחת מפעולות ההקצאה.
לקחתי את malloc שהיא הכי נפוצה.
מה שהיא עושה זה דבר כזה..
אתה שם את שם המשתנה של המערך שאתה רוצה ליצור משמאל..
ואז שם את האופרטור =
ואז יש לך סוגרים עם int* שזה כאילו משהו שנקרא קאסטינג-המרה לטיפוס..כי malloc היא פונקציה כללית ולכן אתה רוצה שהיא תקצה לך מידע למשתנה מסוג int* אז אתה צריך להודיע לה שאתה int*..
ואז את המילה malloc שהיא בעצם שם הפונקציה..ואחריה בסוגרים את הגודל של ההקצאה...
נבוג לשים את הגודל בצורה של
כמות האיברים למערך * גודל של כל משתנה ולכן מקובל לרשום
10 * sizeof(int))
כאשר sizeof(int) זאת פונקציה שתדע להחזיר לך את גודלו של הטיפוס.
הפונקציה מבצעת את ההקצאה ומחזירה לך מערך..
שאתה יכול להשתמש בו כפי שאתה מכיר
arr = 6;
תשים לך במקום ה 0 של המערך 6..
ואתה יכול להשתמש בו גם אחרת
*(arr) <-> arr
*(arr + 1) <-> arr
*(arr + size) <-> arr
arr <-> &arr
(arr + 1) <-> &arr
(arr + size) <-> &arr
בחלק הראשון זה מה שאתה בד"כ מכיר..הרי ה arr הוא עדיין מצביע לכתובת(כתובת ההתחלה של ההקצאה) אבל עם שימוש ב * אפשר לשים בו ערך.
ובחלק התחתון הראתי לך גישה לזכרון של מקום(לא נרצה לשנות אותו סתם ככה).
ומעכשיו אתה יכול לעשות משחקים:
int* arr;
int size = 10;
arr=(int*)malloc(size * sizeof(int));
for(i = 0 ; i < size ; i++)
{
*(arr+i) = i;
}
זה שקול ל
for(i = 0 ; i < size ; i++)
{
arr = i;
}
ונשמיך בתוכנית-כרגע אני עם מערך בגודל 10 שמכיל את האיברים 0 עד 9..
*(arr) = 12 //putting 12 in the "0" index of arr
*(arr + 1) = 15//putting 15 in the "1" index of arr
arr = 27//putting 27 in the 2 index of arr
דבר אחרון שיש לי להגיד זה נגיד ואתה מבצע הקצאה באמצעות malloc לדוגמא..אז אתה זה שאחראי בסוף השימוש במערך לשחרר זכרון.
בסוף התוכנית תבצע שחרור ע"י
free(arr);
עם הזמן אתה תבין את העניין..
הסקתי שאתה יחסית חדש בתחום ולכן בטוח יש כאן דברים שנראים לך טריוואלים ונראה לך מפגר שהסברתי לך אותם כמו לתינוק..אבל ככה זה יהיה הכי ברור..ניסיתי לרשום מסודר עם שמאל ימין אבל הממשק כאן קצת דפוק ולכן שמתי הכל בקוד..מקווה שתבין...