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

Slides:



Advertisements
Similar presentations
ממיבחניםC שאלות ++.
Advertisements

מבוא למדעי המחשב לתעשייה וניהול
Agenda  Review: pointer & array  Relationship between pointer & array  Dynamic memory allocation.
הרצאה 04 הקצאות דינאמיות קרן כליף.
More Pointers Write a program that: –Calls a function to input an integer value –The above function calls another function that will double the input value.
הקצאות דינאמיות קרן כליף.
Pointers הרצאה קריטית. השאלות הפתוחות מה זה ה- & שמופיע ב scanf מדוע כשמעבירים מחרוזת ל scanf אין צורך ב & האם ניתן להכריז על מערך שגדלו אינו ידוע בתחילת.
1 מבוא למדעי המחשב הקצאה דינאמית. 2 הקצאת זיכרון דינאמית  כאשר אנו משתמשים במערכים, אנו מקצים אוטומטית את הזיכרון המקסימלי שנצטרך.  בפועל, אנו משתמשים.
תכנות מונחה עצמים Object Oriented Programming (OOP) אתגר מחזור ב'
תרגול מס' 2  העברת פרמטרים לתוכניות ב-C  קלט ופלט ב-C  I/O redirection  זיכרון דינמי  מצביעים  מערכים  גישות לא חוקיות לזיכרון.
רקורסיות נושאי השיעור פתרון משוואות רקורסיביות שיטת ההצבה
תכנות תרגול 11 שבוע : מבנים מטרת המבנים היא לאפשר למתכנת להגדיר טיפוסי משתנים חדשים אשר מתאימים ספציפית לבעיה שאותה התוכנית פותרת. מטרת המבנים.
תרגול 5 רקורסיות. רקורסיה קריאה של פונקציה לעצמה –באופן ישיר או באופן עקיף היתרון : תכנות של דברים מסובכים נעשה ברור ונוח יותר, מכיוון שזו למעשה צורת.
תכנות תרגול 4 שבוע : לולאות while לולאות while while (condition) { loop body } במקרה של קיום התנאי מתבצע גוף הלולאה ברגע שהתנאי לא מתקיים נצא.
מבוא לשפת C חידות ונקודות חשובות נכתב על-ידי יורי פקלני. © כל הזכויות שמורות לטכניון – מכון טכנולוגי לישראל.
מבוא למדעי המחשב תרגול 8 - מחרוזות שעת קבלה : יום שני 11:00-12:00 דוא " ל :
מבוא כללי למדעי המחשב תרגול. הבית האדום כתובת : רחוב קוקוריקו 2 הבית הירוק כתובת : רחוב קוקוריקו 4 הבית הצהוב כתובת : רחוב קוקוריקו 1 הבית הורוד כתובת.
תכנות תרגול 9 שבוע : מערכים int a; a=5; int a[10]; a[2] = 5; 5 a a[0] a[1] a[2] a[9]  5 משתנה בודד מערך גישה למשתנה השלישי במערך.
תוכנה 1 - חזרה שולי לב יהודי 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית ע ” י אינדקס. ב -C מערך מוגדר.
11 Introduction to Programming in C - Fall 2010 – Erez Sharvit, Amir Menczel 1 Introduction to Programming in C תרגול
מבוא למדעי המחשב © אריק פרידמן 1 מצביעים כמערכים דוגמה.
תרגול חזרה. מבנה האובייקט תאר את מבנה האובייקט כולל מבנה טבלאות הפונקציות הוירטואליות עבור התכנית הבאה struct A { int x; virtual void a() {}; }; struct.
תכנות תרגול 6 שבוע : תרגיל שורש של מספר מחושב לפי הסדרה הבאה : root 0 = 1 root n = root n-1 + a / root n-1 2 כאשר האיבר ה n של הסדרה הוא קירוב.
11 Introduction to Programming in C - Fall 2010 – Erez Sharvit, Amir Menczel 1 Introduction to Programming in C תרגול
מנפה שגיאות - DEBUGGER מבוא למדעי המחשב (234114) רועי מלמד
תכנות תרגול 6 שבוע : הגדרת פונקציות return-value-type function-name(parameter1, parameter2, …) הגדרת סוג הערכים שהפונקציה מחזירה שם הפונקציהרשימת.
תכנות תרגול 10 שבוע : הקשר בין מערכים למצביעים נרצה לעמוד על הקשר בין מערך למצביע מאחר ומערכים הם הכללה של משתנים הרי שברור שלמערך ולכל אחד מאיבריו.
מבוא כללי למדעי המחשב תרגול 3. לולאות while לולאות while while (condition) { loop body } במקרה של קיום התנאי מתבצע גוף הלולאה ברגע שהתנאי לא מתקיים נצא.
תרגול 2 העברת פרמטרים לתוכניות ב -C קלט ופלט ב -C I/O redirection זיכרון דינמי מצביעים מערכים גישות לא חוקיות לזיכרון.
תכנות תרגול 12 שבוע : הקצאת זיכרון דינאמית הזיכרון המקסימאלי ששימש את התוכנית שלנו עד היום היה קבוע מראש. לפני הרצת התוכנית, לאחר שהתוכנית עברה.
1 מבוא למדעי המחשב ארגומנטים לתוכנית בזמן ריצה קבצים הקדם מעבד Preprocessor טיפוסים סדורים Enumerated Types Typedef.
תכנות תרגול 5 שבוע : הגדרת פונקציות return-value-type function-name(parameter1, parameter2, …) הגדרת סוג הערכים שהפונקציה מחזירה שם הפונקציהרשימת.
מערכים עד היום כדי לייצג 20 סטודנטים נאלצנו להגדיר עד היום כדי לייצג 20 סטודנטים נאלצנו להגדיר int grade1, grade2, …, grade20; int grade1, grade2, …, grade20;
עקרון ההכלה וההדחה.
תכנות מונחה עצמים Object Oriented Programming (OOP) אתגר מחזור ב' Templates תבניות.
Last time on Clang משתנה: "פתק" המשמש את המחשב לשמירת מידע. לכל משתנה יש שם וטיפוס כללים לשמות משתנים –חייבים להכיל רק אותיות, מספרים ו '_' –חייבים להתחיל.
תוכנה 1 - תרגול שיעור 10 Pointers (2) שולי לב יהודי
מבוא כללי למדעי המחשב הקצאת זיכרון דינאמית
1 מבוא למדעי המחשב סיבוכיות. 2 סיבוכיות - מוטיבציה סידרת פיבונאצ'י: long fibonacci (int n) { if (n == 1 || n == 2) return 1; else return (fibonacci(n-1)
מבוא למדעי המחשב תרגול 12 – הקצאת זיכרון דינאמית שעת קבלה : יום שני 11:00-12:00 דוא " ל :
תכנות תרגול 8 שבוע : מערכים עד היום התוכניות שלנו לא ידעו לשמור כמות גדולה של מידע ללא הגדרת כמות גדולה של משתנים. עד היום התוכניות שלנו לא.
Structure. מה לומדים היום ? דרך לבנות מבנה נתונים בסיסי – Structure מייצר " טיפוס " חדש מתאים כאשר רוצים לאגד כמה משתנים יחד דוגמאות : עובד : שם, טלפון,
הגדרת משתנים יום שישי 18 ספטמבר 2015 יום שישי 18 ספטמבר 2015 יום שישי 18 ספטמבר 2015 יום שישי 18 ספטמבר 2015 יום שישי 18 ספטמבר 2015 יום שישי 18 ספטמבר.
CPT: Arrays of Pointers/ Computer Programming Techniques Semester 1, 1998 Objectives of these slides: –to illustrate the use of arrays.
Methods public class Demonstrate { public static void main (String argv[]) { public static void main (String argv[]) { int script = 6, acting = 9, directing.
קורס תכנות שיעור שמיני: הקצאת זיכרון דינאמית, הצצה לייצוג ועיבוד תמונות 1.
מבוא למדעי המחשב לתעשייה וניהול הרצאה 7. סברוטינות subroutines.
קורס תכנות שיעור עשירי: מיונים, חיפושים, וקצת סיבוכיות חישוב.
תכנות מכוון עצמים ושפת ++C וויסאם חלילי. TODAY TOPICS: 1. Function Overloading & Default Parameters 2. Arguments By Reference 3. Multiple #include’s 4.
Arrays, Strings, and Memory. Command Line Arguments #include int main(int argc, char *argv[]) { int i; printf("Arg# Contents\n"); for (i = 0; i < argc;
Dynamic Allocation. Malloc - Reminder void* malloc(unsigned int nBytes); Used to dynamically allocate nBytes in memory Returns a pointer to the allocated.
מבנים קרן כליף. ביחידה זו נלמד :  מהו מבנה (struct)  איתחול מבנה  השמת מבנים  השוואת מבנים  העברת מבנה לפונקציה  מבנה בתוך מבנה  מערך של מבנים.
עקרונות תכנות מונחה עצמים תרגול 11: OOP in C++. Outline  Where do the objects live ?  Inheritance  Slicing  Overriding vs Shadowing.
מחרוזות – הטיפוס String
מבוא למדעי המחשב סיבוכיות.
הקצאות דינאמיות בשילוב מבנים
מערכים ומצביעים הקצאה דינאמית של מערכים דו-מימדיים
מצביעים קרן כליף.
הקצאות דינאמיות קרן כליף.
שיעור שישי: מחרוזות, מצביעים
Introduction to Programming in C
הקצאת זיכרון דינאמית מבוא כללי למדעי המחשב
מבוא כללי למדעי המחשב תרגול 6
סוגי משתנים קרן כליף.
מערכים של מצביעים הקצאה דינאמית
Programming in C תרגול Introduction to C - Fall Amir Menczel.
מבוא למדעי המחשב מצביעים.
תירגול 8:מצביעים והקצאה דינאמית
Computer Programming תרגול 3 Summer 2016
Engineering Programming A
Presentation transcript:

קורס תכנות שיעור שנים-עשר: ניהול זיכרון 1

הקצאת זיכרון דינאמית עד עכשיו עשינו "הקצאה סטטית" הגדרנו את משתני התוכנית כבר כשכתבנו אותה הקומפיילר הקצה עבורם מקום בזיכרון בפרט, בהגדרת מערך קבענו את גודלו ולא יכולנו לשנות אותו בזמן הריצה למשל: הנחנו חסם עליון על כמות המשתנים הנדרשת int main() { int a[10];... }; 2

טעות נפוצה ניסיון להגדיר מערך בגודל משתנה הקומפיילר צריך לדעת כמה זיכרון להקצות לכל משתנה 3 int main() {... printf("enter number of elements\n"); scanf("%d", &size); int a[size];... }; ×

הקצאת זיכרון דינאמית לא תמיד כל המידע ידוע בזמן כתיבת התכנית לדוגמא, תלוי בקלט מהמשתמש ניתן להקצות זיכרון במהלך ריצת התכנית הזיכרון יוקצה באזור ה"ערימה" (heap) לא נעלם כאשר הפונקציה מסתיימת הקצאה ושחרור באחריות המתכנת 4

מודל הזיכרון של התכנית הקוד פקודות התכנית Data מחרוזות שהוגדרו ע"י המתכנת מחסנית (Stack) משמש לאיחסון משתנים לוקאליים Last In First Out (LIFO) בשליטת התכנית ערימה (Heap) בשליטת המתכנתת (היום!) קריאה בלבד קריאה וכתיבה 5 קוד data מחסנית (stack) ערימה (heap)

הקצאה דינאמית בשפת C C מספקת לנו מנגנון בסיסי להקצאה ושחרור של זיכרון מוגדרות ב stdlib.h 6 פונקציהמטרה mallocהקצאת זיכרון בגודל מבוקש callocהקצאת מערך של אברים ואיתחולו ל-0 freeשחרור זיכרון שהוקצה קודם לכן reallocשינוי גודלו של זיכרון שהוקצה קודם לכן

הפונקציה malloc מקבלת את גודל הזיכרון שנרצה להקצות (בבתים) מחזירה את הכתובת לזיכרון שהוקצה NULL אם נכשלה תמיד יש לבדוק אם הקצאת הזיכרון הצליחה או נכשלה void *malloc(int nBytes) 7

malloc דוגמא הקצאה דינאמית של זיכרון בגודל 10 int האופרטור sizeof מחזיר את הגודל (בבתים) של הטיפוס המבוקש הפונקציה מחזירה כתובת (void*) באחריותנו להמיר את המצביע לטיפוס המתאים int main() { int *a = (int*) malloc(10 * sizeof(int));... return 0; } 8

שימוש ב malloc הערך המוחזר הוא כתובת כלשהי ללא ציון הטיפוס כדי להשתמש במצביע יש לבצע המרה (casting) type *var-name = (type*) malloc(amount * sizeof(type)); מצביע לתחילת הזיכרון המוקצה המרת הערך המוחזר לטיפוס המתאים גודל הטיפוס בבתים 9

הפונקציה free – שיחרור זיכרון באחריות המתכנת לשחרר זיכרון שהוקצה דינאמית ptr- מצביע לזיכרון שהוקצה דינאמית ptr- ערך מוחזר מקריאה ל-malloc, calloc או realloc אחרת שגיאה אין שיחרור חלקי של זיכרון void free(void *ptr) 10

הקצאת מערך בגודל משתנה 11 int main() { int *a, size, i; printf("Enter array size\n"); scanf("%d", &size); a = (int*) malloc(size * sizeof(int)); if (a == NULL) return 1; for (i = 0; i < size; i++) scanf("%d", &a[i]); for (i = 0; i < size; i++) printf("%d", a[i]); free(a); return 0; } קרא גודל מערך מהמשתמש הקצאת זיכרון בגודל המבוקש בדיקה האם ההקצאה הצליחה קלט מהמשתמש הדפסת תוכן המערך שיחרור הזיכרון

הקצאת מערך בגודל משתנה 12 int main() { int *a, size, i; printf("Enter array size\n"); scanf("%d", &size); a = (int*) malloc(size * sizeof(int)); if (a == NULL) return 1; for (i = 0; i < size; i++) scanf("%d", &a[i]); for (i = 0; i < size; i++) printf("%d", a[i]); free(a); return 0; } main a size i Stack Heap

פונקציות נוספות מקצה מערך של n איברים, כל איבר בגודל size_el בתים, כל בית מאותחל לאפס (ולכן פחות יעילה). מקבלת מצביע לזיכרון שהוקצה דינאמית ומספר בתים size הפונקציה מקצה זיכרון בהתאם לגודל הנדרש מעתיקה את תכולת הזיכרון הישן לחדש משחררת את הזיכרון הישן בשתי הפונקציות קריאה מוצלחת תחזיר את כתובת תחילת הזיכרון המוקצה, אחרת יוחזר NULL void* calloc( unsigned int n, unsigned int size_el ) void* realloc( void *ptr, unsigned int size ) 13

calloc - דוגמא 14 int main() { int *a, size, i; printf("Enter array size\n"); scanf("%d", &size); a = (int*) calloc(size, sizeof(int)); if (a == NULL) return 1; for (i = 0; i < size; i++) scanf("%d", &a[i]); for (i = 0; i < size; i++) printf("%d", a[i]); free(a); return 0; } הקצאת size אלמנטים, כל אלמנט בגודל sizeof(int) הפונקציה תאתחל את הזיכרון ל-0

realloc - דוגמא int *ptr = NULL; int size = 0, new_size = 0; scanf("%d", &size); ptr = (int*) malloc( size * sizeof(int) ); /* incomplete, must check if allocation succeeded */... scanf("%d", &new_size); ptr = (int*) realloc( ptr, new_size*sizeof(int) ); /* incomplete, must check if allocation succeeded */... if (ptr != NULL) free(ptr); הקצאת זיכרון הקצאת חדשה שחרור זיכרון 15

זיכרון שהוקצה דינאמית 16 int* func() { int *memPtr = NULL; memPtr = (int*) malloc(10 * sizeof(int));... return memPtr; } int main() { int * ptr = func(); if (ptr != NULL) { // do something with ptr free(ptr); ptr = NULL; } memPtr ptr מותר להחזיר כתובת לזיכרון שהוקצה דינאמית הזיכרון שייך לתוכנית ולא לפונקציה

שיחרור זיכרון אפשרות א': הפונקציה שהקצתה האפשרות המועדפת – כותב הפונקציה אחראי על הזיכרון הדינאמי אפשרות ב': החזרת הכתובת האחריות עוברת למי שקרא לפונקציה המקצה חובה לתעד זאת, אחרת "דליפת זיכרון" עלינו להימנע ממצב שבו יש הקצאת זיכרון אבל לא מתקיים א' או ב' 17

קריאת שורת קלט בגודל לא ידוע 18 char* readLine() { int index = 0, c, capacity = INITIAL_SIZE; char *buffer = (char*) malloc(capacity * sizeof(char)); if (buffer == NULL) return NULL; for (c = getchar(); c != '\n'; c = getchar()) { if (index == capacity – 1) { buffer = (char*) realloc(buffer, capacity * INCREMENT * sizeof(char)); if (buffer == NULL) return NULL; capacity = capacity * INCREMENT * sizeof(char); } buffer[index++] = c; } buffer[index] = '\0'; return buffer; }

קריאת שורת קלט בגודל לא ידוע 19 char* readLine() { int index = 0, c, capacity = INITIAL_SIZE; char *buffer = (char*) malloc(capacity * sizeof(char)); if (buffer == NULL) return NULL; for (c = getchar(); c != '\n'; c = getchar()) { if (index == capacity – 1) { buffer = (char*) realloc(buffer, capacity * INCREMENT * sizeof(char)); if (buffer == NULL) return NULL; capacity = capacity * INCREMENT * sizeof(char); } buffer[index++] = c; } buffer[index] = '\0'; return buffer; } מערך בגודל התחלתי כלשהו

קריאת שורת קלט בגודל לא ידוע 20 char* readLine() { int index = 0, c, capacity = INITIAL_SIZE; char *buffer = (char*) malloc(capacity * sizeof(char)); if (buffer == NULL) return NULL; for (c = getchar(); c != '\n'; c = getchar()) { if (index == capacity – 1) { buffer = (char*) realloc(buffer, capacity * INCREMENT * sizeof(char)); if (buffer == NULL) return NULL; capacity = capacity * INCREMENT * sizeof(char); } buffer[index++] = c; } buffer[index] = '\0'; return buffer; } יש לוודא שהקצאת הזיכרון לא נכשלה

קריאת שורת קלט בגודל לא ידוע 21 char* readLine() { int index = 0, c, capacity = INITIAL_SIZE; char *buffer = (char*) malloc(capacity * sizeof(char)); if (buffer == NULL) return NULL; for (c = getchar(); c != '\n'; c = getchar()) { if (index == capacity – 1) { buffer = (char*) realloc(buffer, capacity * INCREMENT * sizeof(char)); if (buffer == NULL) return NULL; capacity = capacity * INCREMENT * sizeof(char); } buffer[index++] = c; } buffer[index] = '\0'; return buffer; } קריאת קלט מהמשתמש עד לסוף השורה

קריאת שורת קלט בגודל לא ידוע 22 char* readLine() { int index = 0, c, capacity = INITIAL_SIZE; char *buffer = (char*) malloc(capacity * sizeof(char)); if (buffer == NULL) return NULL; for (c = getchar(); c != '\n'; c = getchar()) { if (index == capacity – 1) { buffer = (char*) realloc(buffer, capacity * INCREMENT * sizeof(char)); if (buffer == NULL) return NULL; capacity = capacity * INCREMENT * sizeof(char); } buffer[index++] = c; } buffer[index] = '\0'; return buffer; } האם נגמר המקום?

קריאת שורת קלט בגודל לא ידוע 23 char* readLine() { int index = 0, c, capacity = INITIAL_SIZE; char *buffer = (char*) malloc(capacity * sizeof(char)); if (buffer == NULL) return NULL; for (c = getchar(); c != '\n'; c = getchar()) { if (index == capacity – 1) { buffer = (char*) realloc(buffer, capacity * INCREMENT * sizeof(char)); if (buffer == NULL) return NULL; capacity = capacity * INCREMENT * sizeof(char); } buffer[index++] = c; } buffer[index] = '\0'; return buffer; } נקצה מערך גדול יותר

קריאת שורת קלט בגודל לא ידוע 24 char* readLine() { int index = 0, c, capacity = INITIAL_SIZE; char *buffer = (char*) malloc(capacity * sizeof(char)); if (buffer == NULL) return NULL; for (c = getchar(); c != '\n'; c = getchar()) { if (index == capacity – 1) { buffer = (char*) realloc(buffer, capacity * INCREMENT * sizeof(char)); if (buffer == NULL) return NULL; capacity = capacity * INCREMENT * sizeof(char); } buffer[index++] = c; } buffer[index] = '\0'; return buffer; } לא לשכוח לבדוק

קריאת שורת קלט בגודל לא ידוע 25 char* readLine() { int index = 0, c, capacity = INITIAL_SIZE; char *buffer = (char*) malloc(capacity * sizeof(char)); if (buffer == NULL) return NULL; for (c = getchar(); c != '\n'; c = getchar()) { if (index == capacity – 1) { buffer = (char*) realloc(buffer, capacity * INCREMENT * sizeof(char)); if (buffer == NULL) return NULL; capacity = capacity * INCREMENT * sizeof(char); } buffer[index++] = c; } buffer[index] = '\0'; return buffer; } לא לשכוח לעדכן את capacity

קריאת שורת קלט בגודל לא ידוע 26 char* readLine() { int index = 0, c, capacity = INITIAL_SIZE; char *buffer = (char*) malloc(capacity * sizeof(char)); if (buffer == NULL) return NULL; for (c = getchar(); c != '\n'; c = getchar()) { if (index == capacity – 1) { buffer = (char*) realloc(buffer, capacity * INCREMENT * sizeof(char)); if (buffer == NULL) return NULL; capacity = capacity * INCREMENT * sizeof(char); } buffer[index++] = c; } buffer[index] = '\0'; return buffer; } נשמור את התו שקראנו במקום המתאים

קריאת שורת קלט בגודל לא ידוע 27 char* readLine() { int index = 0, c, capacity = INITIAL_SIZE; char *buffer = (char*) malloc(capacity * sizeof(char)); if (buffer == NULL) return NULL; for (c = getchar(); c != '\n'; c = getchar()) { if (index == capacity – 1) { buffer = (char*) realloc(buffer, capacity * INCREMENT * sizeof(char)); if (buffer == NULL) return NULL; capacity = capacity * INCREMENT * sizeof(char); } buffer[index++] = c; } buffer[index] = '\0'; return buffer; } בסוף נוסיף ‘\0’

קריאת שורת קלט בגודל לא ידוע 28 char* readLine() { int index = 0, c, capacity = INITIAL_SIZE; char *buffer = (char*) malloc(capacity * sizeof(char)); if (buffer == NULL) return NULL; for (c = getchar(); c != '\n'; c = getchar()) { if (index == capacity – 1) { buffer = (char*) realloc(buffer, capacity * INCREMENT * sizeof(char)); if (buffer == NULL) return NULL; capacity = capacity * INCREMENT * sizeof(char); } buffer[index++] = c; } buffer[index] = '\0'; return buffer; } מחזירים זיכרון שהוקצה דינאמית – באחריות הלקוח לשחרר (צריך לתעד)

שימוש ב readLine 29 int main() { char *line = readLine(); if (line == NULL) { printf("Fatal error: memory allocation failed!\n"); return 1; } printf("%s\n", line); free(line); return 0; } קריאת שורת קלט מהמשתמש

שימוש ב readLine 30 int main() { char *line = readLine(); if (line == NULL) { printf("Fatal error: memory allocation failed!\n"); return 1; } printf("%s\n", line); free(line); return 0; } אם הייתה בעיה נדפיס הודעת שגיאה ונסיים

שימוש ב readLine 31 int main() { char *line = readLine(); if (line == NULL) { printf("Fatal error: memory allocation failed!\n"); return 1; } printf("%s\n", line); free(line); return 0; } שימו לב לערך המוחזר

שימוש ב readLine 32 int main() { char *line = readLine(); if (line == NULL) { printf("Fatal error: memory allocation failed!\n"); return 1; } printf("%s\n", line); free(line); return 0; } נשתמש בקלט

שימוש ב readLine 33 int main() { char *line = readLine(); if (line == NULL) { printf("Fatal error: memory allocation failed!\n"); return 1; } printf("%s\n", line); free(line); return 0; } כשאיננו צריכים יותר את הקלט, נשחרר את הזיכרון

הקצאת זיכרון - בעיות נדיר שהקצאת הזיכרון נכשלת אפשרויות לטיפול: החזרת הערך NULL מהפונקציה - כאשר תפקיד הפונקציה הוא הקצאת הזיכרון שימוש בפונקציה exit לסיום התכנית

הפונקציה exit מוגדרת ב stdlib.h מסיימת את התכנית באופן מיידי נשתמש רק כאשר מתרחשת בעיה שאין לנו שום דרך לטפל בה בדרך כלל נדפיס הודעת שגיאה למשתמש ונסיים את תכנית void exit(int status);

דוגמה לשימוש ב -exit נשנה את גודלו של מערך של int בעזרת realloc אם השינוי נכשל, נסיים את התכנית 36 void resize(int *array, int newSize) { if (array == NULL) return; array = (int*) realloc(array, newSize * sizeof(int)); if (array == NULL) { printf("Fatal error: memory allocation failed!\n"); exit(1); }

הקצאה דינאמית של מבנים בדיוק כמו בטיפוסים בסיסיים 37 typedef struct { char *title, *author; } Book; Book* newBook(const char *title, const char *author) { Book *result = (Book*) malloc(sizeof(Book)); /* incomplete, must check if allocation succeeded */ result->title = strdup(title); result->author = strdup(author); /* incomplete, must check if allocation succeeded */ return result; }

משתנים בשורת הפקודה 38

Command Line Arguments בעת הרצת התוכנית ניתן להעביר לה משתנים בשורת הפקודה משתנים אלו יועברו כארגומנטים ל-main כל המשתנים הם מחרוזות 39 int main(int argc, char *argv[]) { } מספר המשתניםמערך של מחרוזות (המשתנים)

מי מעביר את הערכים ? סביבת הריצה (מערכת ההפעלה) אחראית להעביר את המשתנים ל-main המשתנים יקיימו את התנאים הבאים: argc יהיה חיובי argv[argc] == NULL argv[0] היא מחרוזת המכילה את שם התכנית 40

דוגמה התכנית מדפיסה את ערכי המשתנים 41 #include int main(int argc, char *argv[]) { int i; for (i = 0; i < argc; i++) printf("argv[%d] = %s\n", i, argv[i]); return EXIT_SUCCESS; }

דוגמת הרצה 42

מערך של ארגומנטים 43 argc 4 argv NULL “1” “abcde” “100” “hello world”

מחשבון פשוט 44 int main(int argc, char *argv[]) { double leftOperand, rightOperand, result; char operator; /* incomplete, make sure all arguments are present */ leftOperand = atof(argv[1]); rightOperand = atof(argv[3]); operator = *argv[2]; switch (operator) { case '+': result = leftOperand + rightOperand; break; case '-': result = leftOperand - rightOperand; break; case '*': result = leftOperand * rightOperand; break; case '/': result = leftOperand / rightOperand; break; } printf("%g %c %g = %g\n", leftOperand, operator, rightOperand, result); return EXIT_SUCCESS; }