תכנות תרגול 12 שבוע : 14.6.06. הקצאת זיכרון דינאמית הזיכרון...

28
ללללל ללללל ללללל ללללל12 12 לללל לללל: : 14.6.06 14.6.06

Post on 21-Dec-2015

229 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: תכנות תרגול 12 שבוע : 14.6.06. הקצאת זיכרון דינאמית הזיכרון המקסימאלי ששימש את התוכנית שלנו עד היום היה קבוע

1212 תכנות תרגולתכנות תרגול

::שבועשבוע

14.6.0614.6.06

Page 2: תכנות תרגול 12 שבוע : 14.6.06. הקצאת זיכרון דינאמית הזיכרון המקסימאלי ששימש את התוכנית שלנו עד היום היה קבוע

הקצאת זיכרון דינאמיתהקצאת זיכרון דינאמית

הזיכרון המקסימאלי ששימש את התוכנית שלנו עד היום היה הזיכרון המקסימאלי ששימש את התוכנית שלנו עד היום היה קבוע מראש.קבוע מראש.

לפני הרצת התוכנית, לאחר שהתוכנית עברה את שלב לפני הרצת התוכנית, לאחר שהתוכנית עברה את שלב התרגום, כל המערכים שבתוכנית גודלם נקבע ואינו ניתן התרגום, כל המערכים שבתוכנית גודלם נקבע ואינו ניתן

לשינוי לשינוי במהלך ריצת התוכנית!במהלך ריצת התוכנית!

בעיות אפשריות:בעיות אפשריות: לשמור את ציוני כל הסטודנטים לשמור את ציוני כל הסטודנטים 100100אם הגדרנו מערך בגודל אם הגדרנו מערך בגודל

וכעת מגיע סטודנט נוסף מה נעשה? וכעת מגיע סטודנט נוסף מה נעשה?

התוכנית כבר כתובה ולא ניתן לשנות את גודל המערך!התוכנית כבר כתובה ולא ניתן לשנות את גודל המערך!

Page 3: תכנות תרגול 12 שבוע : 14.6.06. הקצאת זיכרון דינאמית הזיכרון המקסימאלי ששימש את התוכנית שלנו עד היום היה קבוע

הקצאת זיכרון דינאמיתהקצאת זיכרון דינאמיתCC מאפשרת לנו להקצות זיכרון תוך כדי ריצת התוכנית וכך מאפשרת לנו להקצות זיכרון תוך כדי ריצת התוכנית וכך

להגדיר מערכים ומבנים אחרים בצורה דינאמית להגדיר מערכים ומבנים אחרים בצורה דינאמית

int main(){ int a[10]; a[6] = 7;}

10 ints

int main(){ int *a; a = (int*) malloc(sizeof(int) * 10); a[6] = 7;}

a

10 ints

6024

6024

Page 4: תכנות תרגול 12 שבוע : 14.6.06. הקצאת זיכרון דינאמית הזיכרון המקסימאלי ששימש את התוכנית שלנו עד היום היה קבוע

שחרור זיכרון שהוקצה דינאמיתשחרור זיכרון שהוקצה דינאמית

כל שטח זיכרון שהוקצה ע"י המתכנת צריך להיות כל שטח זיכרון שהוקצה ע"י המתכנת צריך להיות •משוחרר בסיום השימוש בו. לכן חייבים תמיד להחזיק משוחרר בסיום השימוש בו. לכן חייבים תמיד להחזיק

את כתובת האזור שהוקצה על מנת שנוכל לשחרר אותו את כתובת האזור שהוקצה על מנת שנוכל לשחרר אותו בסיום השימוש.בסיום השימוש.

int main(){ int *a; a = (int*) malloc(sizeof(int) * 10); a[6] = 7; free(a);}

a

6024

6024

Page 5: תכנות תרגול 12 שבוע : 14.6.06. הקצאת זיכרון דינאמית הזיכרון המקסימאלי ששימש את התוכנית שלנו עד היום היה קבוע

stdlib.hstdlib.h הפונקציות נמצאות ב- הפונקציות נמצאות ב-

• void *malloc(size_t size);void *malloc(size_t size);– Allocate size bytes. Successful call return base Allocate size bytes. Successful call return base

address; otherwise NULL is returned.address; otherwise NULL is returned.• void *calloc(size_t n,size_t size_el)void *calloc(size_t n,size_t size_el)

