Transcript Functions

C Programming
Functions
Macros
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 )
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 1 to N
int sumToN( int N )
{
if (____________________)
return N;
// base case
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 );