Presentation is loading. Please wait.

Presentation is loading. Please wait.

הקצאות דינאמיות קרן כליף.

Similar presentations


Presentation on theme: "הקצאות דינאמיות קרן כליף."— Presentation transcript:

1 הקצאות דינאמיות קרן כליף

2 ביחידה זו נלמד: מוטיבציה להקצאות דינאמיות מהי הקצאה דינאמית
יצירת מערך בגודל שאינו ידוע מראש החזרת מערך מפונקציה הקצאת מערך של מערכים הגדלת מערך הפונקציה strdup 2 © Keren Kalif

3 מוטיבציה להקצאה דינאמית
בעזרת הקצאה דינאמית נוכל: להקצות מערך בזמן ריצה, בלי לדעת את גודלו בזמן קומפילציה נוכל להחזיר מערך מפונקציה 3 © Keren Kalif

4 מהי הקצאה דינאמית? הקצאה דינאמית היא הקצאת שטח זיכרון בגודל מבוקש בזמן ריצת התוכנית בניגוד להקצאה סטטית שמוקצית בתחילת התוכנית וגודלה ידוע כבר בזמן קומפילציה הקצאה דינאמית מוקצית על שטח הזיכרון heap בניגוד להקצאה סטטית שמוקצית על ה- stack של הפונקציה ה- heap הוא שטח זיכרון המשותף לכל הפונקציות, בניגוד ל- stack בהקצאת זיכרון דינאמית המתכנת מבקש ממערכת ההפעלה זיכרון בגודל מסוים המוגדר בבתים ומקבל את כתובת הבית הראשון בקטע הזיכרון שקיבל 4 © Keren Kalif

5 הגדרה נוספת ל- <type>*
אנו יודעים שמשתנה מטיפוס *<type>מכיל כתובת של משתנה מטיפוס <type> כלשהו כתובת התחלה של מערך מטיפוס <type>היא גם כתובתו של האיבר הראשון במערך, שהוא משתנה מטיפוס <type> לכן משתנה מטיפוס <type>* יכול להכיל גם כתובת התחלה של מערך לכן נאמר ש- <type>* הוא פוטנציאל למערך כלומר, יכול להכיל כתובת התחלה של מערך (ולא רק כתובת של משתנה יחיד מטיפוס <type>) 5 © Keren Kalif

6 הפקודה new נשתמש בה כאשר נרצה להקצות מערך בגודל שאינו ידוע בזמן קומפילציה int size; cin >> size; int* arr = new int[size]; כדי להקצות מערך נשתמש ב- [] ובתוכם גודל המערך המבוקש הפקודה מחזירה את כתובת ההתחלה של המערך שהוקצה ובהמשך נשתמש עם כתובת זו 6 © Keren Kalif

7 new – הקצאת מערך בגודל שאינו ידוע מראש
7 © Keren Kalif new – הקצאת מערך בגודל שאינו ידוע מראש void main() { int size, *arr; cout << "Please enter the size of the array: "; cin >> size; arr = new int[size]; if (!arr) // (arr == NULL) --> allocaton didn't succeed cout << "ERROR! Out of memory!\n"; return; } cout << "Values in the array: "; for (int i=0 ; i < size ; i++) cout << *(arr+i) << “ “; //*(arr+i) == arr[i] cout << "\nPlease enter “ << size << “ numbers: “; cin >> arr[i]; cout << arr[i] << “ “; cout << endl; נשים לב שלמשתנה על ה- heap אין שם, אלא רק יש אליו הצבעה מאחת הפונקציות! int ??? 3000 3004 3008 int 1 3000 5 3004 8 3008 זיכרון ה- heap int:size 3 1000 int*: arr ??? 1004 int: i 1008 int:size 3 1000 int*: arr 3000 1004 int: i ??? 1008 int:size ??? 1000 int*: arr 1004 int: i 1008 הזיכרון של ה- main

8 שחרור הזיכרון שהוקצה אחריות המתכנת לשחרר את כל זיכרון שהוקצה דינאמית
במילים אחרות, המתכנת אחראי להחזיר למערכת ההפעלה כל שטח זיכרון שביקש ממנה בזמן ריצה הסיבה: שטח ה- heap עליו מוקצות ההקצאות הדינאמיות מוגבל בשטחו ומשותף לכל התוכניות, ואז התוכנית הבאה שתבקש זיכרון עלולה לקבל NULL כי אנחנו לא החזרנו את הזיכרון שביקשנו בסיום העבודה... צריך לזכור: כאשר יש סביבת עבודה משותפת, צריך להתחשב גם באחרים (וזה שיעור חשוב בכלל לחיים ;-)) הקומפיילר לא מתריע על אי-שחרור הזיכרון ואין שום אינדיקציה לדעת זאת, לכן חייבים לשים לב!! 8 © Keren Kalif