– Allocate an array on n elements each in size of Allocate an array on n elements each in size of size_el. Each bit is initialized to zero. Successful size_el. Each bit is initialized to zero. Successful call return base address; otherwise NULL is call return base address; otherwise NULL is returned.returned.

• void free(void *ptr)void free(void *ptr)– Deallocate the memory pointed by ptr which Deallocate the memory pointed by ptr which

must be a base address of previously allocated must be a base address of previously allocated memorymemory

• void *realloc(void *,size_t size)void *realloc(void *,size_t size)– Reallocate a memory block of size size. Reallocate a memory block of size size.

Page 6: תכנות תרגול 12 שבוע : 14.6.06. הקצאת זיכרון דינאמית הזיכרון המקסימאלי ששימש את התוכנית שלנו עד היום היה קבוע

רשימות מקושרותרשימות מקושרות

ישנו מבנה נתונים אשר מאפשרישנו מבנה נתונים אשר מאפשר•לנו לבצע את הוספת האיברים בצורהלנו לבצע את הוספת האיברים בצורה

נוחה יותר. מבנה זה נקרא רשימה מקושרת. נוחה יותר. מבנה זה נקרא רשימה מקושרת.

איבר

מידע

מצביע לאיבר

מצביע לראש

הרשימה

איבר

מידע

מצביע לאיבר

איבר

מידע

מצביע לאיבר

איבר

מידע

מצביע לאיבר

איבר

מידע

מצביע לאיבר

5 7 1 8

Page 7: תכנות תרגול 12 שבוע : 14.6.06. הקצאת זיכרון דינאמית הזיכרון המקסימאלי ששימש את התוכנית שלנו עד היום היה קבוע

struct list {struct list { int data;int data; struct list *next;struct list *next;};};

typedef strcut list typedef strcut list Item;Item;

מידע

מצביע לאיבר

:פעולות על הרשימה

יצירה והריסה של רשימה•ספירת מספר האיברים ברשימה•חיבור שתי רשימות•מחיקה/הוספה של איבר לרשימה•הדפסת רשימה•

Page 8: תכנות תרגול 12 שבוע : 14.6.06. הקצאת זיכרון דינאמית הזיכרון המקסימאלי ששימש את התוכנית שלנו עד היום היה קבוע

CCרשימות מקושרות ב-רשימות מקושרות ב-

נחזיק מצביע אשר יהיה מצביע לראש נחזיק מצביע אשר יהיה מצביע לראש ..--mainmainהרשימה וישב בהרשימה וישב ב

תהיה לנו פונקצית הוספה אשר תוסיף תהיה לנו פונקצית הוספה אשר תוסיףאיברים לרשימה בסוף הרשימה. איברים לרשימה בסוף הרשימה.

הפונקציה תדע לקבל מצביע לראש הפונקציה תדע לקבל מצביע לראשהרשימה וערך להוספה ותוסיף את האיבר הרשימה וערך להוספה ותוסיף את האיבר

בסוף הרשימה.בסוף הרשימה.

Page 9: תכנות תרגול 12 שבוע : 14.6.06. הקצאת זיכרון דינאמית הזיכרון המקסימאלי ששימש את התוכנית שלנו עד היום היה קבוע

איבר

מידע

מצביע לאיבר

3

איבר

מידע

מצביע לאיבר

7

איבר

מידע

מצביע לאיבר

5

CCרשימות מקושרות ב-רשימות מקושרות ב-int main()int main()

{{

Item *L_head = NULL;Item *L_head = NULL;

L_head = Add(L_head,5);L_head = Add(L_head,5);

L_head = Add(L_head,3);L_head = Add(L_head,3);

L_head = Add(L_head,7);L_head = Add(L_head,7);

}}מצביע לראש

הרשימה

Page 10: תכנות תרגול 12 שבוע : 14.6.06. הקצאת זיכרון דינאמית הזיכרון המקסימאלי ששימש את התוכנית שלנו עד היום היה קבוע

Item* Add(Item* L_head, int value)Item* Add(Item* L_head, int value){{ Item* L_tail = L_head;Item* L_tail = L_head; Item* I_new = malloc(sizeof (Item));Item* I_new = malloc(sizeof (Item)); I_new->value = value;I_new->value = value; I_new->next = NULL;I_new->next = NULL;

if (L_tail == NULL) if (L_tail == NULL) return I_new;return I_new;

while (L_tail->next != NULL)while (L_tail->next != NULL) L_tail=L_tail->next;L_tail=L_tail->next; L_tail->next = I_new;L_tail->next = I_new; return L_head;return L_head;} }

