אריתמטיקה של מצביעים
חלק מהיחידה לוגיקה וזרימת תוכנית במסלול ה-C של Coddy. שיעור 9 מתוך 63.
למדת איך לגשת לאיברי מערך באמצעות סימון מצביעים כמו *(array + i). עכשיו תכיר טכניקה חזקה עוד יותר: אריתמטיקה של מצביעים, שמאפשרת לך להזיז מצביעים בזיכרון באמצעות פעולות פשוטות של הגדלה והקטנה.
כשמגדילים מצביע באמצעות ++ או מקטינים אותו באמצעות --, המצביע לא זז רק בבייט אחד. במקום זאת, הוא זז בגודל של סוג הנתונים שאליו הוא מצביע. עבור מצביע למספר שלם, ptr++ מתקדם ב־sizeof(int) בייטים, ונוחת בדיוק על המספר השלם הבא בזיכרון.
int numbers[5] = {10, 20, 30, 40, 50};
int *ptr = numbers; // מצביע על האיבר הראשון (10)
ptr++; // כעת מצביע על האיבר השני (20)
ptr++; // כעת מצביע על האיבר השלישי (30)חישוב הגודל האוטומטי הזה הוא מה שהופך את אריתמטיקת המצביעים לחזקה ונוחה כל כך. אין צורך לדאוג לחישובי בתים — C מטפלת עבורך במיעון הזיכרון על סמך סוג הנתונים של המצביע.
אריתמטיקה של מצביעים שימושית במיוחד למעבר על מערכים בלולאות. במקום להשתמש באינדקסים של מערכים, אפשר להגדיל מצביע כדי לעבור דרך כל איבר בזה אחר זה, ולעיתים קרובות כך מתקבל קוד יעיל יותר.
אתגר
קלכתבו תוכנית C שמדגימה חשבון מצביעים באמצעות פעולות הגדלת מצביע כדי לעבור על מערך ולעבד אותו. התוכנית שלכם צריכה:
- להכריז על מערך של מספרים שלמים בשם
dataובו 5 איברים, ולאתחל אותו בערכים {12, 24, 36, 48, 60} - להכריז על מצביע למספר שלם בשם
ptrולאתחל אותו כך שיצביע על האיבר הראשון במערך - להשתמש בלולאת for שרצה 5 פעמים כדי לעבור על המערך כולו באמצעות חשבון מצביעים בלבד
- בתוך הלולאה:
- להדפיס את הערך הנוכחי שעליו מצביע
ptrבאמצעות אופרטור ביטול ההפניה - להדפיס את כתובת הזיכרון השמורה ב-
ptrבאמצעות מציין הפורמט%p - להגדיל את המצביע באמצעות
ptr++כדי לעבור לאיבר הבא
- להדפיס את הערך הנוכחי שעליו מצביע
- לאחר הלולאה, לאפס את
ptrכך שיצביע שוב על האיבר הראשון במערך - להשתמש בחשבון מצביעים כדי לגשת ישירות לאיבר השלישי (אינדקס 2) ולהדפיס אותו באמצעות
*(ptr + 2) - להשתמש בחשבון מצביעים כדי לגשת ישירות לאיבר האחרון (אינדקס 4) ולהדפיס אותו באמצעות
*(ptr + 4)
הפלט שלכם צריך להציג את התוצאות בפורמט הבא:
Value: 12, Address: [address]
Value: 24, Address: [address]
Value: 36, Address: [address]
Value: 48, Address: [address]
Value: 60, Address: [address]
Third element: 36
Last element: 60האתגר הזה בודק את ההבנה שלכם לגבי האופן שבו פעולות הגדלת מצביע מזיזות אותו אוטומטית בגודל של טיפוס הנתונים, וכיצד אפשר להשתמש בחשבון מצביעים כדי לגשת לאיברי מערך במרחקים מוגדרים ממיקום של מצביע בסיס.
נסו בעצמכם
#include <stdio.h>
int main() {
// TODO: כתבו את הקוד שלכם כאן
// הכריזו על המערך 'data' ואתחלו אותו בערכים {12, 24, 36, 48, 60}
// הכריזו על מצביע 'ptr' ואתחלו אותו כך שיצביע על האיבר הראשון
// השתמשו בלולאת for ובאריתמטיקה של מצביעים כדי לעבור על המערך
// הדפיסו כל ערך ואת הכתובת שלו, ואז קדמו את המצביע
// אפסו את המצביע והשתמשו באריתמטיקה של מצביעים כדי לגשת לאיברים מסוימים
return 0;
}השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה לוגיקה וזרימת תוכנית
1יסודות המצביעים
מהו מצביע?הכרזה על מצביעיםאופרטור לקיחת הכתובת (&)אופרטור ביטול ההפניה (*)מצביעי NULLסיכום: יסודות המצביעים2מצביעים ומערכים
שמות מערכים כמצביעיםאיברי מערך ומצביעיםאריתמטיקה של מצביעיםהשוואת מצביעיםסיכום: מעבר על מערך באמצעות מצביעים5מצביעים ופונקציות
העברה לפי ערךהעברת מצביעים לפונקציותשינוי משתנים באמצעות מצביעיםדוגמה קלאסית: החלפההעברת מערכים לפונקציותחזרה: ארגומנטים של מצביעי פונקציה3מערכי תווים ומחרוזות
מחרוזות כמערכי charתו הסיום nullקלט מחרוזת באמצעות scanfשימוש ב־strlen()שימוש ב־strcpy()שימוש ב־strcat()שימוש ב־strcmp()סיכום: פונקציות מחרוזת בסיסיותתרגלו בעצמכם: קומפיילר C אונליין