Presentation is loading. Please wait.

Presentation is loading. Please wait.

Introduction to C Lecture 4: Functions Alireza Masoum Urmia University Of Technology 2007

Similar presentations


Presentation on theme: "Introduction to C Lecture 4: Functions Alireza Masoum Urmia University Of Technology 2007"— Presentation transcript:

1 Introduction to C Lecture 4: Functions Alireza Masoum amasoum@alum.sharif.edu Urmia University Of Technology 2007 amasoum@alum.sharif.edu

2 Introduction Structured Programming is a problem-solving strategy and a programming methodology that includes the following two guidelines: The flow of control in a program should be as simple as possible. The construction of a program should embody top-down design.

3 Top-down Design Top-down design, also referred to as stepwise refinement, or divide and conquer, consists of repeatedly decomposing a problem into smaller problems. In other words: –Construct a program from smaller pieces or components These smaller pieces are called modules –Each piece more manageable than the original program

4 Program Modules in C Functions –Modules in C –Programs combine user-defined functions with library functions C standard library has a wide variety of functions Function calls –Invoking functions Provide function name and arguments (data) Function performs operations or manipulations Function returns results –Function call analogy: Boss asks worker to complete task –Worker gets information, does task, returns result –Information hiding: boss does not know details

5 Math Library Functions Math library functions –perform common mathematical calculations –#include Format for calling functions –FunctionName( argument ); If multiple arguments, use comma-separated list –y = sqrt( 900.0 ); Calls function sqrt, which returns the square root of its argument All math functions return data type double –Arguments may be constants, variables, or expressions

6 Available Mathematical functions Function HeaderDescription int abs(int num)Returns the absolute value of an integer element. double fabs(double num)Returns the absolute value of a double precision element. double pow(double x,double y)Returns x raised to the power of y. int rand(void)returns a random number double sin(double angle)Returns the sine of an angle the angle should be in Radius. double cos(double angle)Returns the cosine of an angle the angle should be in Radius. double sqrt(double num)Returns the sign the square root.

7 Using Library Functions Calculate the square root of (x1 - x2) 2 + (y1 - y2) 2 a = x1 – x2; b = y1 – y2; c = pow(a,2) + pow(b, 2); d = sqrt(d); OR just: d=sqrt( pow( (x1-x2), 2) + pow( (y1-y2), 2)); What is the value of: sqrt(floor(fabs(-16.8)))

8 Functions We have already written our own functions and used library functions: –main is a function that must exist in every C program. –printf, scanf are library functions which we have already used in our programs. We need to do two things with functions: –Create Functions –Call Functions (Function invocation)

9 Functions #include int main(void) { int i = 0, p = 1; while (++i <= 10) printf(“%-6d”,p*=2); printf(“\n”); return 0; } program structure so far: int main(void) int func1(...) int func2(...) modular program structure using functions:

10 Function Definition A function definition has the following form: return_type function name (formal parameter list) { declarations statements } function prototype return_type - the type of value returned by the function void – indicates that the function returns nothing. function name – any valid identifier formal parameter list – comma separated list, describes the number and types of the arguments that get passed into the function when its invoked.

11 Function definition int main(void) { int m = 12; printf(“%d\n”,fact(m)); return 0; } int fact(int n) { int i, product = 1; for (i = 1; i<=n; ++i) product *= i; return product; } header body declara- tions statements type func_name( parameter_list ) { declarations statements } format of a function definition:

12 Function header type func_name( parameter_list ) type returned by the function ( void if no value returned) list of arguments: type parameter_name multiple arguments are separated by commas void if no parameters function name a = fact(13); error_message(2); x=initial_value(); Usage: int fact(int n) void error_message(int errorcode) int main(void) Examples: double initial_value(void)

13 later Function examples Examples of library functions encountered so far: double sqrt(double x) int abs(int i) double fabs(double x) int putchar(int c) int getchar(void) double pow(double x, double y) int printf(const char *format,...) int scanf(const char *format,...) Write your code as collections of small functions to make your program modular structured programming code easier to debug easier modification reusable in other programs

