Programming Rehearse: 2D arrays Rehearse: Pointers & Structures Intro to Dynamic memory allocation Example 1 – Multiplication table Write a program that computes the Multiplication table. 1 2 3 … 10 2 4 6 … 20 3 6 9 … 30 … 10 100 2 Solution 1 – Multiplication table #define SIZE 10 void init_table(int table[SIZE][SIZE]) } int i, j; for (i = 0; i < SIZE; i++) for (j = 0; j < SIZE; j++) table[i][j] = (i + 1) * (j + 1); } void print_table(int table[SIZE][SIZE]) } int i, j; for (i = 0; i < SIZE; i++) { for (j = 0; j < SIZE; j++) printf("%4d", table[i][j]); printf("\n"); } } int main() } int table[SIZE][SIZE]; init_table(table); print_table(table); return 0; { 3 Example 2 – Matrix multiplication נכתוב תכנית שמחשבת כפל של 2מטריצות a,b בגודל .3x3 את התוצאה נשמור במטריצה .c נוסחא לכפל מטריצות: SIZE 1 ] a[i][k ] b[k ][ j k 0 4 c[i][ j ] Solution 2 – Matrix multiplication #define MATRIX_SIZE 3 c[i][ j ] SIZE 1 a[i][k ] b[k ][ j] k 0 int main(void) { int a[][MATRIX_SIZE] = { {1,2,3}, {4,5,6}, {7,8,9}}; int b[][MATRIX_SIZE] = { {1,0,0}, {0,2,0}, {0,0,3}}; int c[MATRIX_SIZE][MATRIX_SIZE]; int i = 0, j = 0, k = 0; /* Compute the product c = a * b */ for (i = 0; i < MATRIX_SIZE; ++i) for (j = 0; j < MATRIX_SIZE; ++j) { c[i][j] = 0; for (k = 0; k < MATRIX_SIZE; ++k) c[i][j] += a[i][k] * b[k][j]; } /* Print c */ ... return 0; } 5 Example 3 – print a polynom Each element in the polynom is called monom typedef struct monom{ double coefficient; int degree; {Monom; 3x 6 x 5 4 2 6 Example 3 – print a polynom Write a function that gets a valid polynom (pointer to array of Monoms) and the size of the polynom (number of monoms) and prints the polynom in the format : 3x^ 4 6 x^ 2 5 7 void printPolynom(Monom * polynom, int size){ int i; for (i=0; i<size; i++){ if(polynom[i].coefficient != 0){ if(i>0) printf(" + "); if(polynom[i].coefficient != 1 || polynom[i].degree == 0) printf("%g", polynom[i].coefficient); if(polynom[i].degree != 0) printf("x"); if(polynom[i].degree > 1) printf("^%d", polynom[i].degree); {} printf("\n");{ 8 Example 4 - char appearances typedef struct appear{ char ch; int n_appearances; } appear_t; 9 Write a function that gets a string and updates the output array appear (each cell will contain a different char and its number of appearances). The function will return the number of different chars. Assume that appear is big enough. int appearances(char* str, appear_t appear[]) 10 Solution 4 - char appearances int appearances (char* str, appear_t appear[]){ int i, found, n=0; for(; *str != '\0‘; str++) { found = FALSE; for (i=0; i<n; i++){ if(appear[i].ch == *str){ appear[i].n_appearances++; found = TRUE; { { if(!found){ appear[n].ch = *str; appear[n++].n_appearances = 1; { { return n; { 11 Malloc void* malloc(unsigned int nBytes); Used to dynamically allocate nBytes in memory Returns a pointer to the allocated area on success, NULL on failure Always check whether memory was successfully allocated 12 The free Function void free(void *ptr); free(p) deallocates memory pointed by p. Freeing a non-allocated area is an error. No partial deallocation. Always free allocated memory. 13 Warming Up int main() { int i=0, n=0, *p=NULL; printf("How many numbers will you enter?\n"); scanf("%d", &n); casting /* Allocate an int array of the proper size */ p = (int*)malloc(n * sizeof(int)); if (p == NULL) { printf("Memory allocation failed!\n"); return 1; } ... /* Free the allocated space */ free(p); return 0; } 14 Returning Allocated Memory Example: duplicate a string to a new location (with dynamic allocation), return the new string: // strdup - duplicate a string char* strdup(const char* str) { char* dup = (char*)malloc((strlen(str)+1) * sizeof(char)); if (dup != NULL) { strcpy(dup, str); } return dup; } 15 Exercise @ Class Implement the function char* my_strcat(const char *s1, const char *s2); Output: a pointer to a dynamically allocated concatenation of s1 and s2. Example: my_strcat(“hello_”, “world!”); Output: “hello_world!” You can use the functions in string.h Test your function 16 What’s Wrong Here? char* my_strcat(const char *s1, const char *s2) { char result[500]; /* assume this is enough */ strcpy(result, s1); strcpy(result + strlen(s1), s2); return result; } 17 Pitfalls Accessing un-initialized pointer int* p; *p = 3; Using de-allocated memory int* p = (int*)malloc(SIZE * sizeof(int)); ... /* do something with p*/ free(p); *p = 0; 18 שאלה ממבחן -תש"ע ,סמסטר א',שאלה 2 בשאלה זו תתבקשו לכתוב פונקציות ותוכנת מחשב לניהול משחק הלוטו. סעיף א': "מערך משורשר" -מערך המכיל ערכים של מספר תתי מערכים באותו אורך באופן רציף בזה אחר זה .לדוגמא" ,מערך משורשר" המכיל 3תתי מערכים ,כל אחד בגודל :6 19 שאלה ממבחן -תש"ע ,סמסטר א',שאלה 2 כתבו פונקציה המקבלת: מערך של מספרים שלמים שהוא "מערך משורשר" גודל כל תת -מערך .n 2מספרים שלמים i ,ו.j-הפונקציה תחזיר את ].arr[i][j )int getVal(int arr[], int n, int i, int j { ;]return arr[i * n + j } 20 שאלה ממבחן -תש"ע ,סמסטר א',שאלה 2 סעיף ב: מגרילים 6מספרים בין 1ל .49-טופס מנצח מכיל את כל 6המספרים. ממשו פונקציה הבודקת מי הם הזוכים ,המקבלת: - winNumsמערך בגודל 6המכיל את המספרים הזוכים. -Ticketsמערך משורשר עם תתי מערכים באורך 6ובהם טפסים של משתתפים. -numTicketsמספר הטפסים במערך. - resמערך בגודל מספר המשתתפים. בסיום הריצה ,התא ה i-ב res-יכיל 1אם הטופס ה i-זכה בפרס ו 0-אחרת. ערך מוחזר :מספר הטפסים הזוכים. 21 שאלה ממבחן -תש"ע ,סמסטר א',שאלה 2 כדי לקבל את מלוא הנקודות בסעיף זה יש לעבור רק פעם אחת על המערך winNumsורק פעם אחת על המערך .tickets ניצור מערך עזר בגודל 49 שיבדוק אם מספר הוא מספר זוכה באמצעות פעולת השוואה אחת בלבד! 22 2 שאלה,' סמסטר א, תש"ע- שאלה ממבחן #define TICKET_SIZE 6 #define NUM_RANGE 49 int checkWin(int winNums[], int tickets[], int numTickets, int res[]) { int i, j, val, numWinners = 0; char numbers[NUM_RANGE]={0}; Auxiliary array // init auxiliary array for (i = 0; i < TICKET_SIZE; i++) numbers[winNums[i]] = 1; 23 2 שאלה,' סמסטר א, תש"ע- שאלה ממבחן // go over all tickets for (i = 0; i < numTickets; i++) { res[i] = 1; // go over 6 numbers in a ticket for (j = 0; j < TICKET_SIZE; j++) { val = getVal(tickets, TICKET_SIZE, i, j); if (numbers[val] == 0) { // found a non-winning number – ticket lost res[i] = 0; break; } { // if we are here – all 6 numbers won numWinners += res[i]; } return numWinners; } 24 שאלה ממבחן -תש"ע ,סמסטר א',שאלה 2 סעיף ג' ( 15נקודות) : הפרס הראשון בלוטו הוא 10,000,000ש"ח. אם כמה משתתפים זכו הם יתחלקו בפרס באופן שווה )ייתכן שאין זוכה(. כתבו תוכנית הקולטת מהמשתמש את הנתונים הבאים לפי הסדר המתואר: .1ששת המספרים הזוכים .2מספר המשתתפים .3טפסי הניחוש בזה אחר זה פלט התוכנית הוא טבלה שבכל שורה בה מופיע מספר סידורי של משתתף וסכום הזכייה שלו. 25 2 שאלה,' סמסטר א, תש"ע- שאלה ממבחן int main() { int i, numParticipants, numWinners = 0; int winningNumbers[TICKET_SIZE]; int *tickets, *winners; double jackpot = 10000000; printf("Enter winning numbers: "); for (i = 0; i < TICKET_SIZE; i++) scanf("%d", &winningNumbers[i]); printf("Enter number of participants: "); scanf("%d", &numParticipants); // dynamic allocation tickets = (int*) malloc(numParticipants *TICKET_SIZE * sizeof(int)); winners = (int*) malloc(numParticipants *sizeof(int)); 26 2 שאלה,' סמסטר א, תש"ע- שאלה ממבחן if (tickets == NULL || winners == NULL) { printf("Unable to allocate memory!"); return 1; } printf("Enter lottery tickets: "); … numWinners = checkWin(winningNumbers, tickets,numParticipants, winners); ... // free allocated memory free(tickets); free(winners); return 0; { 27 Solution to Class exercise char* my_strcat(const char *s1, const char *s2) { int len; char *result = NULL; len = strlen(s1) + strlen(s2) + 1; result = (char*)malloc(len * sizeof(char)); if (result == NULL) { printf(“Memory allocation failed!\n"); return NULL; } strcpy(result, s1); strcat(result, s2); return result; } 28