מבחן C לגאמא: 12 שאלות עם פתרונות
מאת ארז ברזאני · תרגול מקורי של GammaCyber
תרגול עצמאי של מצביעים, מערכים, זיכרון וקריאת קוד C. בכל שאלה מוגדרות ההנחות, ואחרי הניסיון אפשר לפתוח פתרון. אלה שאלות מקוריות ללמידה, ולא שאלות ממיון צבאי.
איך לתרגל
לפני שמריצים קוד, מסמנים את הטיפוס ואת אורך החיים של כל ערך. מפרידים בין המשתנה שמחזיק כתובת לבין האובייקט שאליו הוא מצביע. אין לנחש פלט כאשר הקוד חורג מגבולות מערך או משתמש באובייקט שכבר אינו חי; במקרים כאלה עצם זיהוי הבעיה הוא התשובה.
דוגמה: כתובת לעומת ערך
אם x הוא int שערכו 4 ו־p מצביע אליו, הביטוי *p += 2 משנה את x ל־6. שינוי p עצמו היה משנה את הכתובת המוחזקת במצביע. בדיקת מעקב טובה רושמת בטורים נפרדים x, p ו־*p; היא אינה מתייחסת לשלושתם כאל אותו משתנה.
תרגול עצמאי עם הסברים
נסו לענות לפני פתיחת ההסבר. אפשר לעבוד ללא שעון או לבחור זמן אימון משלכם.
שאלה 1: מה ערך x בסוף?
int x=4; int *p=&x; *p += 2;- 4
- 6
- כתובת בזיכרון
תשובה והסבר
6: p מצביע אל x. ההשמה דרך *p משנה את אותו אובייקט.
שאלה 2: כמה איברים במערך a?
int a[4]={1,2,3,4}; /* sizeof a / sizeof a[0] */- 3
- 4
- תלוי בגודל מצביע
תשובה והסבר
4: למערך מקומי מסוג int[4], היחס בין גודל המערך לגודל איבר הוא 4.
שאלה 3: מה ערך a[1] אחרי ההשמה?
int a[3]={1,2,3}; int *p=a; *(p+1)=7;- 1
- 7
- 0
תשובה והסבר
7: p+1 מצביע לאיבר השני, בצעדים של sizeof(int).
שאלה 4: האם a[3] הוא איבר תקף?
int a[3]={0};- כן
- לא
- רק אם הוקצה על המחסנית
תשובה והסבר
לא: האינדקסים התקפים הם 0, 1, 2. קריאה ב־a[3] חורגת מהמערך.
שאלה 5: מה ההבדל בין sizeof("hi") ל־strlen("hi")?
- שניהם 2
- sizeof הוא 3 ו־strlen הוא 2
- sizeof הוא 2 ו־strlen הוא 3
תשובה והסבר
sizeof הוא 3 ו־strlen הוא 2: הליטרל כולל שני תווים וסיומת אפס; strlen אינו סופר את הסיומת.
שאלה 6: האם מותר לשנות את הטקסט דרך p?
char *p="hi"; /* p[0]='H'; */- כן
- לא; כתיבה לליטרל מחרוזת אינה מוגדרת
- רק בתו הראשון
תשובה והסבר
לא; כתיבה לליטרל מחרוזת אינה מוגדרת: יש להשתמש במערך ניתן לשינוי כגון char p[]="hi" במקום לכתוב לליטרל.
שאלה 7: מה תוצאת 7/2 כאשר שני האופרנדים הם int חיוביים?
- 3
- 3.5
- 4
תשובה והסבר
3: חלוקה של מספרים שלמים מחזירה מנה שלמה; עבור ערכים חיוביים כאן מתקבל 3.
שאלה 8: מה ערך x אחרי קריאה ל־f(x)?
void f(int n){n=9;}
int x=2; f(x);- 9
- 2
- אינו מוגדר
תשובה והסבר
2: הפרמטר מועבר בערך. כדי לשנות את x דרך הפונקציה צריך להעביר את כתובתו.
שאלה 9: מה נדרש לפני dereference של malloc?
- רק free
- לבדוק שההחזרה אינה NULL
- להגדיל את המצביע
תשובה והסבר
לבדוק שההחזרה אינה NULL: הקצאה יכולה להיכשל. גם אחרי הצלחה יש להישאר בגבולות ההקצאה ולשחרר פעם אחת.
שאלה 10: האם קריאת *p אחרי free(p) תקינה?
- כן כל עוד הערך לא השתנה
- לא
- כן אם p אינו NULL
תשובה והסבר
לא: free מסיים את חיי ההקצאה. ערך מצביע שאינו NULL אינו הוכחת תקפות.
שאלה 11: מה בודק התנאי הבא?
if (x = 3) { /* ... */ }- אם x שווה ל־3
- משים 3 ב־x ובודק ערך אמת
- אם x קטן מ־3
תשובה והסבר
משים 3 ב־x ובודק ערך אמת: = הוא אופרטור השמה. לבדיקת שוויון נדרש ==.
שאלה 12: מה משמעות const int *p?
- אי אפשר לשנות את p
- אי אפשר לשנות את ה־int דרך p
- האובייקט תמיד גלובלי
תשובה והסבר
אי אפשר לשנות את ה־int דרך p: const מגביל כאן את הגישה לערך דרך המצביע; מותר לשנות את הכתובת ב־p.
הכפתור מסמן סיום לפי הדיווח שלכם; פתיחת פתרון אינה בדיקת ידע.
הצעד הבא בלמידה
בחרו עיקרון אחד שעדיין לא ברור, חזרו לדוגמה ונסו להסביר אותה במילים שלכם.
לשיעור הקשור בקורסלמפת הקורס וחלוקת התוכןהמשאבים בעמוד הזה פתוחים. חלק משיעורי הקורס זמינים בתצוגה מקדימה, וגישה מלאה בתשלום.
להמשך תרגול
מקורות טכניים וגבולות התרגול
המקורות מסבירים טכנולוגיה. הם אינם אסמכתה למבנה מיון צבאי. התוכן כאן עצמאי; הנחיות הזימון האישי הן הקובעות. מצאתם שגיאה? כתבו לנו.