Presentation is loading. Please wait.

Presentation is loading. Please wait.

קורס תכנות – סימסטר ב ' תשס " ח שיעור שישי: מערכים www.cs.tau.ac.il/courses/cs4math/09b 9012345678 0987654321.

Similar presentations


Presentation on theme: "קורס תכנות – סימסטר ב ' תשס " ח שיעור שישי: מערכים www.cs.tau.ac.il/courses/cs4math/09b 9012345678 0987654321."— Presentation transcript:

1 קורס תכנות – סימסטר ב ' תשס " ח שיעור שישי: מערכים www.cs.tau.ac.il/courses/cs4math/09b 9012345678 0987654321

2 שאלה רוצים לקלוט 30 מספרים שלמים, ולאחר מכן להדפיס אותם בסדר הפוך מהסדר שקלטנו אותם (כלומר מהסוף להתחלה). כיצד נוכל לעשות זאת? רוצים לקלוט 30 מספרים שלמים, ולאחר מכן להדפיס אותם בסדר הפוך מהסדר שקלטנו אותם (כלומר מהסוף להתחלה). כיצד נוכל לעשות זאת? לדוגמא, אם היה מדובר על קלט של 3 מספרים: לדוגמא, אם היה מדובר על קלט של 3 מספרים: 200 200 100 100 70 70 הפלט היה צריך להיות: הפלט היה צריך להיות: 70 70 100 100 200 200

3 פתרון אפשרי נשתמש ב-30 משתנים, משתנה לכל ערך מהקלט: a1,…,a30. נשתמש ב-30 משתנים, משתנה לכל ערך מהקלט: a1,…,a30. נקלוט את כל אחד מ-30 המספרים לתוך משתנה (הראשון ל- a1, השני ל- a2, וכן הלאה) נקלוט את כל אחד מ-30 המספרים לתוך משתנה (הראשון ל- a1, השני ל- a2, וכן הלאה) נדפיס את ערכי שלושים המשתנים בסדר הפוך מסדר הקלט: קודם a30, אחר-כך a29, וכך הלאה עד a1. נדפיס את ערכי שלושים המשתנים בסדר הפוך מסדר הקלט: קודם a30, אחר-כך a29, וכך הלאה עד a1. אז בתוכנית יהיו 30 משתנים, 30 פקודות קלט, 30 פקודות הדפסה,... זו תהיה תוכנית מאוד מסורבלת (ומה נעשה אם יהיו 1000 מספרים?)

4 מה היינו רוצים יש פה הרבה פעולות זהות על משתנים מאותו סוג – היינו רוצים לכתוב אותן פעם אחת בלבד: יש פה הרבה פעולות זהות על משתנים מאותו סוג – היינו רוצים לכתוב אותן פעם אחת בלבד: להגדיר בבת-אחת 30 משתנים מאותו סוג עבור הקלט. להגדיר בבת-אחת 30 משתנים מאותו סוג עבור הקלט. לכתוב פעם אחת את פקודת הקלט, ושהמחשב יבצע אותה 30 פעם, כל פעם למשתנה המתאים. לכתוב פעם אחת את פקודת הקלט, ושהמחשב יבצע אותה 30 פעם, כל פעם למשתנה המתאים. לכתוב פעם אחת את הדפסת הפלט, ושזה יבוצע עבור כל אחד מהמשתנים בסדר המתאים. לכתוב פעם אחת את הדפסת הפלט, ושזה יבוצע עבור כל אחד מהמשתנים בסדר המתאים.

5 הפתרון: מערך שפת C מאפשרת להגדיר בבת-אחת אוסף של משתנים מאותו סוג, ולגשת לכל אחד מהם בעזרת אינדקס (מספר סידורי). אוסף כזה נקרא "מערך". שפת C מאפשרת להגדיר בבת-אחת אוסף של משתנים מאותו סוג, ולגשת לכל אחד מהם בעזרת אינדקס (מספר סידורי). אוסף כזה נקרא "מערך". זה מאפשר לעשות לולאה על המספר הסידורי של המשתנה, ולבצע אותו דבר על כל אחד מהמשתנים ("התאים") במערך. זה מאפשר לעשות לולאה על המספר הסידורי של המשתנה, ולבצע אותו דבר על כל אחד מהמשתנים ("התאים") במערך. A[0]A[29] 9599........

