Computer Programming Summer 2017 תרגול 5
מערכים חד-מימדיים )תזכורת( לדוגמא: מערך בשם Arr בגודל 8 שאיבריו מטיפוס int 3 7 5 6 8 1 23 16 0 1 2 3 4 5 6 7 ב - arr[0] ב יושב ערך שהוא המספר השלם 3 arr[1] - יושב ערך שהוא המספר השלם 7 ב arr[7] - יושב ערך שהוא המספר השלם 16
הגדרה ואתחול מבנה הפקודה: ;]>מספר איברים<[ >שם המערך< >טיפוס< int ids[7]; char name[12]; דוגמאות להגדרת מערך: דוגמאות להגדרת מערך עם אתחול: int arr[10] = { 1, 4, 6, 7, 8, 0, 5, 5, 1, 2 }; int arr[10] = { 1, 4 }; int arr[10] = {0}; אם נשמיט את גודל המערך, הוא יקבע לפי גודל האתחול: int arr[ ] = {1, 4, 7}; /* Array of 3 ints */
מערכים רב-מימדיים מערך דו מימדי הוא מערך של מערכים, כלומר מטריצה. int mat[n][m]; הגדרתו תתבצע כך: כאשר N הוא מספר השורות ו- M הוא מספר העמודות. ניתן לאתחל מערך דו-מימדי עם הגדרתו בדרכים הבאות: הצבת הנתונים לפי שורות )בכל שורה 3 עמודות, כלומר 3 נתונים(: int mat[4][3]={{1,2,3},{4,5,6},{7,8,9},{10,11,12}}; ואיפוס שאר התאים שבשורה: int table[4][3] = {{1,2},{4,5},{7,8},{10,11}}; הצבת שני נתונים בכל שורה, הצבת הנתונים במערך אחד אחרי השני נוספים(: )לפי סדר השורות( ואיפוס השאר )אם ישנם תאים int mat[4][3]={1,2,3,,12}; ניתן לא להגדיר את מספר השורות, אך חובה להגדיר את מספר העמודות )כלומר גודל כל שורה(: int mat[][3]={{1,2,3},{4,5,6},{7,8,9},{10,11,12}}; int mat[][]={{1,2,3},{4,5,6},{7,8,9},{10,11,12}};
סריקה של מערכים סריקה של מערכים מתבצעת בעזרת לולאות מקוננות, כאשר כלל האצבע הוא שכל מימד של המערך דורש לולאה אחת. דוגמא: כתוב תכנית, אשר עבור כל המספרים מ- 0 ועד 10, שומרת לתוך מערך את 10 החזקות הראשונות של כל מספר )מ- 0 ועד 9(. לאחר מכן, התכנית תקלוט שני מספרים x ו- y )שניהם בין 0 ל- 9 (, ותדפיס את x בחזקת y.
סריקה של מערכים סריקה של מערכים מתבצעת בעזרת לולאות מקוננות, כאשר כלל האצבע הוא שכל מימד של המערך דורש לולאה אחת. דוגמא: כתוב תכנית, אשר עבור כל המספרים מ- 0 ועד 10, שומרת לתוך #include <stdio.h> מערך את 10 החזקות הראשונות של כל מספר )מ- 0 ועד 9(. #define NUMS 11 לאחר מכן, התכנית תקלוט שני מספרים x ו- y )שניהם בין 0 ל- 9 (, #define NPOWERS 10 ותדפיס את x בחזקת y. void main() { int powers[nums][npowers],i,j,k,res,x,y; for (i=0;i<nums;i++){ powers[i][0]=1; for (j=1;j<npowers;j++) { powers[i][j]= powers[i][j-1] * i; } } scanf("%d%d",&x,&y); printf("%d",powers[x][y]); }
שאלה יש לממש את התוכנית הבאה: קלט: מערך דו-ממדי המכיל תווים,)chars( מתווים ואורכה קצר משני ממדי המערך. הקלט נתון,(Hardcoded) אין צורך לקלוט אותו ממשתמש. ומילה המורכבת פלט: הדפסת כל המופעים של המילה במערך הדו-ממדי, כאשר המילה יכולה להופיע בשורה (horizontally) או בעמודה (vertically)
#include <stdio.h> #define ROW 5 #define COL 5 #define WORDSIZE 3 void main(){ int i, j, k, l; char matr[row][col] = { { 'r', 'v', 'o', 'q', 'w' }, { 'a', 'h', 's', 'x', 'l' }, { 'n', 'k', 's', 'd', 'm' }, { 'r', 'a', ' n', 'j', 'r' }, { 'd', 'k', 'u', 'c', 'a' } }; char word[wordsize] = { 'r', 'a', 'n' };
// Search for horizontal words (along the rows): for (i = 0; i < ROW; i++) //Scan the rows. for (j = 0; j <= COL - WORDSIZE; j++) { //Scan the columns. //Scan the word if it is there. for (k = j, l = 0; l < WORDSIZE && matr[i][k] == word[l]; k++, l++); if (l == WORDSIZE) //Check if the whole word was encountered. printf("found horizontally in Row %d, Column [%d, %d]\n", i, k - WORDSIZE, k - 1); }
//Search for vertical words (along the columns): for (i = 0; i <= ROW - WORDSIZE; i++) //Scan the rows: for (j = 0; j < COL; j++){ //Scan the columns: //Scan the word if it is there. for (k = i, l = 0; l < WORDSIZE && matr[k][j] == word[l]; k++, l++); if (l == WORDSIZE) //Check if the whole word was encountered. printf("found vertically in Row [%d, %d], Column %d\n", k - WORDSIZE, k - 1, j); } }
טבלת - ascii
מחרוזות מחרוזת היא מערך של תווים,)chars( שבסופם התו 0\ )התו בעל ערך ה-.)0 ascii מחרוזת קבועה, היא אוסף של תווים בין מרכאות כפולות. דוגמא: המחרוזת hello היא מערך של 6 תווים, שנראים בזיכרון כך: h e l l o \0 a \0 יש הבדל בין a לבין a : a הוא תו יחיד )המייצג את הערך 97(, ו- a היא מחרוזת המורכבת משני תווים: אל התווים השונים במחרוזת ניגש כפי שניגשים לאברי מערך. אם נרצה להדפיס מחרוזת בשלמותה )עד ה 0\ (, או לקלוט מחרוזת שלמה נשתמש בסימן s%.
ההגדרה בדומה למערך: אתחול: הגדרה ואתחול char name[10]; char name[]="sapir"; char name[]={'s','a','p','i','r','\0'}; בשני המקרים ששת תווי המחרוזת נמצאים בזיכרון באופן רציף, ו- name הוא שם המחרוזת )המערך(. ניתן גם לאתחל את המחרוזת עם גודל מוכרז. במקרה זה ערך שאר התוים יהיה '0\': char name[10]="sapir";
תרגיל 1 כתוב תכנית הקולטת מהמשתמש את השם שלו, ומדפיסה אותו למסך עם אות ראשונה גדולה,(uppercase) ושאר האותיות קטנות.(lowercase)
#include <stdio.h> void main() { char name[10]; int I; תרגיל 1 כתוב תכנית הקולטת מהמשתמש את השם שלו, ומדפיסה אותו למסך עם אות ראשונה גדולה,(uppercase) ושאר האותיות קטנות.(lowercase) scanf("%s",name); if (name[0]>='a' && name[0]<='z') name[0]=name[0]-('a'-'a'); } for (i=1;name[i]!='\0';i++) if (name[i]>='a' && name[i]<='z') name[i]=name[i]+('a'-'a'); printf("%s",name);
gets & puts לפקודה scanf עם s% יש מגבלה היא מפסיקה את קליטת המחרוזת כשמוקלד רווח או,TAB ולכן לא יכולה לקלוט יותר ממילה אחת. הפקודה gets מתגברת על כך - קולטת עד שמוקלד.enter הפקודה puts מדפיסה את המחרוזת כמו,printf ולאחר מכן מדפיסה ירידת שורה. char str[50]; gets(str); puts(str);
תרגיל 2 כתוב תכנית הקולטת משפט שהמילים בו מכילות אותיות קטנות בלבד. התכנית לספור כמה פעמים מופיעה כל אות, ולהדפיס זאת. מגבלה: אסור להשתמש בלולאות מקוננות. על
תרגיל 2 כתוב תכנית הקולטת משפט שהמילים בו מכילות אותיות קטנות בלבד. התכנית לספור כמה פעמים מופיעה כל אות, ולהדפיס זאת. מגבלה: אסור להשתמש בלולאות מקוננות. על #include <stdio.h> void main() { char words[100]; int i, counters[26]={0}; gets(words); for (i=0; words[i]!='\0'; i++) if (words[i]!=' ') counters[words[i]-'a']++; } for (i=0;i<26;i++) if (counters[i]>0) printf("%c appeared %d times\n",'a'+i, counters[i]);
פקודות לעבודה עם מחרוזות מהספריה <string.h> strcmp: int strcmp(const char s1[], const char s2[]); The function compares successive elements from two strings, s1 and s2, until it finds elements that are not equal. If all elements are equal, the function returns zero. If the differing element from s1 is greater than the element from s2 (both taken as unsigned char), the function returns a positive number. Otherwise, the function returns a negative number. strlen: unsigned int strlen(const char s[]); The function returns the number of characters in the string s, not including its terminating null character. e.g. char example = { a, b, c, \0 }; strlen(example); // = 3
פקודות לעבודה עם מחרוזות מהספריה <stdio.h> ו- <string.h> strcpy: void strcpy(char s1[], const char s2[]); The function copies the string s2, including its terminating null character, to successive elements of the array of char whose first element has the address s1. It returns s1. strcat: void strcat(char s1[], const char s2[]); The function works like strcpy(), only that it copies the string s2 to the END of the string s1, meaning that the functions ADDS s2 to the end of s1. The function finds the end of s1 according to the character \0. gets: (in <stdio.h>) void gets(char s1[]); The function works like scanf( %s,...), only that it terminates the input via the key ENTER only. Unlike scanf, it can read the characters SPACE & TAB from the user and insert them to the char array s1.
דוגמא #include <stdio.h> #include <string.h> כיצד משתנות המחרוזות בקוד הבא? void main() { char str1[10]; char str2[]="abcdefg"; int result; unsigned int i; } strcpy(str1, str2); result=strcmp(str1, str2); result=strlen(str2); str2[4]='\0'; result=strlen(str2); strcat(str2,"cba"); result=strcmp(str1, str2);
דוגמא #include <stdio.h> #include <string.h> void main() { char str1[10]; char str2[]="abcdefg"; int result; unsigned int i; } strcpy(str1, str2); result=strcmp(str1, str2); result=strlen(str2); str2[4]='\0'; result=strlen(str2); strcat(str2,"cba"); result=strcmp(str1, str2); כיצד משתנות המחרוזות בקוד הבא? Str1 str2 result length value length value 10 [?,?,?,?,?,?,?,?,?,?] 8 [a,b,c,d,e,f,g,\0]? 10 [a,b,c,d,e,f,g,\0,?,?] 8 [a,b,c,d,e,f,g,\0]? 10 [a,b,c,d,e,f,g,\0,?,?] 8 [a,b,c,d,e,f,g,\0] 0 10 [a,b,c,d,e,f,g,\0,?,?] 8 [a,b,c,d,e,f,g,\0] 7 10 [a,b,c,d,e,f,g,\0,?,?] 8 [a,b,c,d,\0,f,g,\0] 7 10 [a,b,c,d,e,f,g,\0,?,?] 8 [a,b,c,d,\0,f,g,\0] 4 10 [a,b,c,d,e,f,g,\0,?,?] 8 [a,b,c,d,c,b,a,\0] 4 10 [a,b,c,d,e,f,g,\0,?,?] 8 [a,b,c,d,c,b,a,\0] > 0 (1)? Stands for unknown/uninitialized memory
תרגיל 3 כתוב תכנית אשר קולטת מילים )אחת אחרי השנייה( מהמשתמש עד אשר מוקלדת המילה,EXIT ולאחר מכן מדפיסה למסך את המילה הארוכה ביותר שהוקלדה )לא כולל.)EXIT אם ישנן כמה מילים באותו האורך, על התוכנית להדפיס רק את המילה שמופיעה ראשונה לפי סדר אלפא-ביתי. לדוגמא עבור הקלט: this is a test תודפס המילה: test
תרגיל 3 #include <stdio.h> #include <string.h> #define MAXLEN 1000 void main() { char word[maxlen]; char longest[maxlen]=""; כתוב תכנית אשר קולטת מילים )אחת אחרי השנייה( מהמשתמש עד אשר מוקלדת המילה,EXIT ולאחר מכן מדפיסה למסך את המילה הארוכה ביותר שהוקלדה )לא כולל.)EXIT אם ישנן כמה מילים באותו האורך, על התוכנית להדפיס רק את המילה שמופיעה ראשונה לפי סדר אלפא-ביתי. לדוגמא עבור הקלט: this is a test תודפס המילה: test scanf("%s",word); while (strcmp(word,"exit")!=0) { if (strlen(word)>strlen(longest) (strlen(word)==strlen(longest) && strcmp(word,longest)<0)) strcpy(longest, word); scanf("%s",word); } } printf("%s\n", longest);