Files for this lab are located in: /stage/classes/archive/2011/summer/50101-1/lab/lab4/src.
In contrast, under call by reference argument evaluation, a function receives a memory address (or pointer) of the variable passed as an argument.
The function swap() in swap.c is an example of a call-by-reference function:
In the argument list of swap(), * ("star") tells us that the arguments are "pointers to integers", or memory addresses of integers.
In the body of swap(), the operator * is used to dereference pointers px and py, or to get the integer values that px and py point to.
For example, here px is dereferenced, and the result is assigned to tmp:
Note that these are two different uses of *.
In the argument list, * indicates a pointer data type.
In the assignment statement, * is an operator that dereferences a pointer variable.
What is the data type of expression *px in the above assignment statement? (Hint: What is the data type of tmp, on the left sign of operator =?)
You can see that the & operator is used in main() to pass the addresses of variables x and y to swap():
Ch. 9, Heading Pointers: A First Look in Prata covers pointers, pointer syntax, and pointers as function arguments.
Add a new function to this file called reorder(),
which is similar to swap() but performs a swap only if the integer value at px is greater than the value at py.
Otherwise, reorder() does not perform a swap.
So after reorder() returns, the second argument always points to the larger of the two integer values.
You are given this function prototype:
main() includes two tests for reorder().
You will have to modify main() to call reorder() for each test case:
Your output should look like this (note a swap occurs in the first test but not the second):
norm_time() will take two arguments:
Compile and run this program. You will see this output:
Next look at function set_array():
Update main() so that it calls set_odd() instead of set_array().
Your output should look like this:
The file str_demo.c contains a simple function that updates the first character in a string:
This function should make changes in-place, meaning that it should change the string that is passed as input. Your function flip_case() should not call printf().
You can use str_demo.c as a starting point. Your output should look something like this:
Submit your *.c files for Lab 4: ex1.c, ex2.c, ex3.c, ex4.c
First, be sure that every source file you submit includes this information in comments
at the top of the file:
Also include a simple README file in your lab4 directory.
This file should include your first and last name, your username, the list of files that you are submitting, and any other comments or questions for the Lab TA.
Do not submit any compiled binary files
You will submit this lab with the hwsubmit program.
prepared by Sonjia Waxmonsky
Call by reference
Up to now we have seen many examples of functions that are call by value,
where the function receives a copy of a variable that is passed as an argument.
In the following example, square() receives a copy of variable x when called from main():
/* returns the square of n */
int square( int x )
{
return x*x;
}
int main()
{
int x=2;
int y=square(x);
...
}
void swap (int * px, int * py)
{
int tmp = *px;
*px = *py;
*py = tmp;
}
Compile and run the program swap.c. You will see this output:
Old value of x: 4
Old value of y: 8
Calling swap...
New value of x: 8
New value of y: 4
Note that the call to swap in main() switches the values of local variables x and y:
int main()
{
int x=4, y=8;
printf("Old value of x: %d\n",x);
printf("Old value of y: %d\n",y);
printf("Calling swap...\n");
swap(&x,&y);
printf("New value of x: %d\n",x);
printf("New value of y: %d\n",y);
return 0;
}
void swap (int * px, int * py) /* argument list */
int tmp = *px; /* assignment statement */
swap(&x,&y);
It's necessary to use the & operator here, since swap expects pointers (i.e., memory addresses) as arguments. If you omit the "&" operator then gcc would report a compiler error, since swap() expects int * arguments, and not int.
Exercise 1
Use ex1.c as a starting point for this Exercise.
void reorder(int * px, int * py);
printf("Calling reorder ...\n");
/* add call to reorder here */
printf("New values: x=%d, y=%d\n",x,y);
Test 1: x=8, y=4
Calling reorder ...
New values: x=4, y=8
Test 2: a=5, b=9
Calling reorder ...
New values: a=5, b=9
Exercise 2
If I told you that a movie lasted "1 hour and 75 minutes", you would probably do some quick arithmetic to figure out that this is the same amount of time as "2 hours and 15 minutes". Write a function called norm_time() that "normalizes" times, represented in hours and minutes, so that the number of minutes is between 0 and 59.
You can use file ex2.c as a starting point. This includes an incomplete version of main, with two test cases for norm_time(). To complete this program, you will need to:
Your output should look like this:
print_time(hours,mins);
/* add call to norm_time() */
printf(" Printing normalized time...\n");
Test 1:
1 hours, 135 minutes
Printing normalized time...
3 hours, 15 minutes
Test 2:
5 hours, 59 minutes
Printing normalized time...
5 hours, 59 minutes
Arrays and array arguments
The file array_demo.c is a simple program that includes two functions, print_array() and set_array(). Both of these functions take an array as an argument.
Calling print_array() ...
0: 10
1: 11
2: 12
3: 13
4: 14
5: 15
6: 16
7: 17
Calling set_array() ...
Calling print_array() ...
0: 42
1: 42
2: 42
3: 42
4: 42
5: 42
6: 42
7: 42
You can see that main() declares and initializes an integer array:
int a[LEN] = {10,11,12,13,14,15,16,17};
Next, look at the function print_array():
void print_array(int * arr, int len)
{
int i=0;
while(i<len)
{
printf("%d: %d\n",i,arr[i]);
++i;
}
}
The first argument, int * arr, holds the address of the first element of array arr. As with C-strings, we can access an element at a particular index with brackets ([]).
void set_array(int * arr, int len, int val)
{
int i=0;
while(i<len)
arr[i++]=val;
printf("\n");
}
set_array() is a function that writes the same value to every position in array argument arr. So unlike print_array(), set_array() does update the values in the array. Because set_array() receives the address of the array, it directly updates the local variable a in main(). That is, set_array() is not working with a copy of the original array.
Exercise 3
Copy array_demo.c to a new file, ex3.c. Next, create a new function, set_odd(), that has the same functionality as set_array() but only updates the odd indices in the array (1,3,5,...).
Even indices are set to zero.
Calling print_array() ...
0: 10
1: 11
2: 12
3: 13
4: 14
5: 15
6: 16
7: 17
Calling set_odd() ...
Calling print_array() ...
0: 0
1: 42
2: 0
3: 42
4: 0
5: 42
6: 0
7: 42
Strings and string arguments
In the last exercise you modified an array of integers by passing the array address (i.e., the address of the first element) to a function as an argument. You can also modify strings in same way.
void set_first(char str[],char c)
{
str[0] = c;
}
Compile and run this program. you will see that set_first() updates the string variable str:
Enter a word: UChicago
Calling set_first() ...
New string: ZChicago
We could also implement set_first() by using the * operator instead of brackets to set the first element in str.
So this implementation would have the same output:
void set_first(char * str, char c)
{
*str = c;
}
Exercise 4
Write a function called flip_case() that takes a single string as input and reverses the case of every letter in that string. That is, lower-case letters are converted to upper-case, and upper-case letters are converted to lower case. Other letters are unchanged. So "Hello!" becomes "hELLO!".
Enter a word: U-Chicago
Calling set_first() ...
New string: u-cHICAGO
Note that in the last lab, you wrote a function that took a character as an argument, and here you will write a function that takes a string as an argument.
Submitting your assignment
Lab 4 is due: Saturday, July 23 at 11:59pm
$ hwsubmit cspp50101lab <path to your lab4 directory>
Submit to cspp50101lab, NOT cspp50101.