Page 11: תכנות תרגול 12 שבוע : 14.6.06. הקצאת זיכרון דינאמית הזיכרון המקסימאלי ששימש את התוכנית שלנו עד היום היה קבוע

איבר

מידע

מצביע לאיבר

3

איבר

מידע

מצביע לאיבר

7

איבר

מידע

מצביע לאיבר

5

CCרשימות מקושרות ב-רשימות מקושרות ב-int main()int main()

{{

Item *L_head = NULL;Item *L_head = NULL;

… …

L_head = Delete(L_head,3);L_head = Delete(L_head,3);

}}

מצביע לראש

הרשימה

Page 12: תכנות תרגול 12 שבוע : 14.6.06. הקצאת זיכרון דינאמית הזיכרון המקסימאלי ששימש את התוכנית שלנו עד היום היה קבוע

Item *Delete(Item * head,int value)Item *Delete(Item * head,int value){{

Item* curr = head;Item* curr = head;Item* prev = head;Item* prev = head;if (curr->value == value)if (curr->value == value){{

curr = curr->next;curr = curr->next;free(head);free(head);return curr;return curr;

}}

האיבר למחיקההוא הראשון

Page 13: תכנות תרגול 12 שבוע : 14.6.06. הקצאת זיכרון דינאמית הזיכרון המקסימאלי ששימש את התוכנית שלנו עד היום היה קבוע

while (curr != NULL)while (curr != NULL){{

if (curr->value == value)if (curr->value == value){{

prev->next = curr->next;prev->next = curr->next;free(curr);free(curr);return head;return head;

}}prev = curr;prev = curr;curr = curr->next;curr = curr->next;

}}return head;return head;

}}

חיפוש ומחיקתאיבר

Page 14: תכנות תרגול 12 שבוע : 14.6.06. הקצאת זיכרון דינאמית הזיכרון המקסימאלי ששימש את התוכנית שלנו עד היום היה קבוע

void PrintList(Item *head){

if (head == NULL){

printf("\n");return;

}else{

printf("%d ",head->data);PrintList(head->next);return;

}}

הדפסת רשימה

Page 15: תכנות תרגול 12 שבוע : 14.6.06. הקצאת זיכרון דינאמית הזיכרון המקסימאלי ששימש את התוכנית שלנו עד היום היה קבוע

כתוב פונקציה המקבלת מצביע לרשימה כתוב פונקציה המקבלת מצביע לרשימה •וסופרת כמה איברים יש ברשימהוסופרת כמה איברים יש ברשימה

Page 16: תכנות תרגול 12 שבוע : 14.6.06. הקצאת זיכרון דינאמית הזיכרון המקסימאלי ששימש את התוכנית שלנו עד היום היה קבוע

int Count(Item * L){

int counter=0;while (L != NULL){

counter++;L=L->next;

}return counter;

}int CountR(Item * L){

if (L == NULL)return 0;

return 1 + CountR(L->next);}

Page 17: תכנות תרגול 12 שבוע : 14.6.06. הקצאת זיכרון דינאמית הזיכרון המקסימאלי ששימש את התוכנית שלנו עד היום היה קבוע

כתוב פונקציה המקבלת מצביעים לשתי כתוב פונקציה המקבלת מצביעים לשתי •רשימות מקושרות ומחברת אותן. רשימות מקושרות ומחברת אותן.

איבר

מידע

מצביע לאיבר

3

איבר

מידע

מצביע לאיבר

7

איבר

מידע

מצביע לאיבר

5

1רשימה איבר

מידע

מצביע לאיבר

3

איבר

מידע

מצביע לאיבר

5

2רשימה

איבר

מידע

מצביע לאיבר

3

איבר

מידע

מצביע לאיבר

7

איבר

מידע

מצביע לאיבר

5

איבר

מידע

מצביע לאיבר

3

איבר

מידע

מצביע לאיבר

5

Page 18: תכנות תרגול 12 שבוע : 14.6.06. הקצאת זיכרון דינאמית הזיכרון המקסימאלי ששימש את התוכנית שלנו עד היום היה קבוע

רקורסיות רקורסיות

דני

יוסי

שמעון

אבנר

רמי

שכן יכול נתון בניין רב קומות וכל לדבר רק עם זה שמעליו

. אנחנו מבקשים וזה שמתחתיומרמי את רשימת הדיירים בבניין

