160 likes | 213 Views
C Programming. Functions Macros. Functions vs. Methods. Java classes include methods which can be called from any code with appropriate access (recall public methods)
E N D
C Programming FunctionsMacros
Functions vs. Methods • Java classes include methods which can be called from any code with appropriate access (recall public methods) • C functions are like Java methods, but they don’t belong to any class. Functions are defined in a file and may be either global to your program or local to (“private” in) the file in which they are defined*. • Like Java methods, C functions • Have a name • Have a return type • May have parameters • Unlike Java methods, a function in C is uniquely identified by its name. Therefore, there is no concept of method overloading in C as there is in Java. There can be only one main( ) function in a C application. • See the course coding standards for function naming conventions.
Arguments vs Parameters • A parameter is defined in the function definition. It is a place holder for the argument during function execution • void printInt( int n ) // n is the parameter • { • printf( “%20d\n”, n); • } • An argument is a value passed to a function when the function is called • int age = 42; • printInt( age ); // age is the argument • These terms are often (incorrectly) used interchangeably, but the context is usually clear
Passing Arguments • Primitive types (int, char, float, etc) and structs are passed to function “by value” • A copy of the argument is passed to the function • Changing the parameter within the function has no effect on the argument in the calling code • Arrays are passed “by reference” • A copy of the address of the array is passed to the function • The parameter is an “alias” for the argument • References to array elements in the function refer to array elements in the calling code • Array parameters which are not intended to be changed by a function should be qualified as const
Passing Arguments /* ages.c */ #include <stdio.h> void growOlder( int a[ ], int size) { int k; for (k = 0; k < size; k++) ++a[ k ]; } int avgAge( const int array[ ], int size) { int k, sum = 0; for (k = 0; k < size; k++) sum += array[ k ]; return sum / size; } int main( ) { int nrStudents = 6;int ages[ 6 ] = {19, 18, 17, 22, 44, 55}; growOlder( ages, nrStudents ); int avg = avgAge( ages, nrStudents ); printf(“The average age is %d\n”, avg); return 0; }
Auto Type Conversion • As we’ve seen, the compiler can and will automatically convert a “small” data type to a “larger” data type without problems. • char initial = ‘B’; • short age = 42; • int intAge = 42, intInitial = initial; • long longAge = age; • The same type conversion occurs for function arguments. • short myAge = 42, yourAge = 33; • long max( long a, long b); • long older = max ( myAge, yourAge);
Passing 2-D Arrays • Passing a 2-d array to a function is similar to passing a 1-d array • Basic function prototype • void printChessBoard( char [ 8 ][ 8 ] theBoard); • Calling the function • char chessBoard[ 8 ] [ 8 ]; • printChessBoard( chessBoard ); • As we will see, the compiler needs to know the size of each row, but not the number of rows. This allows an alternative prototype • void printChessBoard( char[ ] [ 8 ] theBoard );
Recursion • C functions may be called recursively. • Typically a function calls itself • A properly written recursive function has the following properties • A “base case” - a condition which does NOT make a recursive call because a simple solution exists • A recursive call with a condition (usually a parameter value) that is closer to the base case than the condition (parameter value) of the current function call • Each invocation of the function gets its own set of arguments and local variables • We’ll see how recursion is implemented later
Recursion Example /* print an integer in decimal ** K & R page 87 (may fail on largest negative int) */ #include <stdio.h> void printd( int n ) { if ( n < 0 ) { printf( “-” ); n = -n; } if ( n / 10 ) /* (n / 10 != 0) -- more than 1 digit */ printd( n / 10 ); /* recursive call: n has 1 less digit */ printf( “%c”, n % 10 + ‘0’); /* base case --- 1 digit */ }
Recursive Exercise Complete the following recursive function that sums all of the integers from 1 to N int sumToN( int N ) { if (____________________) // base case return N; else // recursive call return ______________________; }
Inline Functions • C99 only • Short functions may be defined as “inline”. This is a suggestion to the compiler that calls to the function should be replaced by the body of the function. • inline functions provide code structure and readability and (may) increase performance • inline bool isEven( int n ) • { return n % 2 == 0; } • inline max( int a, int b ) • { return a > b ? a : b; }
Macros • C provides macros as an alternative to small functions. • More common prior to C99 (inline functions are better) • Handled by the preprocessor • Several “gotcha”s • Parameters have no type. • OK if used carefully • General macro format. • #define NAME( params if any ) code here • Note: there is NO space between the name and the left parenthesis • See macros.c
SQUARE( ) • A simple macro to square a variable • #define SQUARE( x ) x * x • Like all #defines, the preprocessor performs text substitution. Each occurrence of the parameter is replaced by the argument text. • int y = 5; • int z = SQUARE( y ); • But now consider this statement • int w = SQUARE( y + 1 );
A better SQUARE( ) • This version is better • #define SQUARE( x ) ( (x) * (x) ) • int y = 5; • int z = SQUARE( y ); • int w = SQUARE( y + 1 ); • But still doesn’t work in every case • int k = SQUARE( ++y );