Embedded Development Board Learning


Functions

Date: agosto 25, 2025

Author: Guillermo Garcia

Categories: Embedded C programming Tags:

In this article, we will look at the functions that are a fundamental pillar of C language programs for embedded systems.

Computer programs

Most computer programs are built to solve more complex problems than the ones we have treated so far. To develop a computer program for complex problems, it is good practice to divide the problem into smaller and more manageable sub-problems or modules. Then, for each of those modules, an algorithm must be written and translated into C code. To support this process of structured programming, C provides the concept of functions.

At least one function is always present in every C program: the main() function! A function in C is a block of code that performs a task and then returns control to a caller. It has its own name and can be called
from different places in the program. As such, functions can also be used to avoid repetition of code.

Standard functions

The C standard library provides a lot of functions that perform common mathematical calculations, string manipulations, input/output, and many other useful tasks. In this section, we will discuss only a few of these libraries. It is worthwhile to look into the full set of standard functions provided.

Like everything in C, functions need to be declared before they can be used in a program. The declarations of standard functions are grouped into header files (one header file per standard library). This is why we have included “” in all previous programs.

This header file contains the declarations of functions like printf(), scanf(), … The function definitions are inserted by the linker that will look for the correct definitions in the corresponding library. For the functions printf(), scanf() for instance, this will be the stdio library.

Other standard functions

Overview of the most commonly used functions of some standard libraries will be given.

Functions for string manipulations string.h

int strlen(char *s);
int strcmp(char *s, char *t);
int strncmp(char *s, char *t, int n);
char *strcpy(char *s, char *t);
char *strncpy(char *s, char *t, int n);

char *strcat(char *s, char *t);
char *strncat(char *s, char *t, int n);
char *strchr(char *s, int ch);

Functions for character handling ctype.h

int isalnum(int ch);
int isalpha(int ch);
int iscntrl(int ch);
int isdigit(int ch);
int isgraph(int ch);
int islower(int ch);
int isprint(int ch);
int ispunct(int ch);
int isspace(int ch);
int isupper(int ch);
int isxdigit(int ch);
int tolower(int ch);
int toupper(int ch);

Standard lib functions stdlib.h

double atof(char *s);
int atoi(char *s);
long atol(char *s);
exit(int status);
int system(char *s);
int abs(int n);
long labs(long n);
int rand(void);

Programmer-defined functions

Programmers can use self-defined functions to accomplish specific tasks that were not included in the standard libraries. Using self-defined functions is needed to split the problem in sub problems, to avoid code repetition and to be able to reuse code in different programs.
Every function can be described as a black box, that takes inputs or arguments and has a certain result or return value.

Function example in C

Like standard functions, also custom functions need a declaration and a definition. Some declaration needs to be written before the first function call and contains the function name and the types of the return value and parameters or inputs of the function:

return-value-type <function_name>(list of parameter types);

The function definition can be written anywhere in the code. The format of a function definition is:

return-value-type <function_name>(list of parameters + their types)
{
 statements;
}

Once the function declaration and definition are written, the function can be called from everywhere in the program. Like standard functions, custom functions are called using the function name followed by parenthesis. If arguments are to be passed on to the function, these arguments are put in between the parenthesis.

Void functions without parameters

Void functions are functions without return value. In its most general form,
a void function without parameters can be described as:

void <function_name>(void);

To indicate that there is no return value, the function name is preceded by the word void. Simply omitting a return-value-type will result in the assumption of an integer return value. As such, the word void before the function name is absolutely necessary to indicate that no return value will be present. In the same way, the word void is used in between the parenthesis following the function name to indicate that no parameters are needed.

Void functions with parameters

In many cases, the caller needs to pass information to the function. This is done by the use of function parameters that are written between parenthesis after the function name. These parameters can then be used as local variables inside the function. In the function definition, every parameter is given a name and type resulting in:

void <function_name>(type par1, type par2, …)
{
   statements;
}

The function declaration only contains the types of the different parameters:

void <function_name>(type, type, …);

When the function is called, the parameters in the function definition are replaced by real arguments. Every argument is an expression that is evaluated during the function call. The resulting argument value is then used to initialize the formal parameters.

Functions with return value

