## 2.11. Exercises

### Exercises for 2.3: Pointers and Functions

1. Consider the following program:

``````#include <stdio.h>

int arg_modifier(int x, int *y);

int main() {
int val1, val2, ret;

printf("Enter a value: ");
scanf("%d", &val1);
printf("Enter another value: ");
scanf("%d", &val2);

// pass val1 by value and val2 by pointer:
printf("before call: val1 = %d val2 = %d\n", val1, val2);
ret = arg_modifier(val1, &val2);
printf("after call:  val1 = %d val2 = %d ret = %d\n", val1, val2, ret);

/*
* uncomment to test passing val2 by value and val1 by pointer
*/
//printf("before 2nd call: val1 = %d val2 = %d\n", val1, val2);
//ret = arg_modifier(val2, &val1);
//printf("after 2nd call: val1 = %d val2 = %d\n", val1, val2);

return 0;
}

/*
* This function illustrates C-style pass by pointer semantics, the
* argument pointed to by the second parameter, y, will be modified
* after the call, the value of the first argument, x, will not.
*/
int arg_modifier(int x, int *y) {

printf("  in arg_modifier:      x = %d *y = %d\n", x, *y);

/* the location y points to gets (value of what y points to + x) */
*y = *y + x;

x = x + 5;

printf("  leaving arg_modifier: x = %d *y = %d\n", x, *y);

return x;
}``````

Here’s the output from an example run:

```Enter a value: 100
Enter another value: 200
before call: val1 = 100 val2 = 200
in arg_modifier:      x = 100 *y = 200
leaving arg_modifier: x = 105 *y = 300
after call:  val1 = 100 val2 = 300 ret = 105```

Copy this program (ex_passbypointer.c), compile and run it a few times to understand its behavior and the semantics of pass-by-pointer. You can uncomment the second call in main that passes the local variables in different order as arguments to the function.

Then draw the stack for a call to the `arg_modifier` function, entering the values 5 and 2. Draw the stack at the point in the execution right before the return from the `arg_modifier` function, and consider the following questions:

1. Where are variables val1 and val2 located on the stack?

2. Where are the parameter values located?

3. What value does each parameter get?

4. How does the value of the parameter affect the value of each argument after the call?

1. Implement a C program with a `swap` function that swaps the values stored in its two arguments. Make some calls to it in main to test it out.

#### Solutions Figure 1. Stack diagram just before returning from arg_modifier when given 5 and 2 as user input.

Figure 1 shows a snapshot of the stack before `arg_modifier` returns. Parameter `y` receives the value of the address of `val2` (`y` points to `val2`). By dereferencing `y`, it accesses the value stored in `val2` — the statement `*y = *y + x;` changes the value pointed to by `y` from 2 to 7.

1. val1 and val2 are located in main’s stack frame

2. in arg_modifier’s stack frame

3. y gets the value of the second argument (the address of val2), x gets the value of the first argument (the int value stored in val1)

4. the value of the first argument cannot be modified by the function. the value of the second argument can be modified by the function by dereferencing the pointer parameter.

Here’s a swap function. Try it out if you do not understand how it works:

``````#include <stdio.h>

// do you understand why swap is a void function?
void swap(int *v1, int *v2) {
int temp;      // do you understand why temp is an int and not int*?
temp = *v1;
*v1 = *v2;
*v2 = temp;
}

int main() {
int x, y;
x = 10;
y = 50;
printf("x = %d y = %d\n", x, y);  // prints x = 10 y = 50
swap(&x, &y);
printf("x = %d y = %d\n", x, y);  // prints x = 50 y = 10
return 0;
}``````

### Exercises for 2.4 Dynamic Memory Allocation

``````#include <stdio.h>
#include <stdlib.h>

void foo(int *b, int c, int *arr, int n) ;
void blah(int *r, int s);

int main() {
int x, y, *arr;

arr = (int *)malloc(sizeof(int)*5);
if (arr == NULL) {
exit(1);   // should print out nice error msg first
}

x = 10;
y = 20;
printf("x = %d y = %d\n", x, y);
foo(&x, y, arr, 5);
printf("x = %d y = %d arr = %d arr = %d\n",
x, y, arr,arr);
free(arr);

return 0;
}

void foo(int *b, int c, int *arr, int n) {
int i;
c = 2;
for (i=0; i<n; i++) {
arr[i] = i + c;
}
*arr = 13;
blah(b, c);
}

void blah(int *r, int s) {
*r = 3;
s = 4;
// DRAW STACK HERE
}``````
1. Step through the execution and list the program’s output.

2. List the values of the array’s elements after the call to `foo` returns.

3. Draw the contents of the stack and the heap at the point of execution immediately before the `blah` function returns.

#### Solutions

``````x = 10 y = 20
``13, 3, 4, 5, 6`` 