C Programming Functions Macros Functions vs Methods Java

  • Slides: 14
Download presentation
C Programming Functions Macros

C Programming Functions Macros

Functions vs. Methods • Java classes include methods which can be called from any

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

Arguments vs Parameters • A parameter is defined in the function definition. It is a place holder for the argument during function execution void print. Int( int n ) // n is the parameter { printf( “%20 dn”, n); } • An argument is a value passed to a function when the function is called int age = 42; print. Int( 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

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 grow. Older( int a[

Passing Arguments /* ages. c */ #include <stdio. h> void grow. Older( int a[ ], int size) { int k; for (k = 0; k < size; k++) ++a[ k ]; } int avg. Age( const int array[ ], int size) { int k, sum = 0; for (k = 0; k < size; k++) sum += array[ k ]; return sum / size; } int main( ) { int nr. Students = 6; int ages[ 6 ] = {19, 18, 17, 22, 44, 55}; grow. Older( ages, nr. Students ); int avg = avg. Age( ages, nr. Students ); printf(“The average is %dn”, avg); return 0; }

Auto Type Conversion • As we’ve seen, the compiler can and will automatically convert

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. Age = 42, int. Initial = initial; long. Age = age; • The same type conversion occurs for function arguments. short my. Age = 42, your. Age = 33; long max( long a, long b); long older = max ( my. Age, your. Age);

Passing 2 -D Arrays • Passing a 2 -d array to a function is

Passing 2 -D Arrays • Passing a 2 -d array to a function is similar to passing a 1 -d array • Basic function prototype void print. Chess. Board( char [ 8 ] the. Board); • Calling the function char chess. Board[ 8 ]; print. Chess. Board( chess. Board ); • 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 print. Chess. Board( char[ ] [ 8 ] the. Board );

Recursion • C functions may be called recursively. – Typically a function calls itself

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

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 ) printd( n / 10 ); /* (n / 10 != 0) -- more than 1 digit */ /* 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

Recursive Exercise Complete the following recursive function that sums all of the integers from 1 to N int sum. To. N( int N ) { if (__________) // base case return N; else // recursive call return ___________; }

Inline Functions • C 99 only • Short functions may be defined as “inline

Inline Functions • C 99 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 is. Even( 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

Macros • C provides macros as an alternative to small functions. • More common prior to C 99 (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

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 )

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 );