We have already introduced three functions that come with C:
printf() fgets() scanf()A function is a named piece of C code. The code is executed each time the function is called (named). Functions are useful for many reasons. I'll give you three.
First, if you have a complicated task that must be performed in several places in a program,-- like, say, printing or getting input, your choice is to write the complicted code in the several places, or write the code once in a named function, then name the function in several places in the program. When we use printf, it looks simple, we plug-in an argument and printf prints it on the screen. The details of printf involve making calls to the operating system. Ultimately once printf has made the right system calls, it is the operating system that does the printing. This is hidden away from us. We just call printf.
Second, functions let you think about programs a different way. You can say to yourself, "I've got this problem to solve, if only I could do XXX, then I could use XXX to solve the problem". So the big problem is broken into two parts. Writing a function to do XXX and then using the function to help solve the original problem.
Third, if you are working on a large program with a team of programmers, the large problem can be broken into several pieces. Each piece can be assigned to a small group of programmers. You would be responsible for solving your piece and could work independently of the other groups.
int x=5; printf("The value of 3 times %d is: %d.\n", x, 3*x); x = printf("%d\n",12345); printf("%d\n", printf("%d\n",12345) );The second statement above uses the function printf to print the line
The value of 3 times 5 is 15.It does not use the value that printf returns. This is the most common way that printf is used. It is used for the printing work it does, not the value it returns.
NOTE: printf returns the number of characters in its output.
The third statement above is an assignment statement. The value of the expression on the right will be put into the variable on the left. The expression on the right is a call to function printf. The way a function-expresssion is evaluated is to run the function and see what value it returns. When this call to printf is executed printf prints
12345and then a newline character. That is a total of 6 characters. So that is the value that printf returns and that is the value of the expression on the right. So variable x is assigned the value 6.
The fourth line above has two printf's in it. The outside printf has two arguments in it separated by a comma:
"%d\n" printf("%d\n",12345)Before the outside printf can be run its arguments must be evaluated. The first argument is a string literal. Its value is just itself. Note: it tells printf that the type of second argument should be int and to print the evaluation of the second argument using decimal digits. Now the second argument is a function, the function printf. We evaluate it by running it. So the inside printf prints
12345and starts a newline AND returns the value 6. This is the value of the second argument. This value is printed by the outside printf. We see
12345 6
triple
, prtTriple
,
and main
.
1. #include<stdio.h> 2. int triple(int x) { 3. return 3*x; 4. } 5. void prtTriple(char *s) { 6. int i=0; 7. while (i<3) { 8. printf("%s\n", s); 9. i++; 10. } 11. } 12. int main() { 13. int age; 14. printf("Please enter your age\n"); 15. scanf("%d", &age); 16. printf("%d is triple your age\n", triple(age) ); 17. printf("%d is triple 2+3\n", triple(2+3) ); 18. prtTriple("Goodbye"); 19. }Lines 2, 3, and 4 are the definition of the function
triple
.
A function definition begins with a type name, in our case int.
This specifies the type of value that the function will return. Next comes
the function name, triple. Then what follows is a pair of parentheses
that contain declarations of the function's parameters separated by commas.
A function's parameters
are variables that will hold the values of the arguments plugged-into the
function when it is called. The value of first argument is put into the
first parameter, the value of the second argument is put into the second
parameter and so on. Function triple has one parameter, x, so when
triple is called it can take one argument (plug-in expression).
This much is called the function's header.
The rest of the function, its body, is the compound statement that comes after the header. The body contains the steps (statements) that will be executed when the function is called. We have one new keyword, return. The keyword return stops the function and returns the value of the expression that comes after it.
Lines 5-11 are the definition of the function prtTriple
. The type
name void
means that prtTriple does not return a value. Notice
that its body does not contain a statement of the form:
return someExpressionSo prtTriple does work for us but does not return a value. After its name comes the parentheses. Inside them is the declaration of its parameter
char *sSo prtTriple expects to be passed an address of a char, the address is normally the address of the first character of a string whose end is marked with a 0. Notice that the statement
8. printf("%s\n", s);prints the string that starts at address
s
. Since it is in a
loop that repeats 3 times, we will get 3 copies of the string printed on
the screen.
Function triple is called in the statements 16 and 17 of the body of main. We repeat them below:
printf("%d is triple your age\n", triple(age) ); printf("%d is triple 2+3\n", triple(2+3) );The expression plugged-into triple is the variable age. Variables are evaluated just by finding (looking up) the value assigned to them. The pass operation assigns the value of age to parameter x. Then the statements in the body are executed. So the function returns three times the value assigned to age. This is printed on the screen by the printf funtion. In the last line the expression 2+3 is the argument to triple. It evaluates to 5. That is passed to parameter x. Then the body is run and a value of 15 is returned by triple and the printf prints a 15 on the screen.
Function prtTriple is called in line 18. The address of G in "Goodbye" is passed to parameter s. Then statements of prtTriple are executed. Three Goodbyes are printed on the screen.
Parameters are the way functions access (use) the values of their arguments. If we want to use the value of the third argument, we use the name of the third parameter which is assigned (passed) the value of the third argument when the function is called. An Example: Function triple returns three times the value of its argument. It accesses the value of its argument in the expression 3*x, because x is the parameter that has been passed the value of the argument. The types of a parameter and its argument must correspond.
Note: The rules for what is a legal function name are the same as the rules (already covered) for what constitutes a legal variable name.
Note: Parameters of a function, and variables declared in the function are local to the function. That is they are private to the function. Other functions and the main program may have variables with the same name as those defined in our function. But C treats them as distinct variables. This is really important with different members of a programming team working independently on different functions.
int triple(int n) { return 3*n; } int sum(int n) { int s = 0; int i=1; while (i<=n) { s = s+i; i = i+1; } return s; } int main() { printf("Please enter a number\n"); int y; scanf("%d", &y); print("%d is the sum of the numbers from 1 to %d\n", sum(y), y); print("%d is triple the sum of the numbers from 1 to %d\n", triple(sum(y)), y); }Important: functions triple and sum both have a parameter named n. These are completely different variables. Variable names can be reused. That is, different functions and the main program can have variables with the same name. C does confuse or associate these variables.
Function sum has one parameter and two variables of its own. In the last line of the main program, sum is plugged in, inside function triple, which is plugged inside of function printf. So function sum will be run first. The value returned by sum is plugged into function triple. Then function triple is run, and the value it returns is plugged into function printf.
int sum(int n); //function headers required when compiler gets to int triple(int n); //tripleSum; needs int tripleSum(int y) { //compiler chks is plug-in to sum right type? return triple(sum(y)); //chks is plug-in to triple right type? } //chks is does return type of triple match //match return type of tripleSum int triple(int n) { return 3*n; } int sum(int n) { int s = 0; int i = 1; while (i<=n) { s = s + i; i = i + 1; } return s; } int main() { printf("%d\n", tripleSum(3) ); }The new feature here is the declarations (headers) of functions sum and triple that are placed before the definition of function tripleSum. The headers provide information about what can be plugged-in to sum and triple (int's) and what type they return (int).
Functions sum and triple are used in the definition of tripleSum, so when the compiler gets to the body of tripleSum it needs to make sure that sum and triple are being used correctly. It will check that the type of the plug-in to sum matches the type of the parameter of sum. And that the type of the plug-in to triple (namely the return type of sum) matches the type of the parameter of triple. Finally that the value returned by triple matches the return type of tripleSum.
In this example we could have avoided use of the headers by putting the whole definitions of sum and triple before the definition of tripleSum.
Let's go back to the concept of working on a programming team. Say we are working on the complicated function tripleSum and others are working on triple and sum. All we need to know about what the others are doing are the plug-in and return types of the two functions. That is exactly the information contained in the headers:
int sum(int n); int triple(int n);In fact, if you do your work, and you make a file, called say, ts.c, that contains
int sum(int n); int triple(int n); int tripleSum(int y) { return triple(sum(y)); }then you can compile it to object code with the command
gcc -c ts.cThis command will not make an executable a.out. It has no main and it does not have the definitions of sum or triple. It will make a file ts.o that contains the machine language translation of your work with subroutine calls for triple and sum that are missing the addresses of triple and sum. Later we can use gcc to link your object file, ts.o with a main and code for triple and sum to make an executable.
gcc ts.o triple.o sum.o main.oThe link operation fills in the missing addresses in the subroutine calls.
Next: Program Structure