CSC270: More Functions, and Types
Call-by-value
[not in King?]
When a function is called, C does several things:
1. Compute values for all the arguments.
2. Set each parameter to the value of the corresponding argument.
3. Execute the function body.
If an argument is a variable name, the *value* of the variable is
passed in to the function, not the variable itself. This means that
any changes the function makes to parameters are *not* returned
from the function.
int square( int x )
{
x = x * x;
return x;
}
...
i = 9;
j = square( i );
printf( "i = %d, j = %d\n", i, j );
--> i = 9, j = 81
In the example above, the parameter x is given the value of argument i
before the function is executed. When executed, the function changes
the value of its parameter. However, the change is not brought
outside the function.
Variable scope
[King 10.4]
Note that the variable name `i' occurs twice in the program below.
These are two different local variables, one in `main' and the other
in `print_lots'.
void print_lots( int n )
{
int i;
for (i=n; i>0; i--)
printf( "." );
printf( "\n" );
}
main()
{
int i;
for (i=0; i<20; i++)
print_lots( i );
}
The `scope' of a variable is the region of the program in which it is
recognized. The scope of a variable is the code between the smallest
enclosing braces { } around the declaration of the variable. Above,
the scope of `i' is the function body of `print_lots' (for one of the
variables) and the body of `main' (for the other variable).
There is one exception: if these braces contain another set of braces
in which the same variable name is declared, then the scope of the
variable does not include the region between the inner braces:
main()
{
int i, j;
for (i=0; i<10; i++) {
for (j=0; j<10; j++) {
int i;
i = j * 10;
printf( "inner i = %d\n", i );
}
printf( "-- outer i = %d\n", i );
}
}
The scope of the outer `i' is the body of `main' EXCEPT that part
between the innermost braces. Inside the innermost braces is another
variable `i' (same name, different variable) whose scope is the code
between the innermost braces.
Conversion between types of variables
[King 7.5]
What happens when you assign a float to an int?
int i;
float x;
x = 3.14;
i = x;
C converts the float into an int before assigning it. Typically, C
will truncate any fractional part of the float.
Numeric operators must have arguments of the same type. If we add
an int and a float, the int gets `promoted' to a float before the
addition takes place.
y = i + x;
Watch out for divisions with integers! If you divide integer i by
integer j and *then* assign the result to a float x, the value i/j
will be an integer which is converted to a float *upon* being
assigned. This means that the fractions part of the quotient will be
lost:
main()
{
int i, j;
float x;
i = 7; j = 2;
x = i/j;
printf( "%g\n", x );
}
--> 3
You must explicitly convert one of the ints to a float *before* doing
the division. If one argument of the division is a float, the other
will be automatically converted to a float and the quotient will be a
float.
Casting
To convert a variable to a new type, add the type name in parentheses
in from of the variable:
x = i / (float) j;
printf( "%g\n", x );
--> 3.5
The explicit transformation into a new type is called a `cast'. A
variable (or expression) is said to be `cast' into a new type.
Macros
[King 14.3]
A macro is a string of characters that gets substituted with another
string before being compiled. For example, the following defines MAX
to be 10:
#define MAX 10
Whereever "MAX" appears in the program, it will be replaced with "10";
main()
{
int i;
for (i=0; i < MAX; i++)
printf( "%d ", i );
printf( "\n" );
}
Arrays
[King 8]
An array hold many elements of the same type. Each element is
associated with an index. In C, indices always start with *zero*.
To declare an array of 10 integers or floats or chars:
int i[10];
float f[10];
float c[10];
The array can be thought of as
i
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| | | | | | | | | | |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
i[0] i[1] i[2] i[3] i[4] i[5] i[6] i[7] i[8] i[9]
The variable `i' denotes the *whole* array, whereas `i[k]' denotes
element k of the array. This is often pronounced ``i at k''. `k' is
called the index. The index can be any integer expression.
To initialize an array:
#define N 10
int a[ N ];
for (i=0; i < N; i++)
a[i] = 0;
To compute Fibonacci numbers (recall f(i) = f(i-1) + f(i-2)):
a[0] = 1;
a[1] = 1;
for (i=2; i < N; i++)
a[i] = a[i-1] + a[i-2];
Note that the array indices go from 0 to N-1, *not* from 1 to N!