6 איך ניראה הפיתרון #include<stdio.h> int main() { int i, input[30]; int i, input[30]; printf(“Enter the 30 integers:\n”); printf(“Enter the 30 integers:\n”); for (i=0; i<=29; i++) for (i=0; i<=29; i++) scanf(“%d”, &input[i]); scanf(“%d”, &input[i]); for (i=29; i>=0; i--) for (i=29; i>=0; i--) printf(“%d”, input[i]); printf(“%d”, input[i]); } קלט לתאי המערך, מתא 0 עד תא 29 הדפסה בסדר הפוך, מתא 29 עד תא 0 התוכנית קולטת 30 מספרים ומדפיסה אותם בסדר הפוך מגדירים מערך של 30 משתנים מסוג int עוברים בלולאה על המשתנים האלה

7 נושאי השיעור היום מה זה מערך ולמה הוא משמש מה זה מערך ולמה הוא משמש הגדרה ואיתחול הגדרה ואיתחול גישה לתאים גישה לתאים

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

9 מערכים – משמעות והגדרה כאמור, מערך הוא אוסף של משתנים מאותו טיפוס (הטיפוס יכול להיות int, char, float, double או כל טיפוס אחר שנכיר). כאמור, מערך הוא אוסף של משתנים מאותו טיפוס (הטיפוס יכול להיות int, char, float, double או כל טיפוס אחר שנכיר). בהגדרת המערך רושמים את טיפוס המשתנים ואת מספרם. בהגדרת המערך רושמים את טיפוס המשתנים ואת מספרם. למשל כך נגדיר מערך של 100 משתנים מטיפוס double: למשל כך נגדיר מערך של 100 משתנים מטיפוס double: double prices[100]; הגדרת מערך מקצה רצף של מקומות בזיכרון שיכילו את ערכי תאי (משתני) המערך. למשל:הגדרת מערך מקצה רצף של מקומות בזיכרון שיכילו את ערכי תאי (משתני) המערך. למשל: A[0]A[9] 5 9........

10 הכנסת ערך לתא במערך לכל אחד מהתאים במערך יש מספר סידורי (אינדקס), החל מ-0. לכל אחד מהתאים במערך יש מספר סידורי (אינדקס), החל מ-0. ההתייחסות אל כל תא היא על-ידי שם המערך והמספר הסידורי של התא, בתוך סוגריים מרובעים. ההתייחסות אל כל תא היא על-ידי שם המערך והמספר הסידורי של התא, בתוך סוגריים מרובעים. לדוגמא, נגדיר מערך של 10 משתנים מסוג int, ונשים 51 בתא הראשון ו-45 בתא העשירי: לדוגמא, נגדיר מערך של 10 משתנים מסוג int, ונשים 51 בתא הראשון ו-45 בתא העשירי: int A[10]; int A[10]; A[0]=51; A[0]=51; A[9]=45; A[9]=45; A[0]A[9] 4551........

11 קריאת ערך מתא במערך כמו שאפשר לשים ערך בתא מסויים, אפשר גם לקבל את הערך שנמצא בתא מסויים. למשל: כמו שאפשר לשים ערך בתא מסויים, אפשר גם לקבל את הערך שנמצא בתא מסויים. למשל: printf(“%d”, A[0]); i=A[5]; נשים לב: כדי להתייחס לתא במערך צריך תמיד לציין את המספר הסידורי שלו בתוך סוגריים מרובעים. נשים לב: כדי להתייחס לתא במערך צריך תמיד לציין את המספר הסידורי שלו בתוך סוגריים מרובעים. שם המערך ללא סוגריים מרובעים מתייחס לכתובת ההתחלה של המערך בזיכרון, ולא לתא במערך. שם המערך ללא סוגריים מרובעים מתייחס לכתובת ההתחלה של המערך בזיכרון, ולא לתא במערך.

12 הדוגמא שראינו #include<stdio.h> int main() { int i, input[30]; int i, input[30]; printf(“Enter the 30 integers:\n”); printf(“Enter the 30 integers:\n”); for (i=0; i<=29; i++) for (i=0; i<=29; i++) scanf(“%d”, &input[i]); scanf(“%d”, &input[i]); for (i=29; i>=0; i--) for (i=29; i>=0; i--) printf(“%d”, input[i]); printf(“%d”, input[i]); } קלט לתאי המערך, מתא 0 עד תא 29 הדפסה בסדר הפוך, מתא 29 עד תא 0 התוכנית קולטת 30 מספרים ומדפיסה אותם בסדר הפוך מגדירים מערך של 30 משתנים מסוג int עוברים בלולאה על המשתנים האלה