9 פונקציה לשחרור הקצאות דינאמיות
הפונקציה delete משחררת הקצאה דינאמית כאשר ההקצאה היא למערך צריך לזכור לשים [] לפני שם המערך delete [] arr 9 © Keren Kalif

10 delete – שחרור זיכרון ??? 1 5 8 זיכרון ה- heap 3 3000 ??? 3 ??? ???
void main() { int size, *arr; cout << "Please enter the size of the array: "; cin >> size; arr = new int[size]; if (!arr) // (arr == NULL) --> allocaton didn't succeed cout << "ERROR! Out of memory!\n"; return; } cout << "Values in the array: "; for (int i=0 ; i < size ; i++) cout << *(arr+i) << “ “; //*(arr+i) == arr[i] cout << "\nPlease enter “ << size << “ numbers: “; cin >> arr[i]; cout << "Values in the array: “; cout << arr[i] << “ “; cout << endl; delete []arr; int ??? 3000 3004 3008 int 1 3000 5 3004 8 3008 זיכרון ה- heap int:size 3 1000 int*: arr 3000 1004 int: i ??? 1008 int:size 3 1000 int*: arr ??? 1004 int: i 1008 int:size ??? 1000 int*: arr 1004 int: i 1008 הזיכרון של ה- main 10 © Keren Kalif

11 תזכורת: החזרת מערך מפונקציה
ראינו כי כאשר מעבירים מערך לפונקציה, מעבירים רק את כתובת ההתחלה שלו, ולא עותק של כל המערך ובאופן דומה, כאשר מחזירים מערך שהוגדר בפונקציה, חוזרת כתובת ההתחלה שלו, ולא עותק של כל המערך הבעייתיות: כאשר יוצאים מהפונקציה שטח הזיכרון שלה משתחרר ויש לנו מצביע לזיכרון שנמחק... הפתרון: הקצאה דינאמית

12 תזכורת: הבעייתיות בהחזרת מערך מפונקציה - דוגמא
const int SIZE = 3; int* readArray() { int arr[SIZE]; cout << "Please enter “ << SIZE << “ numbers: “; for (int i=0 ; i < SIZE ; i++) cin >> arr[i]; return arr; } void main() int* arr; arr = cout << "The array is: \n"; cout << arr[i] << “ “; cout << endl; int[]: arr 3 2000 5 2004 6 2008 int: i 2012 int[]: arr ??? 2000 2004 2008 int: i 2012 הזיכרון של readArray הקומפיילר נותן warning: returning address of local variable or temporary שפירושה שאנחנו מחזירים כתובת למשתנה בזיכרון שישתחרר לעולם לא נחזיר מפונקציה כתובת של משתנה שהוגדר בה מקומית! readArray(); int*: arr ??? 1000 int: i 1004 int*: arr 2000 1000 int: i ??? 1004 הזיכרון של ה- main

13 הפתרון: הקצאת המערך דינאמית
const int SIZE = 3; int* buildArray() { int* arr = new int[SIZE]; if (!arr) cout << "ERROR! Not enough memory!\n"; return; } for (int i=0 ; i < SIZE; i++) cin >> arr[i]; return arr; void main() int *arr, i; arr = cout << "Values in the array: "; for (i=0 ; i < SIZE ; i++) cout << arr[i] << “ “; cout << endl; delete []arr; הפתרון: הקצאת המערך דינאמית אם אנחנו יוצאים מפונקציה שהקצתה דינאמית ולא שחררה, חובה להחזיר את כתובת ההתחלה של ההקצאה, כדי שנוכל לשחרר אותה בהמשך! אחרת כאשר נצא מהפונקציה כבר לא יהיה משתנה שיכיל את מיקום ההקצאה! int:i ??? 2000 int*: arr 3000 2004 int:i ??? 2000 int*: arr 2004 הזיכרון של buildArray buildArray(); int ??? 3000 3004 3008 int 1 3000 2 3004 3 3008 int*: arr ??? 1000 int: i 1004 int*: arr 3000 1000 int: i ??? 1004 הזיכרון של ה- main זיכרון ה- heap 13 © Keren Kalif

14 הקצאה בתוך פונקציה אחריות שלנו כמתכנתים לשחרר את כל הזיכרון שהקצינו
יש לשים לב בייחוד במקרים בהם ההקצאה מתבצעת בפונקציה אחת, והשחרור צריך להיות בפונקציה אחרת! 14 © Keren Kalif

15 החזרת מערך מפונקציה by pointer
למדנו שפונקציה יכולה להחזיר ערכים ע"י קבלת כתובת לעדכון התשובה למשל: int getSum(int arr[], int size); לעומת: void getSum(int arr[], int size, int* sum); באותו אופן ניתן גם להחזיר מערך שייוצר בתוך הפונקציה לא לשכוח להעביר את המערך כ- ** 15 © Keren Kalif

16 החזרת מערך מפונקציה by pointer - דוגמא
void buildArray(int* arr, int size) { arr = new int[size]; if (!arr) } cout << "ERROR! Not enough memory!\n”; return; for (int i=0 ; i < size ; i++) arr[i] = i+1; void main() int size, *arr=NULL; cout << "Please enter the size of the array: “; cin >> size; buildArray(arr, size); cout << "Values in the array: “; cout << arr[i] << “ “; cout << endl; delete []arr; החזרת מערך מפונקציה by pointer - דוגמא int 1 3000 2 3004 3 3008 int ??? 3000 3004 3008 זיכרון ה- heap int:size 3 2000 int: i ??? 2004 int*: arr 3000 2008 int:size 3 2000 int: i ??? 2004 int*: arr NULL 2008 הזיכרון של buildArray int:size 3 1000 int*: arr NULL 1004 int: i ??? 1008 int:size ??? 1000 int*: arr 1004 int: i 1008 int:size ??? 1000 int*: arr NULL 1004 int: i 1008 פה התוכנית תעוף... הזיכרון של ה- main 16 © Keren Kalif

17 החזרת מערך מפונקציה by pointer - התיקון
void buildArray(int** arr, int size) } *arr = new int[size]; if (!*arr) cout << "ERROR! Not enough memory!\n”; return; { for (int i=0 ; i < size ; i++) (*arr)[i] = i+1; void main() int size, *arr=NULL; cout << "Please enter the size of the array: “; cin >> size; buildArray(&arr, size); cout << "Values in the array: “; cout << arr[i] << “ “; cout << endl; delete []arr; int 1 3000 2 3004 3 3008 int ??? 3000 3004 3008 זיכרון ה- heap int:size 3 2000 int: i ??? 2004 int**: arr 1004 2008 הזיכרון של buildArray int:size 3 1000 int*: arr NULL 1004 int: i ??? 1008 int:size ??? 1000 int*: arr NULL 1004 int: i 1008 int:size ??? 1000 int*: arr 1004 int: i 1008 int:size 3 1000 int*: arr 3000 1004 int: i ??? 1008 הזיכרון של ה- main 17 © Keren Kalif

18 החזרת מערך מפונקציה by ref
למשל: int getSum(int arr[], int size); לעומת: void getSum(int arr[], int size, int& sum); באותו אופן ניתן גם להחזיר מערך שייוצר בתוך הפונקציה לא לשכוח להעביר את המערך כ- &* 18 © Keren Kalif

19 החזרת מערך מפונקציה by ref- התיקון
void buildArray(int*& arr, int size) } arr = new int[size]; if (!arr) cout << "ERROR! Not enough memory!\n”; return; { for (int i=0 ; i < size ; i++) arr[i] = i+1; void main() int size, *arr=NULL; cout << "Please enter the size of the array: "; cin >> size; buildArray(arr, size); cout << "Values in the array: “; cout << arr[i] << “ “; cout << endl; delete []arr; int 1 3000 2 3004 3 3008 int ??? 3000 3004 3008 זיכרון ה- heap int:size 3 2000 int: i ??? 2004 int*: arr הזיכרון של buildArray int:size 3 1000 int*: arr NULL 1004 int: i ??? 1008 int:size ??? 1000 int*: arr NULL 1004 int: i 1008 int:size ??? 1000 int*: arr 1004 int: i 1008 int:size 3 1000 int*: arr 3000 1004 int: i ??? 1008 הזיכרון של ה- main 19 © Keren Kalif