14 Example Let’s define a function to compute the cube of a number: int cube ( int num ) { int result; result = num * num * num; return result; } This function can be called as: n = cube(5);

15 Function prototypes If a function is not defined before it is used, it must be a declared by specifying the return type and the types ot the parameters doublesqrt(double); tells the compiler that the function sqrt() takes an argument of type double and returns a double. This means, that the result of a function is cast to the correct type. sqrt(4) will return the correct type (double) even though 4 is int not double. definition variable names in the argument list of a function declaration are optional: (but, of course, not in the function definition) void f (char, int); void f ( char c, int i) ; equivalent but makes code more readable These function prototypes are placed at the top of the program, or in a separate header file file.h, included as #include “file.h“ If all functions are defined before they are used, no prototypes are needed. In this case, main() is the last function of the program.

16 Function Prototypes Function prototype –Function name –Parameters – what the function takes in –Return type – data type function returns (default int ) Used to validate functions –Prototype only needed if function definition comes after use in program The function with the prototype int maximum( int, int, int ); Takes in 3 int s Returns an int

17 Function calls expressions in the parameter list are evaluated (in no particular order!) results are transformed to the required type parameters are copied to local variables for the function function body is executed when return is encountered, the function is terminated and the result (specified in the return statement) is passed to the calling function (for example main) int fact (int n) { int i, product = 1; for (i = 2; i <= n; ++i) product *= i; return product; } int main (void) { int i = 12; printf(“%d”,fact(i)); return 0; } When a function is called, this is what happpens:

18 Scope rules for blocks Identifiers (i.e. variables etc.) are accessible only within the block in which they are declared. A variable that is declared in an outer block is available in the inner block unless it is redeclared. In this case the outer block declaration is temporarily “masked”. Avoid masking! Use different identifiers instead to keep your code debuggable! { int a = 2;/* outer block a */ printf(“%d\n”, a);/* 2 is printed */ { int a = 5;/* inner block a */ printf(“%d\n”, a);/* 5 is printed */ } printf(“%d\n”, a);/* 2 is printed */ } /* a no longer defined */ outer a masked

19 Scope rules for functions int main (void) { int a = 2, b = 1, c; c = func(a); return 0; } int func (int n) b { printf(“%d\n”, b ); return n; } variables defined within a function (including main) local are local to this function and no other function has direct access to them! b not defined locally! the only way to pass variables to a function is as parameters the only way to pass (a single) variable back to the calling function is via the return statement Exceptions:1. Global Variables2. Pointers

20 Function Invocation A program is made up of one or more functions, one of them being main ( ). When a program encounters a function, the function is called or invoked. After the function does its work, program control is passed back to the calling environment, where program execution continues. Main Func 1 Func 2

21 #include void prn_message (void); /* function prototype */ int main (void) { prn_message ( ); /* function invocation */ return 0; } void prn_message(void) /* function definition */ { printf(“A message for you: ”); printf(“Have a nice day!\n”); }

22 #include void print_message (int k); /*function prototype */ int main (void) { int n; printf(“There is a message for you.\n”); printf(“How many times do you want to see it? ”); scanf(“%d”, &n); print_message(n); return 0; } void print_message (int k) /* function definition */ { int i; printf(“\nHere is the message.\n”); for (i=0; i < k; ++i) printf(“Have a nice day!\n”); }

23 /* An example demonstrating local variables */ #include void func1 (void); int main (void) { int i = 5; printf(“%d \n”, i); func1( ); printf(“%d \n”,i); return 0; } void func1 (void) { int i = 5; printf(“%d\n”, i); i++; printf(“%d\n”, i); } 55655565

24 The return statement When a return statement is executed, program control is immediately passed back to the calling environment. If an expression follows the keyword return, the value of the expression is returned to the calling environment as well. A return statement has one of the following two forms: return; return expression ;