13 איתחול מערכים בשורת ההגדרה כמו טיפוסי משתנים אחרים, ניתן לאתחל מערך כשמגדירים אותו. זה נעשה באופן הבא: כמו טיפוסי משתנים אחרים, ניתן לאתחל מערך כשמגדירים אותו. זה נעשה באופן הבא: int A[5]={7,43,15,17,235}; int A[5]={7,43,15,17,235}; ערכי האיתחול נכנסים לתאי-המערך לפי הסדר (משמאל לימין). ערכי האיתחול נכנסים לתאי-המערך לפי הסדר (משמאל לימין). אם ניתן ערכים רק לחלק מהתאים, שאר התאים יאותחלו עם הערך 0. אם ניתן ערכים רק לחלק מהתאים, שאר התאים יאותחלו עם הערך 0. int A[5]={9,42}; אז אפשר למשל לאתחל מערך באפסים על-ידי int A[5]={0}; אז אפשר למשל לאתחל מערך באפסים על-ידי int A[5]={0}; אם לא נציין את מספר תאי המערך, הוא יהיה כמספר ערכי האיתחול (בדוגמא הבאה יהיו לו 6 תאים): אם לא נציין את מספר תאי המערך, הוא יהיה כמספר ערכי האיתחול (בדוגמא הבאה יהיו לו 6 תאים): int A[]={16,2,19,256,5,1432}; int A[]={16,2,19,256,5,1432}; לא ניתן להכניס ערכים למערך באופן הזה אחרי ההגדרה שלו. לא ניתן להכניס ערכים למערך באופן הזה אחרי ההגדרה שלו.

14 אין גישה לכל המערך בבת-אחת אחרי הגדרת המערך אפשר רק להתייחס לכל אחד מהתאים שלו בנפרד. אחרי הגדרת המערך אפשר רק להתייחס לכל אחד מהתאים שלו בנפרד. אי-אפשר לשים ערכים בתאי המערך בבת-אחת: אי-אפשר לשים ערכים בתאי המערך בבת-אחת: למשל אי-אפשר לאפס בבת-אחת את כל התאים, וצריך לעשות זאת ע"י לולאה: למשל אי-אפשר לאפס בבת-אחת את כל התאים, וצריך לעשות זאת ע"י לולאה: for(i=0; i<10; i++) A=0 for(i=0; i<10; i++) A=0 A[i]=0; A[i]=0; אי-אפשר להעתיק מערך למערך אחר ע"י פעולת = גם זה דורש לולאה: אי-אפשר להעתיק מערך למערך אחר ע"י פעולת = גם זה דורש לולאה: for(i=0; i<10; i++) A=B for(i=0; i<10; i++) A=B A[i]=B[i]; A[i]=B[i]; כך גם לגבי פעולות השוואה, הדפסה, קלט, וכו' (דרושה לולאה). כך גם לגבי פעולות השוואה, הדפסה, קלט, וכו' (דרושה לולאה).

15 חריגה מגבולות המערך אם נכתוב לתא במערך מעבר לגודל שהוגדר, בסבירות גבוהה יפגעו נתונים של תוכנות אחרות, והתוכנית "תעוף". אם נכתוב לתא במערך מעבר לגודל שהוגדר, בסבירות גבוהה יפגעו נתונים של תוכנות אחרות, והתוכנית "תעוף". למשל: למשל: int a[10]; a[10]=1; a[-1]=5;

16 נקודה תשומת-לב בהגדרת מערך הגודל שלו חייב להיות מספר קבוע, ולא יכול להיות ערך של משתנה. בהגדרת מערך הגודל שלו חייב להיות מספר קבוע, ולא יכול להיות ערך של משתנה. למשל: למשל: int a[10]; int my_size=10; ולא: int a[my_size]; גודל מערך יכול להיות קבוע שמוגדר ב- #define (כי זה מספר שכתוב בתוכנית ולא יכול להשתנות במהלך הריצה). גודל מערך יכול להיות קבוע שמוגדר ב- #define (כי זה מספר שכתוב בתוכנית ולא יכול להשתנות במהלך הריצה). #define SIZE 10 #define SIZE 10 int a[SIZE];

