Presentation is loading. Please wait.

Presentation is loading. Please wait.

מבוא למדעי המחשב מערכים.

Similar presentations


Presentation on theme: "מבוא למדעי המחשב מערכים."— Presentation transcript:

1 מבוא למדעי המחשב מערכים

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

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

4 מערכים - דוגמא #include <stdio.h> #define NUM_GRADES 5
/* This program reads NUM_GRADES grades and prints the average grade. Then, it lists the above-average grades */ #include <stdio.h> #define NUM_GRADES 5 int main() { int grades[NUM_GRADES]; int i; double average=0; for (i=0; i<NUM_GRADES; i++) scanf("%d", &(grades[i])); average = average+grades[i]; average /= NUM_GRADES; printf("The following grades are above average:\n"); if (grades[i]>average) printf("%d\n", grades[i]); return 0; } מערכים - דוגמא הגדרת מערך בשם grades המכיל NUM_GRADES תאים, כל אחד מטיפוס int.

5 מערכים - הגדרה דוגמא: הפקודה int grades[5];
תגרום להקצאה רציפה של 5 תאים מטיפוס int. למשל אםsizeof(int)=2 , אזי המערך grades יתפוס 10 בתים רצופים בזיכרון. address contents 4 3 2 1 index

6 מערכים - דוגמא #include <stdio.h> #define NUM_GRADES 5
/* This program reads NUM_GRADES grades and prints the average grade. Then, it lists the above-average grades */ #include <stdio.h> #define NUM_GRADES 5 int main() { int grades[NUM_GRADES]; int i; double average=0; for (i=0; i<NUM_GRADES; i++) scanf("%d", &(grades[i])); average = average+grades[i]; average /= NUM_GRADES; printf("The following grades are above average:\n"); if (grades[i]>average) printf("%d\n", grades[i]); return 0; } מערכים - דוגמא יש צורך להודיע לקומפיילר בדיוק מהו גודלו של המערך. גודל המערך חייב להיות קבוע. באופן כללי מערך מוגדר ע"י: type id[length]

7 מערכים – גישה לתאים דוגמא: עבור ההגדרה int grades[5]
grades[0] מתייחס לתא הראשון (למשל: grades[0]=5) grades[1] מתייחס לתא השני. למשל: if (grades[0]<51) printf(“Fail\n”); : grades[4] מתייחס לתא החמישי. שימו לב: אינדקסים של מערכים ב- C מתחילים תמיד באפס. אינדקס יכול להיות כל ביטוי שערכו מספר שלם. הצבה לתא קריאה מתא

8 מערכים - דוגמא #include <stdio.h> #define NUM_GRADES 5
/* This program reads NUM_GRADES grades and prints the average grade. Then, it lists the above-average grades */ #include <stdio.h> #define NUM_GRADES 5 int main() { int grades[NUM_GRADES]; int i; double average=0; for (i=0; i<NUM_GRADES; i++) scanf("%d", &(grades[i])); average = average+grades[i]; average /= NUM_GRADES; printf("The following grades are above average:\n"); if (grades[i]>average) printf("%d\n", grades[i]); return 0; } מערכים - דוגמא קליטת נתונים לתוך המערך. בכל איטרציה נקלט מספר אחד לתוך התא ה- i (המשתנה i משמש כמונה "הרץ" על האינדקסים של המערך). סכימת אברי מערך. הדפסת התאים הרלוונטיים מן המערך.

9 מערכים – גישה לתאים גודל מערך הינו קבוע (ידוע בזמן קומפילציה).
אינדקס של איבר במערך יכול להיות כל ביטוי שערכו מספר שלם – קבוע או משתנה או ביטוי מורכב, ואף כזה שערכו ידוע רק בזמן ריצה. האינדקסים של מערך בגודל n הם המספרים בין 0 ל- n-1. התייחסות לאיבר לא קיים במערך (איבר שהאינדקס שלו קטן מ- 0 או גדול או שווה ל- n) עשויה לגרום לטעות בזמן ריצה.

10 מערכים – אתחול int days[]={31,28,31,30,31,30,31,31,30,31,30,31}
אתחול של מערך נעשה ע"י כתיבת רשימת איבריו בתוך סוגריים מסולסלים. כאשר גודל המערך מושמט הקומפיילר יקצה מספר תאים לפי גודל סדרת המאתחלים. כאשר גודל המערך מצוין, ונתונים יותר מאתחלים מגודל המערך, תתקבל טעות בזמן קומפילציה. כאשר גודל המערך מצוין, ונתונים פחות מאתחלים מגודל המערך, יאותחלו אברי המערך הראשונים לפי הרשימה ושאר האיברים יאותחלו לאפסים.

11 פעולות על מערכים הערה חשובה:
שפת C אינה מגדירה פעולות פרימיטיביות על מערכים. השוואה, העתקה, קליטה והדפסה של איברי מערך צריכה להיעשות ע"י שימוש בלולאה, איבר אחר איבר. דוגמא: for (i=0; i<NUM_GRADES; i++) { scanf("%d", &(grades[i])); }

