Functions
Functions
Split programs into named, reusable pieces: declarations, definitions, parameters, return values and call by value.
A function is a named block of code that does one job. You have been calling functions since lesson one — printf and scanf are functions written by someone else. Now you will write your own.
Why bother?
- Reuse — write the logic once, call it many times.
- Readability —
isPrime(n)explains itself; forty lines of loop do not. - Testing — a small function is easy to check on its own.
Defining and calling a function
#include <stdio.h>
// definition: return type, name, parameters, body
int square(int x) {
return x * x;
}
int main(void) {
int a = square(7); // call: 7 is the argument
printf("7 squared is %d\n", a);
printf("12 squared is %d\n", square(12));
return 0;
}7 squared is 49 12 squared is 144
| Part | In the example |
|---|---|
| Return type | int — the type of value sent back |
| Name | square |
| Parameter list | (int x) — inputs the function receives |
| Body | { return x * x; } |
return |
sends a value back and ends the function |
A function that returns nothing has return type void. A function that takes nothing has (void) as its parameter list.
#include <stdio.h>
void printLine(int n, char ch) {
for (int i = 0; i < n; i++) putchar(ch);
putchar('\n');
}
int main(void) {
printLine(20, '=');
printf(" REPORT CARD\n");
printLine(20, '-');
return 0;
}==================== REPORT CARD --------------------
Declarations (prototypes)
C reads your file top to bottom. If main calls a function defined below it, you must declare the function first with a prototype — the header line followed by a semicolon:
#include <stdio.h>
int isPrime(int n); // prototype: tells the compiler the function exists
int main(void) {
printf("Primes up to 30: ");
for (int i = 1; i <= 30; i++)
if (isPrime(i)) printf("%d ", i);
printf("\n");
return 0;
}
int isPrime(int n) { // definition comes later
if (n < 2) return 0;
for (int d = 2; d * d <= n; d++)
if (n % d == 0) return 0;
return 1;
}Primes up to 30: 2 3 5 7 11 13 17 19 23 29
Call by value
When you pass a variable to a function, C copies its value into the parameter. The function works on the copy; the original is untouched.
#include <stdio.h>
void tryToChange(int x) {
x = 100;
printf("Inside the function: x = %d\n", x);
}
int main(void) {
int x = 5;
tryToChange(x);
printf("Back in main: x = %d\n", x);
return 0;
}Inside the function: x = 100 Back in main: x = 5
So how can a function swap two variables in main? It needs their addresses — that is call by reference, which you will learn in Pointers, Arrays & Functions.
Functions calling functions
Good programs are built from small functions that call each other:
#include <stdio.h>
int gcd(int a, int b) {
while (b != 0) {
int r = a % b;
a = b;
b = r;
}
return a;
}
int lcm(int a, int b) {
return a / gcd(a, b) * b;
}
int main(void) {
int a, b;
printf("Two numbers: ");
scanf("%d %d", &a, &b);
printf("GCD = %d, LCM = %d\n", gcd(a, b), lcm(a, b));
return 0;
}Two numbers: 12 18
GCD = 6, LCM = 36gcd uses Euclid's algorithm: gcd(a, b) = gcd(b, a mod b), stopping when b is 0.
Library functions
C ships with many ready-made functions. Include the right header to use them:
| Header | Useful functions |
|---|---|
stdio.h |
printf, scanf, fgets, puts, fopen |
math.h |
sqrt, pow, fabs, ceil, floor, sin, log |
string.h |
strlen, strcpy, strcmp, strcat |
stdlib.h |
malloc, free, abs, rand, atoi, exit |
ctype.h |
isdigit, isalpha, toupper, tolower |
#include <stdio.h>
#include <math.h>
int main(void) {
printf("sqrt(144) = %.0f\n", sqrt(144));
printf("pow(2, 10) = %.0f\n", pow(2, 10));
printf("ceil(4.1) = %.0f, floor(4.9) = %.0f\n", ceil(4.1), floor(4.9));
printf("hypotenuse of 3,4 = %.1f\n", sqrt(3 * 3 + 4 * 4));
return 0;
}sqrt(144) = 12 pow(2, 10) = 1024 ceil(4.1) = 5, floor(4.9) = 4 hypotenuse of 3,4 = 5.0
Test yourself
4 questions · pick an answer to check it instantly
- 1
What is printed?
Cvoid f(int n) { n = n * 2; } int main(void) { int n = 4; f(n); printf("%d", n); }freceives a copy ofn. Doubling the copy does not changemain'sn. - 2
Why do we write a function prototype?
A prototype lets you call a function that is defined later in the file. - 3
What is the return type of a function that does not return a value?
voidmeans "returns nothing". - 4
In
int add(int a, int b), what areaandb?The variables named in the definition are formal parameters; the values passed in a call are actual parameters.