שימוש ב-sizeof() להקצאה
חלק מהיחידה לוגיקה וזרימת תוכנית במסלול ה-C של Coddy. שיעור 33 מתוך 63.
בעוד ש־malloc() מאפשרת לך להקצות זיכרון באופן דינמי, ישנו נוהג מומלץ חשוב שהופך את הקוד שלך לנייד יותר וקל יותר לתחזוקה: שימוש באופרטור sizeof() כדי לקבוע כמה בתים להקצות.
האופרטור sizeof() מחזיר את מספר הבייטים הדרושים לאחסון של סוג נתונים מסוים במערכת שלך. במקום לקבוע מראש את גודל הבייטים, אפשר לתת ל־sizeof() לחשב את הכמות הנכונה באופן אוטומטי:
// במקום לנחש גדלים בבתים:
int *ptr = (int*)malloc(4); // מניח ש-int הוא בגודל 4 בתים
// השתמשו ב-sizeof() כדי שהקוד יהיה נייד:
int *ptr = (int*)malloc(sizeof(int)); // נכון תמידהגישה הזו נעשית שימושית במיוחד כשמקצים מערכים. כדי להקצות מקום למספר איברים, כופלים את מספר האיברים בגודל של כל איבר:
// הקצה מקום ל-10 מספרים שלמים
int *arr = (int*)malloc(10 * sizeof(int));
// הקצה מקום ל-5 ערכים מסוג double
double *values = (double*)malloc(5 * sizeof(double));השימוש ב־sizeof() מאפשר לקוד שלך לפעול כראוי במערכות שונות שבהן גדלי טיפוסי הנתונים עשויים להיות שונים, ומבהיר היטב שהתכוונת להקצות מקום למספר מסוים של איברים מטיפוס מסוים.
אתגר
קלכתבו תוכנית C שמדגימה שימוש נכון ב־sizeof() עם malloc() להקצאת זיכרון דינמית. התוכנית שלכם צריכה:
- לקרוא מהמשתמש מספר שלם
nשמייצג את מספר האיברים שיש להקצות - להשתמש ב־
malloc()עםsizeof()כדי להקצות באופן דינמי זיכרון למערך שלnערכי double - להמיר את מצביע ה־void שהוחזר למצביע ל־double
- לקרוא מהמשתמש
nערכי double ולאחסן אותם במערך שהוקצה - לחשב את סך הזיכרון שהוקצה בבתים ולהדפיס אותו בתבנית:
Memory allocated: [bytes] bytes - לחשב ולהדפיס את הממוצע של כל הערכים בדיוק בשתי ספרות אחרי הנקודה העשרונית, בתבנית:
Average: [value] - למצוא ולהדפיס את הערך הגדול ביותר בדיוק בשתי ספרות אחרי הנקודה העשרונית, בתבנית:
Largest: [value]
זכרו לכלול את הכותרת <stdlib.h> כדי להשתמש ב־malloc(). התוכנית שלכם צריכה להדגים כיצד sizeof() מבטיח הקצאת זיכרון נכונה, בלי תלות בגדלים של טיפוסי הנתונים במערכת.
לדוגמה, אם הקלט הוא:
3
2.5 7.8 4.1הפלט שלכם צריך להיות:
Memory allocated: 24 bytes
Average: 4.80
Largest: 7.80האתגר הזה מחזק את החשיבות של שימוש ב־sizeof() כדי להפוך את הקצאת הזיכרון הדינמית לניידת ולנוחה לתחזוקה, וכדי לחשב באופן אוטומטי את מספר הבתים הנכון הדרוש לכל טיפוס נתונים בכל מערכת.
נסו בעצמכם
#include <stdio.h>
#include <stdlib.h>
int main() {
// קראו את מספר האיברים
int n;
scanf("%d", &n);
// TODO: כתבו את הקוד שלכם למטה
// 1. הקצו זיכרון עבור n ערכים מסוג double באמצעות malloc() ו-sizeof()
// 2. המירו את המצביע שהוחזר ל-double*
// 3. קראו n ערכים מסוג double ושמרו אותם במערך שהוקצה
// 4. חשבו והדפיסו את כמות הזיכרון שהוקצה בבתים
// 5. חשבו והדפיסו את הממוצע עם 2 ספרות אחרי הנקודה העשרונית
// 6. מצאו והדפיסו את הערך הגדול ביותר עם 2 ספרות אחרי הנקודה העשרונית
return 0;
}השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה לוגיקה וזרימת תוכנית
1יסודות המצביעים
מהו מצביע?הכרזה על מצביעיםאופרטור לקיחת הכתובת (&)אופרטור ביטול ההפניה (*)מצביעי NULLסיכום: יסודות המצביעים2מצביעים ומערכים
שמות מערכים כמצביעיםאיברי מערך ומצביעיםאריתמטיקה של מצביעיםהשוואת מצביעיםסיכום: מעבר על מערך באמצעות מצביעים5מצביעים ופונקציות
העברה לפי ערךהעברת מצביעים לפונקציותשינוי משתנים באמצעות מצביעיםדוגמה קלאסית: החלפההעברת מערכים לפונקציותחזרה: ארגומנטים של מצביעי פונקציה3מערכי תווים ומחרוזות
מחרוזות כמערכי charתו הסיום nullקלט מחרוזת באמצעות scanfשימוש ב־strlen()שימוש ב־strcpy()שימוש ב־strcat()שימוש ב־strcmp()סיכום: פונקציות מחרוזת בסיסיות6ניהול זיכרון
זיכרון מחסנית לעומת ערימההקצאה דינמית - malloc()שימוש ב-sizeof() להקצאהבדיקת כישלון בהקצאהשחרור זיכרון באמצעות free()הקצאה באמצעות calloc()סיכום: מערך דינמיתרגלו בעצמכם: קומפיילר C אונליין