Skip to content
Laviyx Learn

Try

C course menu

Functions in C: Declaration, Definition, Prototypes and Calling

Learn functions in C: defining and calling functions, return types and void, function prototypes (declarations) and why they matter, the order of functions in a file, and how to design small, reusable functions.

Beginner7 min readUpdated
On this page

A function is a named block of code that performs one task. You have already used library functions such as printf. Writing your own lets you split a program into small, reusable, testable pieces.

Defining and calling a function#

C
#include <stdio.h>

double area_of_rectangle(double width, double height) {
    return width * height;
}

int main(void) {
    double a = area_of_rectangle(4.0, 2.5);
    printf("Area: %.2f\n", a);
    printf("Another: %.2f\n", area_of_rectangle(3, 3));
    return 0;
}
Output
Area: 10.00
Another: 9.00

A function definition has four parts:

PartExample
Return typedouble
Namearea_of_rectangle
Parameters(double width, double height)
Body{ return width * height; }

return sends a value back to the caller and ends the function.

void functions#

A function that returns nothing has the return type void. A function that takes no parameters should be written with (void):

C
#include <stdio.h>

void print_line(void) {
    printf("--------\n");
}

void greet(const char *name) {
    printf("Hello, %s!\n", name);
}

int main(void) {
    print_line();
    greet("Asha");
    print_line();
    return 0;
}
Output
--------
Hello, Asha!
--------

In C, void f() (empty parentheses) is not the same as void f(void): before C23 it means "unspecified parameters", which turns off argument checking. Always write (void).

Prototypes: declaring before use#

The compiler reads a file from top to bottom. To call a function that is defined later, declare it first with a prototype: the function's header followed by a semicolon:

C
#include <stdio.h>

int square(int n);              /* prototype (declaration) */

int main(void) {
    printf("%d\n", square(12));
    return 0;
}

int square(int n) {             /* definition */
    return n * n;
}
Output
144

The prototype tells the compiler the function's name, return type and parameter types, so it can check every call. In larger programs, prototypes go in header files (.h), which other files #include (Header Files and Multi-file Programs).

Calling a function with the wrong argument count is then a compile error:

C
int square(int n);

int main(void) {
    return square(1, 2);
}

int square(int n) {
    return n * n;
}

GCC reports error: too many arguments to function 'square'.

Functions calling functions#

C
#include <stdio.h>

double with_gst(double price) {
    return price * 1.18;
}

double order_total(double unit_price, int qty) {
    return with_gst(unit_price * qty);
}

int main(void) {
    printf("%.2f\n", order_total(250.0, 3));
    return 0;
}
Output
885.00

Designing good functions#

  • One task per function: read_marks, average, print_report rather than one large main.
  • Descriptive names, usually verbs: calculate_tax, is_valid_pin.
  • Return results rather than printing inside the function, so the caller decides what to do.
  • Keep functions short enough to read at a glance.

Practice#

Practice exercise

Write int max3(int a, int b, int c) that returns the largest of three numbers, and int is_even(int n) that returns 1 or 0. Declare both with prototypes above main, define them below it, and test them.

Show solution
C
#include <stdio.h>

int max3(int a, int b, int c);
int is_even(int n);

int main(void) {
    printf("%d\n", max3(7, 19, 4));
    printf("%d %d\n", is_even(10), is_even(7));
    return 0;
}

int max3(int a, int b, int c) {
    int m = a;
    if (b > m) m = b;
    if (c > m) m = c;
    return m;
}

int is_even(int n) {
    return n % 2 == 0;
}
Output
19
1 0

Key takeaway#

Finished this lesson?