A function can also produce a result that needs to be given back to the function caller. This function result is called the functionreturn-value and is written before the function name in both the function declaration and the function definition.

Example

Write a program that reads a real base and a non-negative integer exponent and calculates the exponentiation.

#include <stdio.h>
double exponentiation(double, int); /* function declaration */

int main(void)
{
 double a, m;
 int n;
 printf("Exponentiation \n");
 printf("Enter base: ");
 scanf("%lf%*c", &a);
 printf("Enter (non-negative) exponent: ");
 scanf("%d%*c", &n);
 m = exponentiation(a, n); /* function call */
 printf("The result is %16.8f \n", m);
 return 0;
 }

 /* function definition */
 double exponentiation(double base, int exponent)
{
 double result = 1.0;
 int i;
 for (i = 0; i<exponent; i++)
{
 result *= base;
}
 return result;
}

Output:

Exponentiation
Enter base: 2
Enter (non-negative) exponent: 3
The result is 8.000000

The statement “return result;” inside the function exponentiation, returns the result to the function main where exponentiation was called. In this example, this result is assigned to the variable m.

Storage classes and scope of variables

Every variable has its own storage class and scope. The storage class indicates how long a variable remains valid while the scope gives information on where the variable can be accessed.

Storage class auto – local variables

Auto variables have automatic storage duration, meaning that they will be created upon entrance of the block in which they are defined, exist while the block is active and are destroyed when that block is exited.
The scope of these variables is local to the block in which they are defined.


No block outside the defining block has direct access to automatic variables! These variables may be declared with the keyword auto but this is not mandatory. If no storage class is written, the class auto is used as well. As such, if no keyword is added, the variables defined in a function have a scope local to this function!

Storage class extern – global variables

External variables have static storage duration, meaning that memory will be allocated when the program execution starts and will remain allocated until the program terminates.

An example of external variables are global variables. These variables are created by placing the variable declaration outside any function. In this case, the keyword extern does not need to be added. The variable will be external by default.

The scope of global variables is the entire source code following the declaration. If these variables are not initialized in the declaration, they will be initialized to zero automatically.

The next program demonstrates the difference between local and global variables. Note that, when entering the function, the local variable a belonging to the function has priority over the global variable a. Since the variable b is not declared inside the function, every calculation or assignment done with that variable, refers to the global variable b.

int a, b; /* global variables */
void f(void); /* function declaration */

int main(void)
{
 a = 5;
 b = 7;
 printf("in the main function a = %d and b = %d \n", a, b);
 f();
 printf("after the function call a = %d and b = %d \n", a, b);
 return 0;
}

void f(void)
{
 int a; /* local variable, the global var “a” is invisible */
 a = 15;
 b = 17;
 printf("in the function a = %d and b = %d \n", a, b);
}

Output:

in the main function a = 5 and b = 7
in the function a = 15 and b = 17
after the function call a = 5 and b = 17

Storage class register

This is a special case of the storage class auto. If the word register is written in front of a variable declaration, it suggests the compiler to allocate an automatic variable in a high-speed CPU-register, if possible. Of course, this only makes sense if speed is of outmost importance for that variable.

#define LIMIT 1000

int main(void)
{
 register int i; /* local variable of type register*/
 for (i = 0; i<LIMIT; i++)
 {
   printf("%8d", i);
 }

 return 0;
}

Storage class static

Like variables of the storage class extern, also static variables have a static storage duration, meaning that memory will be allocated when the program execution starts and will remain allocated until the program
terminates.

The scope of these variables is often (but not necessary) limited! If a static variable is defined in a block, the scope of that variable is identical to the scope of automatic variables. Therefore, the variable will keep on existing after the execution of the code block, but none of the other code blocks can access that variable. Static variables are initialized only once!

void f(void);

int main(void)
{
 f();
 f();
 f();
 return 0;
}

void f(void)
{
 static int i = 5; /* static variable (local to function f) */
 printf("i = %d \n", i);
 i++;
}

Output:

i = 5
i = 6
i = 7

Summary

summary functions in C


Card image cap
Guillermo Garcia Thanks for reading! I am one of the editors of this site and I am committed to providing you with the best information possible by sharing my experience in embedded systems.


Comments... There are no comments.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Publicidad