### תרגול 9

```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

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
```