17 מערכים - דוגמא נוספת #include<stdio.h> int main() { int i, num, digits[10]={0}; int i, num, digits[10]={0}; printf(“Enter a positive integer:\n”); printf(“Enter a positive integer:\n”); scanf(“%d”, &num); scanf(“%d”, &num); while (num!=0) while (num!=0) { digits[num%10]++; digits[num%10]++; num=num/10; num=num/10; } } for (i=0; i<10; i++) for (i=0; i<10; i++) printf(“Digit %d appeared %d times\n”, i, digits[i]); printf(“Digit %d appeared %d times\n”, i, digits[i]); } התוכנית הזו קולטת מספר שלם חיובי ומדפיסה כמה פעמים הופיעה בו כל סיפרה מדפיסים כמה פעמים כל ספרה הופיעה כל תאי המערך מאותחלים לאפס (מניחים כאן שהקלט תקין) מגדילים ב-1 את התא שמתאים לספרת האחדות של המספר, ומחלקים אותו ב-10 לולאה שנמשכת כל עוד המספר לא מתאפס i במערך יכיל את מספר ההופעות של הספרה i תא 0000000000 נניח לדוגמא 557 112 5550

18 נקודה לתשומת-לב: מערך קבוע כמו כל משתנה, אפשר להגדיר מערך כקבוע (const). כמו כל משתנה, אפשר להגדיר מערך כקבוע (const). const int M[12]={31,28,31,30,31,30,31,31,30,31,30,31}; ערכי המערך הוגדרו כקבועים, ולכן לא ניתן להעביר אותו

19 מערכים רב-מימדיים לפעמים נירצה לייצג מטריצות, או מערכים ממימדים גבוהים יותר. לפעמים נירצה לייצג מטריצות, או מערכים ממימדים גבוהים יותר. נוכל להגדיר מערכים כאלה למשל על-ידי: נוכל להגדיר מערכים כאלה למשל על-ידי: int a[10][100]; המשמעות היא שהגדרנו 10 מערכים בגודל 100 של מספרים שלמים. המשמעות היא שהגדרנו 10 מערכים בגודל 100 של מספרים שלמים. ואז נוכל לגשת לכל תא ע"י שני אינדקסים, למשל: ואז נוכל לגשת לכל תא ע"י שני אינדקסים, למשל:a[5][8]=4;

20 מערכים רב-מימדיים - איתחול ניתן לתת ערכים התחלתיים גם כשמגדירים מערך רב-מימדי. ניתן לתת ערכים התחלתיים גם כשמגדירים מערך רב-מימדי. מתייחסים אליו כאל מערך של מערכים חד-מימדיים, ומעבירים ערכי איתחול לכל אחד מהם. למשל: מתייחסים אליו כאל מערך של מערכים חד-מימדיים, ומעבירים ערכי איתחול לכל אחד מהם. למשל: int my_matrix[3][2]={ {1,0}, {0,1}, {1,1} }; int my_matrix[3][2]={ {1,0}, {0,1}, {1,1} }; איתחול נפוץ יותר הוא בעזרת לולאות מקוננות (אם יש הרבה תאים לא נירצה לכתוב את ערכי כולם). איתחול נפוץ יותר הוא בעזרת לולאות מקוננות (אם יש הרבה תאים לא נירצה לכתוב את ערכי כולם).

21 דוגמא: איפוס מערך דו-מימדי בגודל 100100x int main() { int a[100][100] int a[100][100] int i,j; int i,j; for(i=0; i<100; i++) for(i=0; i<100; i++) for(j=0; j<100; j++) for(j=0; j<100; j++) a[ i ][ j ] = 0; a[ i ][ j ] = 0; return 0; } אין צורך לרשום את המימד הראשון בסוגריים המרובעים (כמו במערכים רגילים), אבל חייבים לרשום גודל בסוגריים השניים.

22 דוגמא: מה עושה התוכנית הבאה? #include<stdio.h> int main() { int i,j, a[11][11]; int i,j, a[11][11]; for(i=1; i<=10; i++) for(i=1; i<=10; i++) for(j=1; j<=10; j++) for(j=1; j<=10; j++) a[ i ][ j ] = i*j; a[ i ][ j ] = i*j; for(i=1; i<=10; i++) for(i=1; i<=10; i++) { for(j=1; j<=10; j++) for(j=1; j<=10; j++) printf(“% 4 d”, a[ i ][ j ] ); printf(“% 4 d”, a[ i ][ j ] ); printf(“\n”); printf(“\n”); }} מדפיסה את לוח הכפל כך יוקצו 4 תווים להדפסת כל מספר (ואם יש פחות ספרות יהיו משמאל רווחים) יודפס: 1 2 3 4 5 6 7 8 9 10 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30.


Download ppt "קורס תכנות – סימסטר ב ' תשס " ח שיעור שישי: מערכים www.cs.tau.ac.il/courses/cs4math/09b 9012345678 0987654321."

Similar presentations


Ads by Google