25 Examples return; return 77; return ++a; return (a+b+c);

26 #include int min (int a, int b); int main (void) { int j, k, m; printf(“Input two integers: ”); scanf(“%d %d”, &j, &k); m = min(j,k); printf(“\nThe minimum is %d.\n”, m); return 0; } int min(int a, int b) { if (a < b) return a; else return b; } Input two integers: 5 6 The minimum is 5. Input two integers: 11 3 The mininum is 3.

27 Parameters A function can have zero or more parameters. In declaration header: int f (int x, double y, char c); In function calling: value = f(age, score, initial); the formal parameter list (parameter variables and their types are declared here) actual parameter list (cannot tell what their type are from here)

28 Rules for Parameter Lists The number of parameters in the actual and formal parameter lists must be consistent Parameter association is positional: the first actual parameter matches the first formal parameter, the second matches the second, and so on Actual parameters and formal parameters must be of compatible data types Actual parameters may be a variable, constant, any expression matching the type of the corresponding formal parameter

29 Global variables #include int a = 1, b = 2;/* global variables */ int main (void) { int b = 5;/* local redefinition */ printf(“%d”, a+b);/* 6 is printed */ return 0; } global, variables defined outside blocks and functions are global, i.e. available to all blocks and functions that follow Avoid using global variables to pass parameters to functions! Only when all variables in a function are local, it can be used in different programs Global variables are confusing in long code

30 int a, b, c; file.c Structure and scope of variables of a c-file func1 () { int a, b, c; } main () { int x, y; } { int c,d,e; } block2 { int d,e,f; } block1 { int g; } nested block variables out of scope between parallel blocks variables in scope down nested blocks (except for masking) masking) use it for efficient use of memory

31 Invocation and Call-by-Value Each argument is evaluated, and its value is used locally in place of the corresponding formal parameter. If a variable is passed to a function, the stored value of that variable in the calling environment will not be changed. In C, all calls are call-by-value.

32 #include intcompute_sum (int n);/* function prototype */ /* ------------------------------------------------------- */ int main(void) { int n = 3, sum; printf(“%d\n”, n);/* 3 is printed */ sum = compute_sum(n);/* pass value 3 down to func */ printf(“%d\n”, n);/* 3 is printed - unchanged */ printf(“%d\n”,sum);/* 6 is printed */ return 0; } /* ------------------------------------------------------- */ int compute_sum (int n)/* sum integers 1 to n */ { int sum = 0; for ( ; n > 0; --n)/* local value of n changes */ sum += n; return sum; } n unchangedCall-by-value local copy of n, independent of n in calling function Arguments to functions are evaluated, and the copies of the values – not any variables in the argument – are passed down to the function Good:protects variables in calling function Bad:copying inefficient, for example for large arrays pointers sum.c prototype

33 #include int compute_sum (int n); int main (void) { int n, sum; n = 3; printf(“%d\n”, n); sum=compute_sum(n); printf(“%d\n”,n); printf(“%d\n”, sum); return 0; } int compute_sum (int n) { int sum; sum = 0; for ( ; n > 0; --n) sum += n; printf(“%d\n”, n); return sum; } 30363036

34 1/* Finding the maximum of three integers */ 2 3#include 4 5int maximum( int, int, int ); /* function prototype */ 6 7int main() 8{8{ 9 int a, b, c; 10 11 printf( "Enter three integers: " ); 12 scanf( "%d%d%d", &a, &b, &c ); 13 printf( "Maximum is: %d\n", maximum( a, b, c ) ); 14 15 return 0; 16} 17 18/* Function maximum definition */ 19int maximum( int x, int y, int z ) 20{ 21 int max = x; 22 23 if ( y > max ) 24 max = y; 25 26 if ( z > max ) 27 max = z; 28 29 return max; 30} Enter three integers: 22 85 17 Maximum is: 85

35 Storage Classes The storage class tells us the visibility and lifetime of a variable in a C program. –By visibility we mean the extent to which it is accessible to statements in C programs. –By lifetime we mean the length of time for which the variable actually exists in storage. The storage classes for C identifiers: auto extern register static

