SYSTEMATIC ERRORS IN TEMPERATURE ESTIMATES FROM MODIS DATA COVERING THE WESTERN PALEARTIC AND
3.2 Material and methods
int *ptr /* declare integer pointer */
int val1 = 42
int val2
ptr = &val1 /* point ptr at val1 */
val2 = *ptr /* store the value at ptr (val1) in val2 */
printf("val1 = %d, val2 = %d, *ptr = %d", val1, val2, *ptr)
*ptr=5 /* store 5 at *ptr (val1) */
printf("val1 = %d, val2 = %d, *ptr = %d", val1, val2, *ptr)
ptr = &*ptr /* meaningless but */
val1 = *&val1 /* instructive statements */
return EXIT_SUCCESS
}
14.2.2 Examination of
pointers.cWhen the program is compiled and executed, the output is given by:
val1 = 42, val2 = 42, *ptr = 42 val1 = 5, val2 = 42, *ptr = 5
and this can be explained as:
ptr is assigned the address of val1. Therefore the value of ptr is the address of the memory location.
val2is assigned the value of what ptris pointing to. Therefore, the value of val2is the contents of the memory location that ptris pointing to (val1).
After printing out the three values for the rst time, the contents of whatptris pointing to is changed to 5. As the contents of whatptris pointing to isval1, the value ofval1 is also 5 and val2is unchanged.
The nal two statements in the program illustrate how the the * and & operators are
\inverse" concepts, and notice that their order of precedence is right to left, so the one closest to the variable is always applied rst.
14.3 Functions: Call by Value and Call by Reference
As we have already seen in section 12, the C language calls functions by value, i.e. the value of an argument is passed to a function and the value of the variable in the calling function is not changed. But what if we want to change it? This can be achieved by passing the address of the variable which allows the function to know where the variable is and hence change the varaible's value stored at that location. This is known as call by reference, and is illustrated in the following example where a function is used to swap the values held by two variables.
14.3.1 Example:
swap.c/* Swap two values - wrong way using variable names
* - right way using pointers
*/
#include <stdio.h>
#include <stdlib.h>
/* declare functions */
void swap_wrong(int a, int b)
void swap_right(int *aptr, int *bptr)
int main() {
int value1 = 1 /* declare and initialise two integers */
int value2 = 2
printf("start : value1 = %d, value2 = %d\n", value1, value2)
/* try and swap their values the wrong way */
swap_wrong(value1, value2)
printf("swap_wrong: value1 = %d, value2 = %d\n", value1, value2)
/* try and swap their values the right way */
swap_right(&value1, &value2)
printf("swap_right: value1 = %d, value2 = %d\n", value1, value2)
return EXIT_SUCCESS
}
/* A function which (wrongly) attempts to swap the values held
* in the integer variables a and b
*
* Arguments:
* int a, int b: two integers values for swapping
*/
void swap_wrong(int a, int b) {
int tmp /* temporary value to aid swapping process */
tmp = a
a = b
b = tmp
return
}
/* A function which correctly swaps the values of two integers
* *aptr, *bptr and does so by using pointers!
*
* Arguments:
* int *aptr, int *bptr: two initialised integer pointers
*/
void swap_right(int *aptr, int *bptr) {
int tmp /* temporary value to aid swapping process */
tmp = *aptr
*aptr = *bptr
*bptr = tmp
return
}
14.3.2 Examination of
swap.cThe output from this program is:
start : value1 = 1, value2 = 2 swap_wrong: value1 = 1, value2 = 2 swap_right: value1 = 2, value2 = 1
and the following points should be noted about the program.
The swap_wrong() function has the values of value1and value2 passed to a and b, respectively. Hence the values ofvalue1andvalue2inmain()remain unchanged and
a and bare swapped (using the temporary variable tmp). This is lost however, when control is passed back to themain()calling function and the automatic variablesaand
bare destroyed.
The swap_right()function has the addresses (indicated by the & symbol) of value1 andvalue2passed to the pointers aptrandbptr, respectively. It is important to note that the pointer in the argument list is declared as int *aptr, but the address of a variable&value1 is passed across from the calling function. This notation may seem a little strange initially, but it is correct.
It is important to remember to apply the address of, &, operator when the functions are called and the corresponding arguments are pointers. Sometimes the compiler may not complain if you forget to do this, although the program will behave incorrectly. Generally it is only possible to nd these bugs with a debugger.
14.3.3 Modifying Variables and Arguments
Functions can be classied as belonging to either one of two groups: those which modify the (local) variables in the calling function and those which do not. The latter are called for their side eects, such as printing a message to the screen etc., whereas the former are used to modify the calling function's state (such as sqrt() etc.). You now know of two ways for modifying the variables in the calling function:
To change a variable in the calling function by having the called function pass back an appropriate value as its returntype.
To change variables in the calling function by using pointers to eect a call by reference.
When only a single value needs to be remembered (such as calculating the value of a square root), the result should be passed back as a return type, whereas the latter is used when several variables must be altered.
We shall see that sometimes arguments are passed by reference when the data type is large, as instead of having to copy the complete variable, only its address needs to be passed across.