Functions

Functions

Function (subroutine, procedure): why?

  • Externalizing code ⟶ multiple use

  • Program structure

  • Readability

  • ⟶ Key to modularization

How?

  • No difference between function and procedure

  • Function call can be used as value (is an expression)

  • Except return type is void

A Nonsensical Example

#include <stdio.h>

int power(int base, int n)
{
    int p = 1;
    while (n--)
        p *= base;
    return p;
}

void main(void)
{
    int i;
    for (i = 0; i < 10; ++i)
        printf("2^%d = %d\n", i, power(2, i));
}

Function Signature

int power(int base, int n)
  • Function name (power)

  • Names and types of parameters

  • Return type

  • Parameters are local to function

  • Parameter names only relevant inside function

  • No conflicts with the outer world

  • ⟶ caller may use name base and i

Discussion

int p = 1;

Local variable

while (n--)
  • n--Post increment

  • Expression’s value is n’s value before increment

p *= base;

Shorthand for p = p * base;

return p;

Value of the function as seen by the caller

Definition vs. Declaration (1)

To generate a function call, the compiler wants to know its prototype ⟶ error checks

  • Number of parameters

  • Types of parameters

  • Return type

Historical baggage: implicit function declarations ⟶ best avoided using function declarations

  • -Wimplicit: warning issued when function called without declaration

  • -Werror: treat warnings as errors ⟶ hygiene

Definition vs. Declaration (2)

Declaration: declares prototype without giving a definition

int power(int base, int n);
“Dear compiler: I promise that the function will have this

prototype, please check”

  • Definition can be given later

  • … in the same file, after the call

  • … in a different file (⟶ later)

By Value / By Reference

Parameters are only passed by value

  • Function receives a local copy of the caller’s value

  • Modifications not visible to the caller

  • Pass by reference ⟶ pointers (later)

int power(int base, int n)
{
    while (n--) ...
}

Caller does not see modifications to n