דני

דני, יוסי

דני, יוסי,שמעון

דני, יוסי,שמעון,אבנר

דני, יוסי,שמעון,אבנר, רמי

רמי,תן לנו את רשימת הדיירים

של הבניין

Page 19: תכנות תרגול 12 שבוע : 14.6.06. הקצאת זיכרון דינאמית הזיכרון המקסימאלי ששימש את התוכנית שלנו עד היום היה קבוע

Item* Meld(Item* L1,Item* L2){

Item* L1_head = L1;if (L1 == NULL)

return L2;if (L2 == NULL)

return L1;while (L1->next != NULL) L1=L1->next;L1->next = L2;return L1_head;

}

Page 20: תכנות תרגול 12 שבוע : 14.6.06. הקצאת זיכרון דינאמית הזיכרון המקסימאלי ששימש את התוכנית שלנו עד היום היה קבוע

רקורסיות רקורסיות חישוב עצרתחישוב עצרת

n ! = n* (n-1) * … * 1

int factorial(int n){ if (n==1) return 1; return n*factorial(n-1);}

int factorial(int n){ int fact =1 while (n >= 1) {

fact *=n;n--;

}return fact;}

n ! = n * (n-1) !0 ! = 1

Page 21: תכנות תרגול 12 שבוע : 14.6.06. הקצאת זיכרון דינאמית הזיכרון המקסימאלי ששימש את התוכנית שלנו עד היום היה קבוע

רקורסיות רקורסיות : תרגיל

כתבו פונקציה המחשבת את הסכום

Sum(n) = sum(n-1) + nSum(1) = 1

רקורסיה

Page 22: תכנות תרגול 12 שבוע : 14.6.06. הקצאת זיכרון דינאמית הזיכרון המקסימאלי ששימש את התוכנית שלנו עד היום היה קבוע

פתרוןפתרון

int sum(int n){

if (n==1) return 1;

return n+sum(n-1);}

Page 23: תכנות תרגול 12 שבוע : 14.6.06. הקצאת זיכרון דינאמית הזיכרון המקסימאלי ששימש את התוכנית שלנו עד היום היה קבוע

רקורסיות רקורסיות חישוב חזקה ברקורסיה

double power(int x, int y){

if (y == 0)return 1;

return x * power(x, y -1);

}

Page 24: תכנות תרגול 12 שבוע : 14.6.06. הקצאת זיכרון דינאמית הזיכרון המקסימאלי ששימש את התוכנית שלנו עד היום היה קבוע

רקורסיות רקורסיות : תרגיל

א. כתבו פונקציה המחשבת את המכפלה של שני איברים באמצעות חיבור בלבד ברקורסיה

ב. לאחר מכן כתבו פונקציה המחשבת את החלוקה של שני מספרים באמצעות פעולות חיסור

בלבד ברקורסיה

Page 25: תכנות תרגול 12 שבוע : 14.6.06. הקצאת זיכרון דינאמית הזיכרון המקסימאלי ששימש את התוכנית שלנו עד היום היה קבוע

רקורסיות רקורסיות פתרון

int mul(int x,int y){

if (y==1) return x;

return x+mul(x,y-1);}

Page 26: תכנות תרגול 12 שבוע : 14.6.06. הקצאת זיכרון דינאמית הזיכרון המקסימאלי ששימש את התוכנית שלנו עד היום היה קבוע

רקורסיות רקורסיות פתרון

int div(int x,int y){

if (y>x) return 0;

return 1 + div(x-y,y);}

Page 27: תכנות תרגול 12 שבוע : 14.6.06. הקצאת זיכרון דינאמית הזיכרון המקסימאלי ששימש את התוכנית שלנו עד היום היה קבוע

void reverse_array(int *begin, int *end){

while (begin < end){

swap(begin, end);begin++;end--;

}}

reverse_array(my_arr, my_arr + SIZE -1);הפיכת מערךהפיכת מערך

begin end

3 11 35 7

Page 28: תכנות תרגול 12 שבוע : 14.6.06. הקצאת זיכרון דינאמית הזיכרון המקסימאלי ששימש את התוכנית שלנו עד היום היה קבוע

פתרון רקורסיביפתרון רקורסיבי

הפיכת מערךהפיכת מערך

void reverse_array(int array[], int size){

int i;for (i = 0; i < size/2; i++)

swap(&array[i], &array[size - 1 - i]);}