20 הקצאת מערך של מערכים (1) כעת אנחנו יכולים לייצר מטריצה שבכל שורה יש מספר שונה של איברים int rows=3 int* sizes 2 2 3 4 2 3 int** matrix 20 © Keren Kalif

21 void main() { int rows, **matrix, *sizes; cout << "Enter number of rows in the matrix: "; cin >> rows; sizes = new int[rows]; matrix = new int*[rows]; for ( ; ; ) cout << "Enter size of row #“ << i+1 << “: ”; cin >> sizes[i]; matrix[i] = new int[sizes[i]]; for (int j=0 ; j < sizes[i] ; j++) cin >> matrix[i][j]; } cout << "The matrix is:\n”; for (int i=0 ; i < rows ; i++) cout << matrix[i][j] << “ “; cout << endl; delete []sizes; for ( ; ; ) delete []matrix[i]; delete []matrix; 21 © Keren Kalif הקצאת מערך של מערכים (2) int:rows 3 1000 int**: matrix 3000 1004 int: i 1008 int: j ??? 1012 int*: sizes 4000 1016 int:rows 3 1000 int**: matrix 3000 1004 int: i 1008 int: j ??? 1012 int*: sizes 4000 1016 int:rows 3 1000 int**: matrix 3000 1004 int: i 1008 int: j ??? 1012 int*: sizes 4000 1016 int:rows 3 1000 int**: matrix 3000 1004 int: i 2 1008 int: j ??? 1012 int*: sizes 4000 1016 int:rows 3 1000 int**: matrix 3000 1004 int: i 1 1008 int: j ??? 1012 int*: sizes 4000 1016 int:rows 3 1000 int**: matrix 3000 1004 int: i 2 1008 int: j ??? 1012 int*: sizes 4000 1016 int:rows 3 1000 int**: matrix 3000 1004 int: i 1008 int: j ??? 1012 int*: sizes 4000 1016 int:rows 3 1000 int**: matrix 3000 1004 int: i 1 1008 int: j ??? 1012 int*: sizes 4000 1016 int:rows ??? 1000 int**: matrix 1004 int: i 1008 int: j 1012 int*: sizes 1016 int:rows 3 1000 int**: matrix ??? 1004 int: i 1008 int: j 1012 int*: sizes 4000 1016 int:rows 3 1000 int**: matrix ??? 1004 int: i 1008 int: j 1012 int*: sizes 1016 int:rows 3 1000 int**: matrix 3000 1004 int: i ??? 1008 int: j 1012 int*: sizes 4000 1016 int i=0 i < rows i++ הזיכרון של ה- main int ??? 4050 4054 int 11 4050 12 4054 int* 4050 3000 ??? 3004 3008 int* 4050 3000 5000 3004 2200 3008 int* ??? 3000 3004 3008 int* 4050 3000 5000 3004 ??? 3008 int 21 5000 22 5004 23 5008 int ??? 5000 5004 5008 int 31 2200 32 2224 33 2228 34 2232 int ??? 2200 2224 2228 2232 int ??? 4000 4004 4008 int 2 4000 3 4004 ??? 4008 int 2 4000 3 4004 4 4008 int 2 4000 ??? 4004 4008 int i=0 i < rows i++ זיכרון ה- heap

22 הגדלת מערך בדוגמא הבאה אנו קולטים מהמשתמש מספרים לתוך מערך, לא ידוע כמה איברים המשתמש יכניס כל פעם כאשר כבר אין מקום במערך צריך להגדיל אותו פי 2 האלגוריתם: קרא את האיבר החדש, אם 1- צא אם אין מקום במערך, הקצה מערך גדול פי 2 העתק למערך החדש את האיברים מהמערך הישן שחרר את המערך המקורי שנה את מצביע המערך להצביע למערך החדש 22 © Keren Kalif

23 הגדלת מערך - הפלט 23 © Keren Kalif

24 הגדלת מערך – הקוד זיכרון ה- heap -1 ??? 4 3 4300 5 ??? 4 3 4300 5 ???
void main() { int num, physSize = 2, logicSize = 0, *arr, *tmp; arr = new int[physSize]; cout << "Please enter numbers, -1 to stop:\n”; while (1) cin >> num; if (num == -1) break; if (physSize == logicSize) physSize *= 2; tmp = new int[physSize]; for (int i=0 ; i < logicSize ; i++) tmp[i] = arr[i]; delete []arr; arr = tmp; cout << "Doubled the array size to “ << physSize << endl; } cout << "Read number is “ << num << endl; arr[logicSize] = num; logicSize++; cout << "The array has “ << logicSize << “ elements (physSize=“ << physSize << “):\n”; cout << arr[i] << “ “; cout << endl; הגדלת מערך – הקוד int 7 2200 4 2204 int 7 2200 ??? 2204 int ??? 2200 2204 int 7 4300 4 4304 ??? 4308 4312 int ??? 4300 4304 4308 4312 int 7 4300 4 4304 5 4308 ??? 4312 זיכרון ה- heap int: num -1 1000 int: i ??? 1004 int: physSize 4 1008 int: logicSize 3 1012 int*: arr 4300 1016 int*: tmp 1020 int: num 5 1000 int: i ??? 1004 int: physSize 4 1008 int: logicSize 3 1012 int*: arr 4300 1016 int*: tmp 1020 int: num 5 1000 int: i ??? 1004 int: physSize 4 1008 int: logicSize 2 1012 int*: arr 2200 1016 int*: tmp 4300 1020 int: num ??? 1000 int: i 1004 int: physSize 2 1008 int: logicSize 1012 int*: arr 2200 1016 int*: tmp 1020 int: num 5 1000 int: i ??? 1004 int: physSize 4 1008 int: logicSize 2 1012 int*: arr 2200 1016 int*: tmp 1020 int: num 5 1000 int: i ??? 1004 int: physSize 4 1008 int: logicSize 2 1012 int*: arr 4300 1016 int*: tmp 1020 int: num 4 1000 int: i ??? 1004 int: physSize 2 1008 int: logicSize 1 1012 int*: arr 2200 1016 int*: tmp 1020 int: num ??? 1000 int: i 1004 int: physSize 1008 int: logicSize 1012 int*: arr 1016 int*: tmp 1020 int: num 7 1000 int: i ??? 1004 int: physSize 2 1008 int: logicSize 1012 int*: arr 2200 1016 int*: tmp 1020 int: num 4 1000 int: i ??? 1004 int: physSize 2 1008 int: logicSize 1012 int*: arr 2200 1016 int*: tmp 1020 int: num 7 1000 int: i ??? 1004 int: physSize 2 1008 int: logicSize 1 1012 int*: arr 2200 1016 int*: tmp 1020 int: num ??? 1000 int: i 1004 int: physSize 2 1008 int: logicSize 1012 int*: arr 1016 int*: tmp 1020 int: num 5 1000 int: i ??? 1004 int: physSize 2 1008 int: logicSize 1012 int*: arr 2200 1016 int*: tmp 1020 הזיכרון של ה- main 24 © Keren Kalif

25 מה יהיה פלט התוכנית הבאה?
void main() { char* c = new char[5]; char** s = new char*[3]; int i; for( ; ; ) cout << "enter word : “; cin.getline(c, 5); s[i] = c; for(i=0; i<3; i++) cout << "strings : “ << s[i] << endl; delete []c; delete []s; } char ??? 4300 4301 4302 4303 4304 char ‘h’ 4300 ‘i’ 4301 4302 ??? 4303 4304 char ‘b’ 4300 ‘y’ 4301 ‘e’ 4302 4303 ??? 4304 char ‘g’ 4300 ‘o’ 4301 4302 ‘d’ 4303 4304 i=0 i < 3 i ++ char* ??? 5300 5304 5308 char* 4300 5300 5304 5308 char* 4300 5300 5304 ??? 5308 char* 4300 5300 ??? 5304 5308 זיכרון ה- heap char*: c 4300 1000 char**: s 5300 1004 int: i 2 1008 char*: c 4300 1000 char**: s 5300 1004 int: i ??? 1008 char*: c 4300 1000 char**: s 5300 1004 int: i 3 1008 char*: c ??? 1000 char**: s 1004 int: i 1008 char*: c 4300 1000 char**: s ??? 1004 int: i 1008 char*: c 4300 1000 char**: s 5300 1004 int: i 1008 char*: c 4300 1000 char**: s 5300 1004 int: i 1 1008 הזיכרון של ה- main 25 © Keren Kalif

26 התיקון לתוכנית הקודמת זיכרון ה- heap 4300 5300 1 6300 5300 1 6300 5300
void main() { char* c; char** s = new char*[2]; int i; for( ; ; ) c = new char[5]; cout << "enter word : "; cin.getline(c, 5); s[i] = c; for(i=0; i<2; i++) cout << "strings : “ << s[i] << endl; for (i=0 ; i < 2 ; i++) delete []s[i]; delete []s; } char ??? 4300 4301 4302 4303 4304 char ‘h’ 4300 ‘i’ 4301 4302 ??? 4303 4304 char ??? 6300 6301 6302 6303 6304 char ‘b’ 6300 ‘y’ 6301 ‘e’ 6302 6303 ??? 6304 i=0 i < 2 i ++ char* ??? 5300 5304 char* 4300 5300 ??? 5304 char* 4300 5300 6300 5304 זיכרון ה- heap char*: c 4300 1000 char**: s 5300 1004 int: i 1 1008 char*: c 6300 1000 char**: s 5300 1004 int: i 1 1008 char*: c 6300 1000 char**: s 5300 1004 int: i 2 1008 char*: c 4300 1000 char**: s 5300 1004 int: i 1008 char*: c ??? 1000 char**: s 5300 1004 int: i 1008 char*: c ??? 1000 char**: s 5300 1004 int: i 1008 char*: c ??? 1000 char**: s 1004 int: i 1008 הזיכרון של ה- main 26 © Keren Kalif

27 char* strdup(const char *str)
מקבלת מחרוזת ומחזירה העתק שלה: מקצה דינאמית על ה- heap מערך של תווים בגודל המחרוזת המקורית, מעתיקה אליו את התוכן ומחזירה את כתובת ההתחלה שלו תחזיר NULL במידה וההקצאה נכשלה אחריות המתכנת לשחרר את המחרוזת שחזרה!! 27 © Keren Kalif

28 זיכרון ה- static storage
28 © Keren Kalif strdup – דוגמא void main() } char str1[] = "hi"; char* str2 = "bye"; char* newStr1 = strdup(str1); char* newStr2 = strdup(str2); cout << "The first duplicated string: |” << newStr1 << “|\n”; cout << "The second duplicated string: |” << newStr2 << “|\n”; delete []newStr1; delete []newStr2; { char ‘b’ 5300 ‘y’ 5301 ‘e’ 5302 ‘\0’ 5303 זיכרון ה- static storage char: str1[] ‘h’ 1000 ‘i’ 1001 ‘\0’ 1002 char*: str2 5300 1003 char*: newStr1 4300 1007 char*: newStr2 ??? 1011 char: str1[] ‘h’ 1000 ‘i’ 1001 ‘\0’ 1002 char*: str2 5300 1003 char*: newStr1 4300 1007 char*: newStr2 6300 1011 char: str1[] ‘h’ 1000 ‘i’ 1001 ‘\0’ 1002 char*: str2 5300 1003 char*: newStr1 ??? 1007 char*: newStr2 1011 char: str1[] ‘h’ 1000 ‘i’ 1001 ‘\0’ 1002 char*: str2 ??? 1003 char*: newStr1 1007 char*: newStr2 1011 char: str1[] ??? 1000 1001 1002 char*: str2 1003 char*: newStr1 1007 char*: newStr2 1011 char ‘b’ 6300 ‘y’ 6301 ‘e’ 6302 ‘\0’ 6303 char ‘h’ 4300 ‘i’ 4301 ‘\0’ 4302 זיכרון ה- heap הזיכרון של ה- main

29 ביחידה זו למדנו: מוטיבציה להקצאות דינאמיות מהי הקצאה דינאמית
יצירת מערך בגודל שאינו ידוע מראש החזרת מערך מפונקציה הקצאת מערך של מערכים הגדלת מערך הפונקציה strdup 29 © Keren Kalif

30 תרגיל 1 כתוב תוכנית המבקשת מהמשתמש להכניס את כמות המספרים שהוא רוצה שיהיו במערך, והקצה מערך בהתאם הגרל ערכים למערך והגרל מספר נוסף (בטווח 0-9) ייצר מערך חדש המכיל את האינדקסים במערך המקורי שערך האיבר שבתוכם שווה למספר הנוסף שהתקבל הצג את המערך שחדש שייצרת דוגמא: עבור המערך 1,2,5,2,2,9 גודלו 6 והמספר 2, יוחזר מערך בגודל 3 שערכיו 1,3,4 30 © Keren Kalif

31 תרגיל 2 כתוב פונקציה המקבלת מחרוזת ותו. הפונקציה תייצר ותחזיר מחרוזת חדשה שאורכה ככמות הפעמים שהתו מופיעה במחרוזת המקורית והיא תכיל תו זה כמספר פעמים זה דוגמאות: עבור המחרוזת “hello” והתו ‘l’ תוחזר המחרוזת “ll” עבור המחרוזת “keren” והתו ‘e’ תוחזר המחרוזת “ee” 31 © Keren Kalif

32 תרגיל 3 כתוב פונקציה המקבלת 2 מערכים וגודלם. הפונקציה תחזיר מערך חדש המכיל את הערכים שבשני המערכים הפוקנציה גם תחזיר את גודל המערך המוחזר דוגמא: עבור המערך 1,8,2 וגודלו 3 והמערך 9,2,6,7 וגודלו 4 יוחזר המערך החדש 1,8,2,9,2,6,7 וגודלו 7 32 © Keren Kalif


Download ppt "הקצאות דינאמיות קרן כליף."

Similar presentations


Ads by Google