12 מערכים – דוגמא נוספת /* This program counts the number of digits
in its input and prints the count for each digit */ #include <stdio.h> int main () { int c, i; int ndigit[10]; for (i=0; i<10; i++) ndigit[i]=0; while ((c=getchar()) != EOF) { if (c >= '0' && c <= '9') ndigit[c-'0']++; } printf ("The digit %d occurs %d times.\n", i, ndigit[i]); return 0;

13 מערכים של תווים ← מחרוזות
מערך הוא סדרה רציפה של איברים שווי טיפוס. בפרט, הטיפוס יכול להיות תו. מחרוזות הן מקרה פרטי של מערכים: התאים הם מטיפוס char, ובסופן התו ‘\0’. השוני היחיד – ניתן לאתחל מערך של תווים גם ע"י ציון מחרוזת מפורשת. למשל: char pattern[]=“hello”; char pattern[]={‘h’,’e’,’l’,’l’,’o’,’\0’};

14 מחרוזות – דוגמא /* This program reverses a string in place */
#include <stdio.h> #define MAXLINE 100 int main () { char s[MAXLINE]; int c, i, j, length; printf("Input string:\n"); for (length=0; length<MAXLINE-1 && (c=getchar()) != EOF && c != '\n'; length++) s[length] = c; s[length] = '\0'; printf("%s\n", s); for (i=0, j=length-1; i<j; i++, j--) { c=s[i]; s[i]=s[j]; s[j]=c; } return 0;

15 העברת מערכים לפונקציות
בכותרת הפונקציה יש להצהיר על טיפוס המערך ושמו הפורמלי, ללא אורך. בסביבה הקוראת יצוין שם המערך. בתוך הפונקציה, הארגומנט הוא למעשה משתנה פנימי מאותחל. int mystrlen (char s[ ]) { int n=0; while (s[n]!=‘\0’) n++; return n; }

16 העברת מערכים לפונקציות
#include<stdio.h> #define LEN 100 int mystrlen (char s[]); int main() { char array1[LEN]="hello" , array2[LEN], array3[LEN]={'h','i'}, array4[]="hi"; array2 [0]='a'; array2[1]='b'; array2[2]='c'; array2[3]='\0'; printf("The length of the string %s is %d.\n",array1,mystrlen(array1)); printf("The length of the string %s is %d.\n",array2,mystrlen(array2)); printf("The length of the string %s is %d.\n",array3,mystrlen(array3)); printf("The length of the string %s is %d.\n",array4,mystrlen(array4)); return 0; } int mystrlen (char s[]) int n=0; while (s[n]!='\0') n++; return n;

17 העברת מערכים לפונקציות
הערה חשובה: עד כה למדנו כי בשפת C העברת פרמטרים היא by value בלבד, כלומר, הפונקציה הנקראת מקבלת העתק בלבד של המשתנים. לעומת זאת, כאשר מערך נשלח לפונקציה, הפונקציה מקבלת גישה למערך המקורי (ולא העתק של המערך!) למה? בהמשך...

18 העברת מערכים לפונקציות
int main() { int i, a[10]={1,2,3,4,5,6,7,8,9,10}; for (i=0;i<10;i++) printf("%d ",a[i]); printf("\n"); change(a); return 0; } void change (int a[]) { int i; for (i=0;i<10;i++) a[i]=i*i; return; }

19 מערכים ורקורסיות - דוגמא
תרגיל: כתבו פונקציה רקורסיבית המקבלת מחרוזת ומחזירה 1 אם המחרוזת היא פלינדרום ו- 0 אחרת. (מחרוזת היא פלינדרום אם ניתן לקרוא את אותה המחרוזת משמאל ומימין)

20 מערכים ורקורסיות - דוגמא
# include <stdio.h> # include <string.h> # define TRUE 1 #define FALSE 0 int IsPal (char str[]) { return IsPalRec (str, 0, strlen(str)) } int IsPalRec (char str[], int start, int len) if ( (len==0) || (len==1) ) return TRUE; else if (str[start]!=str[start+len-1]) return FALSE; else return IsPalRec (str, start+1, len-2);

21 רקורסיה – דוגמא (2) סידרת פיבונאצ'י: long fibonacci (int n) {
if (n == 1 || n == 2) return 1; else return (fibonacci(n-1) + fibonacci(n-2)); } החיסרון: חישובים חוזרים של תתי בעיות!

22 חישובים חוזרים של תתי בעיות - דוגמא
פונקציה לא רקורסיבית: long fib (int n) { long tmp[LEN]={1,1}, i; for (i=2; i<n; i++) tmp[i]=tmp[i-1]+tmp[i-2]; return tmp[n-1]; }

23 מערכים דו-ממדיים מערך דו-ממדי הוא למעשה מערך של מערכים.
לכן, צורת הכתיבה היא a[i][j] ולא a[i,j] . איברים נשמרים לפי שורות. לכן, מעבר על המערך כאשר האינדקס הימני משתנה מהר יותר הינו יעיל יותר. כשמעבירים מערך דו-ממדי לפונקציה יש להצהיר על גודל כל הממדים פרט לראשון. אתחול מערך דו-ממדי: int daytable[2][13] = { {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} };

