Functions

Functions allow the C programmer to extend the language by writing your own functions which are syntactically just like the C Standard Library functions, print() for example. Every C program has at least one function that is named main(). Functions must be declared before they are referenced, just like variables must be declared before they are referenced.

Functions return either nothing or one value. For example, a function can return either nothing or one integer, it cannot return two integers. If a function is declared to return a value, the the function must have return statement that returns a value of the declared data type.

Functions take from zero to many parameters. If a function is declared to take two parameters, then two parameters must be passed each time the function is called.

Nothing  |  Return  |  Pass  |  Change  |  Scope  |  Pointers

Nothing functions

Nothing functions take no parameters and return nothing. The keyword void is used to signify nothing. In this example MyFirstFunction() is declared with the statement void MyFirstFunction(void); with the actual function appearing after main().

#include <stdio.h>

void MyFirstFunction(void);

int main(int argc, char *argv[])
{
  MyFirstFunction();
  return 0;
}

void MyFirstFunction(void)
{
  printf("This is my first function\n");
}
Top

Return a value

Here is a trivial program with a function that returns an integer, which is coded just like main() which also returns an integer. The int before ReturnInteger(void); declares function ReturnInteger as: a function that returns an integer.

#include <stdio.h>

int ReturnInteger(void);

int main(int argc, char *argv[])
{
  int ReturnValue;
  
  ReturnValue = ReturnInteger();
  printf("The value return is: %d", ReturnValue);
  printf("\n");
  return 0;
}

int ReturnInteger(void)
{
  return 737;
}

Return a single character.

#include <stdio.h>

char ReturnCharacter(void);

int main(int argc, char *argv[])
{
  char ReturnValue;
  
  ReturnValue = ReturnCharacter();
  printf("The value return is: %c", ReturnValue);
  printf("\n");
  return 0;
}

char ReturnCharacter(void)
{
  return 'k';
}

Return a floating point number. Your compiler may complain about the statement GrossPay = 473.52; with a warning like this:

warning '=' : truncation from 'const double' to 'float'
For the purpose of this example, that warning can be ignored.

The %3.2f in the prinf() statement formats the floating point number as 3 digits to left of the decimal point and 2 digits to the right of the decimal point.

#include <stdio.h>

float ReturnFloat(void);

int main(int argc, char *argv[])
{
  float ReturnValue;
  
  ReturnValue = ReturnFloat();
  printf("The value return is: %3.2f", ReturnValue);
  printf("\n");
  return 0;
}

float ReturnFloat(void)
{
  float GrossPay;

  GrossPay = 473.52;
  return GrossPay;
}
Top

Passing values

One or more values can be passed to a function. When a function is declared, the data type and variable name is declared for each value to be passed.

Passing variables in this manner is referred to as passing by value.

#include <stdio.h>

void PrintAnInteger(int IntegerToBePrinted);

int main(int argc, char *argv[])
{
  int Count;
  
  Count = 7;
  PrintAnInteger(Count);
  Count = 52;
  PrintAnInteger(Count);
  return 0;
}

void PrintAnInteger(int IntegerToBePrinted)
{
  printf("The integer is: %d", IntegerToBePrinted);
  printf("\n");
}

This example has a function that accepts two values: a single character and an integer.

#include <stdio.h>

void PrintTwo(char CharacterToBePrinted, int IntegerToBePrinted);

int main(int argc, char *argv[])
{
  char OneCharacter;
  int  Count;
  
  OneCharacter = 'f';
  Count = 7;
  PrintTwo(OneCharacter, Count);
  OneCharacter = 'z';
  Count = 52;
  PrintTwo(OneCharacter, Count);
  return 0;
}

void PrintTwo(char CharacterToBePrinted, int IntegerToBePrinted)
{
  printf("The character is: %c", CharacterToBePrinted);
  printf("\n");
  printf("The integer is: %d", IntegerToBePrinted);
  printf("\n");
}
Top

Changing a value

To permanently change the value of a variable that is passed to a function, you must use pointers. Without pointers, the value of a variable can be passed to a function and changed within the called function, but upon returning from the called function, the value of the variable which was passed will remain unchanged.

This program WILL NOT change the value of Count permanently.

#include <stdio.h>

void ChangeIt(int Count);

int main(int argc, char *argv[])
{
  int Count;

  Count = 123;
  printf("Count 1st time is: %d\n", Count);
  ChangeIt(Count);
  printf("Count 3rd time is: %d\n", Count);
  return 0;
}