36 The storage class auto An automatic variable is declared within a function body. Every variable we seen so far is automatic. –When a block is entered, storage for the automatic variables in it are allocated, and their initial values (if any) are set. Storage for these values only exists while the block is being executed. Automatic variables are frequently referred to as local variables since they are only locally visible. However, local variables are truly determined by scope. As we shall see, some local variables are not of storage class auto.

37 Storage classes Every variable and function in C has two attributes: type ( int, float,... ) storage class auto extern register static auto auto (the default and the most common) Memory for automatic variables is allocated when a block or function is entered. They are defined and are “local” to the block. When the block is exited, the system releases the memory that was allocated to the auto variables, and their values are lost. There are four storage classes: Storage class is related to the scope of the variable auto type variable_name; There’s no point in using auto, as it’s implicitly there anyway Declaration:

38 Example of storage class auto behavior #include void autoprinter(int j); intmain(void){ int j; for (j = 0; j < 5; j++) autoprinter( j ); return 0; } void autoprinter(int j){ int k = 1; printf (“j = %d k = %d\n”, j, k++); } This program produces the following output: j = 0 k = 1 j = 1 k = 1 j = 2 k = 1 j = 3 k = 1 j = 4 k = 1

39 Storage class extern global variables (defined outside functions) and all functions are of the storage class extern and storage is permanently assigned to them extern type variable_name; Within a file variables outside functions have external storage class, even without the keyword extern. Files can be compiled separately, even for one program. extern is used for global variables that are shared across code in several files.

40 The storage class extern Variables declared outside of functions are of storage class extern. No keywords are necessary, rather the placement of the declaration within the file determines the storage class. Variables of extern storage class are visible in all functions that follow their declaration in a file. Storage for extern variables is allocated once when the program begins and remains for the life of the program. Variables of extern storage class are frequently referred to as global variables. Variables of storage class extern cannot be register or auto. All functions are extern storage class.

41 Do we need function parameters given global variable capability. Communication through parameters is usually the preferred way of communication between functions. –Global variables can be modified by any function within a program as a side effect of execution of the function. It can be exceedingly difficult to determine all of the possibilities by which global variables can be updated and what their values might be when a function is invoked. This can make it very difficult to maintain programs that make extensive use of global variables. –When the same input may be treated differently depending on data that has been previously processed, the program is said to have state. The findyes program had state, it acted differently when it saw an ‘e’ depending on whether it had just seen a ‘y’. Global variables cause programs to have state when we may note want them to.

42 Example of storage class extern #include inta = 1, b = 2, c = 3; /* global variables (extern storage class)*/ intf(void);/* function prototype*/ int main(void){ printf(“%3d\n”, f());/* 12 is printed */ printf(“%3d%3d%3d\n”, a, b, c);/* 4 2 3 printed*/ return 0; } int f(void){ intb,c;/* b, and c are local variables */ /* global copies of b and c are masked*/ a = b = c = 4;/* global variable a and local b, c updated */ return (a + b + c); }

43 extern in multi-file projects file1.c #include int a =1, b = 2, c = 3; /* external variables */ int f(void); int main (void) { printf(“%3d\n”, f( )); printf(“%3d%3d%3d\n”, a, b, c); return 0; } file2.c int f(void) { extern int a;/* look for it elsewhere */ int b, c; a = b = c = 4; return (a + b + c); } return 12 a is global and changed by f print 4, 2, 3 b and c are local and don‘t survive compile as: cc file1.c file2.c –o prog

44 What is a register? A register is very high speed memory. Typical machines have a very small number of registers, often 16. Programs copy data into registers from regular memory (RAM) and then operate on it. For a number in memory to undergo arithmetic it must first be copied into a register and the result copied back to memory. When a byte of data is to be copied from one location to another in memory, on most computers, it is copied into a register from the original location and then copied out of the register into the destination location. In short, registers are very fast memory and their contents are usually short- lived.