24 מערכים דו-ממדיים – דוגמא (1)
נרצה לכתוב תכנית המבצעת המרה מיום בחודש ליום בשנה ולהיפך. למשל: ה- 1 במרץ הוא היום ה- 60 בשנה רגילה והיום ה- 61 בשנה מעוברת. לכן, עבור הקלט: יום 60 בשנת 2005 נקבל את הפלט: 1 במרץ עבור הקלט: יום 60 בשנת 2000 נקבל את הפלט: 29 בפברואר (*) תזכורת: שנה היא מעוברת אם היא מתחלקת ב- 4 אך לא ב- 100, או לחלופין אם היא מתחלקת ב- 400.

25 מערכים דו-ממדיים – דוגמא (1)
/* day_of_year.c -- K&R page 111 */ #include <stdio.h> int daytable[2][13] = { {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} }; /* day_of_year: set day of year from month and day */ int day_of_year (int year, int month, int day) { int i, leap; leap = (((year % 4) == 0) && ((year % 100) != 0)) || ((year % 400) == 0); for (i=1; i<month; i++) day += daytable[leap][i]; return day; }

26 מערכים דו-ממדיים – דוגמא (1)
#include <stdio.h> int daytable[2][13] = { {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} }; /* month_day: set month, day from day of year */ void month_day (int year, int yearday) { int i, leap; leap = (((year % 4) == 0) && ((year % 100) != 0)) || ((year % 400) == 0); for (i=1; yearday>daytable[leap][i]; i++) yearday -= daytable[leap][i]; return ??? }

27 מערכים דו-ממדיים – דוגמא (2)
מטריצה הינה טבלה בגודל (m שורות ו- n עמודות) חיבור מטריצות מוגדר עבור מטריצות מאותו סדר ונעשה ע"י חיבור האיברים במקומות המתאימים. לדוגמא: נרצה לכתוב תכנית המבצעת חיבור מטריצות לא מוגדר

28 מערכים דו-ממדיים – חיבור מטריצות
#include <stdio.h> #include <stdlib.h> #define SIZE 10 #define FALSE 0 #define TRUE 1 void ReadMatrix (int a[SIZE][SIZE], int row, int col); void CheckSize (int size); int add (int a[SIZE][SIZE], int row1, int col1, int b[SIZE][SIZE], int row2, int col2, int c[SIZE][SIZE]); void PrintMatrix (int a[SIZE][SIZE], int row, int col);

29 מערכים דו-ממדיים – חיבור מטריצות
int main() { int a[SIZE][SIZE], b[SIZE][SIZE], c[SIZE][SIZE]; int row1, row2, col1, col2; printf("Enter the number of rows and columns of the first matrix and the second matrix\n"); if (scanf("%d%d%d%d",&row1, &col1, &row2, &col2)!=4){ printf("Input error\n"); return 1; } CheckSize(row1); CheckSize(col1); CheckSize(row2); CheckSize(col2); ReadMatrix(a,row1,col1); ReadMatrix(b,row2,col2); if (add(a,row1,col1,b,row2,col2,c)==FALSE) { printf("Matrices cannot be added\n"); return 0; else{ printf("The result matrix:\n"); PrintMatrix(c,row1,col1);

30 מערכים דו-ממדיים – חיבור מטריצות
/* Check a matrix dimension*/ void CheckSize (int size) { if (size<0){ printf(“Matrix dimensions should be positive\n"); exit (1); } return;

31 מערכים דו-ממדיים – חיבור מטריצות
/* read a matrix*/ void ReadMatrix (int a[SIZE][SIZE], int row, int col) { int i,j; printf("Please enter matrix [%d][%d]\n",row,col); for (i=0; i < row; i++) { for (j=0; j < col; j++) { if(scanf("%d", &(a[i][j]))!=1){ printf("Input error"); exit (1); } PrintMatrix(a, row, col); return;

32 מערכים דו-ממדיים – חיבור מטריצות
/* print a matrix */ void PrintMatrix (int a[SIZE][SIZE], int row, int col) { int i,j; printf("Printing matrix [%d][%d]\n", row, col); for (i=0; i < row; i++) { for (j=0; j < col; j++) { printf("%6d", a[i][j]); } printf("\n");

33 מערכים דו-ממדיים – חיבור מטריצות
/* add two matrices */ int add (int a[SIZE][SIZE], int row1, int col1, int b[SIZE][SIZE], int row2, int col2, int c[SIZE][SIZE]) { int i,j; if ( (col1!=col2) || (row1!=row2) ) return FALSE; for (i=0; i < row1; i++) for (j=0; j < col2; j++) c[i][j]=a[i][j]+b[i][j]; return TRUE; }


Download ppt "מבוא למדעי המחשב מערכים."

Similar presentations


Ads by Google