void ChangeIt(int Count)
{
  Count = 456;
  printf("Count 2nd time is: %d\n", Count);
}

The variable Count in main() and the variable Count in ChangeIt() are not the same variable. They are, obviously, named the same, but they are two totally different variables. The variable Count in ChangeIt() gets its initial value from Count in main(), but any connection between the two Counts ends there.


This program WILL change the value of Count permanently. The line void ChangeIt(int *pCount); means that ChangeIt() is expecting the address of an integer variable to be passed to it. The line ChangeIt(&Count); passes the address of Count to ChangeIt(), as expected. The line *pCount = 456; dereferences pCount, then assigns 456.

Passing variables in this manner is referred to as passing by reference.

In this program, these two statements refer to the exact same 4 bytes of memory which contain the value of the integer variable named Count:

  1. Count = 123;
  2. *pCount = 456;

#include <stdio.h>

void ChangeIt(int *pCount);

int main(int argc, char *argv[])
{
  int Count;

  Count = 123;
  printf("Count 1st time is: %d\n", Count);
  ChangeIt(&Count);
  printf("Count 3rd time is: %d\n", Count);
  return 0;
}

void ChangeIt(int *pCount)
{
  *pCount = 456;
  printf("Count 2nd time is: %d\n", *pCount);
}
Top

Variable scope

A concept that is critical to understanding C is variable scope. Variables can have a scope of either global or local.

The scope of a global variable is: all functions can refer to or change it. Global variables are declared by placing the declaration outside the body of a function.

The scope of a local variable is: only the function in which the variable is declared can refer to or change it. Also, each time a function is executed, the value of each local variable is undefined and must be initialized before being used. Local variables are delcared by placing the declaration inside the body of a function.

The question of using global variables or not using global variables has caused many heated discussions. Just as with numerous other hot topics in the world of programming, the wise programmer will weigh the arguments and decide the appropriate use of global variables on a program by program basis and ensure that the resulting code is easy to understand, maintain, and debug.

This example is functionally identical to the previous example (the one that changes Count permanently). In this case, variable Count is replaced with variable GlobalCount, a global integer variable.

#include <stdio.h>

int GlobalCount;

void ChangeIt(void);

int main(int argc, char *argv[])
{
  GlobalCount = 123;
  printf("Count 1st time is: %d\n", GlobalCount);
  ChangeIt();
  printf("Count 3rd time is: %d\n", GlobalCount);
  return 0;
}

void ChangeIt(void)
{
  GlobalCount = 456;
  printf("Count 2nd time is: %d\n", GlobalCount);
}
Top

Changing passed pointers

Passing a pointer variable to a function is just like passing an integer variable, but changing a passed pointer is a little weird. First, a simple program to demostrate passing a pointer variable to a function.

#include <stdio.h>

void PassPointer(int *pEmployeeNumber);

int main(int argc, char *argv[])
{
  int   EmployeeNumber;
  int *pEmployeeNumber;

  pEmployeeNumber = &EmployeeNumber;
  PassPointer(pEmployeeNumber);

  return 0;
}

void PassPointer(int *pEmployeeNumber)
{
  printf("The value of pEmployeeNumber is: %x\n", pEmployeeNumber);
  *pEmployeeNumber = 309;
  printf("The value of EmployeeNumber is: %d\n", *pEmployeeNumber);
}

In order to change a pointer variable, you must use a 'pointer to a pointer'. In the Change section of this page, you learned that in order to change a variable that is passed to a function you had to pass the variable using pointers. This is the same, except in this case the variable being passed is a pointer.

Dereferencing a pointer to a pointer yields an address. To get to the actual variable, you must derefernce the pointer twice.

Here the above code is modified to set the pEmployeeNumber pointer to NULL before returning from PassPointer(). The changes to the code are highlighted in red.

#include <stdio.h>

void PassPointer(int **pEmployeeNumber);

int main(int argc, char *argv[])
{
  int   EmployeeNumber;
  int *pEmployeeNumber;

  pEmployeeNumber = &EmployeeNumber;
  PassPointer(&pEmployeeNumber);
  printf("The value of pEmployeeNumber is: %x\n", pEmployeeNumber);

  return 0;
}

void PassPointer(int *pEmployeeNumber)
{
  printf("The value of pEmployeeNumber is: %x\n", *pEmployeeNumber);
  **pEmployeeNumber = 309;
  printf("The value of EmployeeNumber is: %d\n", **pEmployeeNumber);
  *pEmployeeNumber = NULL;
}
Top