45 The storage class register The storage class register suggests to the compiler that a variable be kept only in a register. Automatic variables in short-lived functions are reasonable candidates if they are very frequently referenced. The overhead of reading and writing to memory is avoided and the performance improvements can be dramatic. The downside of register variables is that each register variable used removes a possible register the compiler might be able to use in improving speed of the code. (Remember there are not very many registers on most machines.) Consider using register variables for the indices of an innermost loop. Declaring a variable to be storage class register does not guarantee that the compiler will use a register for it, it is only a suggestion to the compiler that will be followed if it is physically possible and makes semantic sense. If you declare a variable to be of storage class register, declare it as close to its place of use as possible. If the compiler uses a register for the variable the register is unavailable for other purposes during the entire life of the variable.

46 Storage class register register tells the compiler that the variables should be stored in high-speed memory registers if possible. Only a few such registers are available, and can be assigned to frequently-accessed variables if execution time is a problem. If no register space is free, variables become auto instead. Keep registers in small local blocks which are deallocated quickly. Example: { register int i; for (i=0; i < 100; i++) {..... } now obsolete since done automatically by most compilers register is freed on block exit

47 Storage class static This can be useful, e.g., for debugging: you can insert code like this anywhere without interfering with the rest of the program {/* debugging starts here */ static int cnt = 0; printf(“*** debug: cnt = %d, v = %d\n”, ++cnt, v); } The variable cnt is local to the block and won’t interfere with another variable of the same name elsewhere in an outer block; it just increases by one every time this block is encountered. static variables are local variables that keep their previous value when the block is reentered. A declaration static int cnt = 0; will set cnt to zero the first time the function is used; thereafter, it will retain its value from previous iterations.

48 Static Storage Class Static variables are variables that exist for the life of the program. They are truly the opposite of automatic variables. Using a static variable as a local variable, even a called function can retain private information from one invocation to the next. This is sometimes used to make a function act differently the first time it is called in a program. (As an alternative to priming the pump.) Static variables can only be seen within functions that are defined after the static variable appears in the source file. If they are at the top of the file, all functions in that file may “see” them but all functions in other source files may not. If they appear between functions in a source file, those defined above can’t “see” them while those below can.

49 Recursion A function is called recursive if it calls itself, either directly or indirectly. In C, all functions can be used recursively. int sum(int n) { if (n <= 1) return n; else return (n + sum(n - 1)); } Example: If you don‘t want to generate an infinite loop, you must provide a condition to end the recursion (here n<=1), which is eventually met. Exercise: rewrite the above code to calculate factorials; 0!=1, n! = n(n-1)…3 2 1 for n>0. Recursion is often inefficient as it requires many function calls. See recurs.c in lect4 as another example of recursion.

50 Example: Fibonacci numbers A recursive function for Fibonacci numbers (0,1,1,2,3,5,8,13...) int fibonacci(int n) { if (n <= 1) return n; else return (fibonacci(n-1) + fibonacci(n-2)); } 1.4 x 10 9 function calls needed to find the 43 rd Fibonacci number! (which has the value 433494437) If possible, it is better to write iterative functions, for example: int factorial (int n) /* iterative version */ { for ( ; n > 1; --n) product *= n; return product; }

51 Example: Towers of Hanoi The object of the game is to move a set of disks, stacked in successively decreasing diameters, from tower A to tower C using a third tower B as an intermediate. It is not allowed to stack any disk on top of a smaller disk. In directory lect4/hanoi/ there is a program whose core routine is move(n, ‘A’, ‘B’, ‘C’) which moves n disks from ‘A’ to ‘C’, using ‘B’ as intermediary. Recursion is a useful way to deal with the task, since before the n th disk can be moved from A to C, the n-1 disks above it must temporarily be moved to B. A B C


Download ppt "Introduction to C Lecture 4: Functions Alireza Masoum Urmia University Of Technology 2007"

Similar presentations


Ads by Google