Overview of the Use of Functions in C/C++


Overview of the Use of Functions in C/C++


In C/C++, statements are grouped within functions. Good programming style dictates that each individual function should be relatively “simple,” meaning that it should accomplish a given task without requiring too much code. If a function contains many lines of code that perform multiple tasks, it would probably be best to divide this code into multiple functions. Functions can call other functions, meaning that one function can use other functions to accomplish the task it is intended to perform. We want to use a modular approach with relatively short functions, rather than having large, monolithic functions. This approach facilitates debugging and code reuse (i.e., if a function accomplishes a given task and is known to be bug-free, we can easily use that function in another sketch).

You may already be familiar with the concept of a function from your math classes. In C/C++, functions share some characteristics with the functions you've seen in math, but the functions in C/C++ are more general. In math, a function is called to perform a particular computation. The function has arguments that can be thought of as the inputs to the function, and the function returns a value based on the values of these arguments. Here are some examples of math functions:

\[\begin{array}{l}f(x) = x + 3,\\g(a,b) = \frac{{a + b}}{{a \times b}},\\h(u,v,w) = 10 \times f(u + v) \times g(v,w).\end{array}\]

The first function $f$ returns the sum of the argument $x$ and $3$. Keep in mind that $x$ is just a placeholder. We have to provide an actual value to perform a calculation. For example, we might write $f(11)$ where we are dictating that $x$ should be assigned the value $11$. Then the computation is the sum of $11$ and $3$, so the function “returns” $14$.

The second function $g$ has two arguments and returns the sum of the arguments divided by their product. The third function $h$ has three arguments and performs a computation that uses the functions $f$ and $g$.

In C/C++ we can write functions that behave essentially the same way as these math functions. Functions have a “name,” they accept any number of arguments, and they can return a value. However, unlike math functions, in C/C++ a function is sometimes called for its side effects. For example, a side effect might be that something is written to a file. Or, the side effect of a function might be that an LED is blinked in a certain pattern. In these cases it may not be necessary for the function to return a value.

There are a large number of functions already available for our use when we program in C/C++. Furthermore, in MPIDE, there are additional functions available that are designed to facilitate interactions with the chipKIT™ board. On top of this, we can write our own functions as part of a sketch. In fact, every sketch requires that we provide two functions as described below.

To create a function of our own, we must provide the four separate parts shown in the template in Fig. 1. We start by specifying the type of thing the function returns, i.e., we specify the return type. If the function doesn't return anything, the return type is void (we will consider non-void return types later and won't discuss this topic further here).

Figure 1. Template for the creation of a function.

The return type is followed by the function's name. The rules that govern valid function names are:

  1. The name can consist of any combination of letters, digits, and the underscore character.
  2. The name must not start with a digit.
  3. The name cannot conflict with a keyword (which are words that are reserved because they have meaning within the language, such as void). A list of keywords in C++ is available via the tab to the right.

Following the name, and enclosed in parentheses, is the argument list. Some functions do not take any arguments, in other words, they are not provided any input data. Nevertheless, these parentheses must always be present. Like math functions, functions in C/C++ can accept any number of arguments. Arguments are separated by commas.

Finally, following the argument list is the body of the function. The body contains all the code (statements) associated with the function and is enclosed in braces ({ and }). Code enclosed in braces is known as a block of code.

In Fig. 1, this particular function is named setup(). Because it does not return anything, its return type is void. This function takes no arguments and hence the parentheses following the name are empty. We have used an ellipsis as a stand-in for the statements that would appear in the body of the function.

The following code defines two functions. The first, given on lines 2 through 7, does nothing. It accepts no arguments and its body is empty (other than comments). Although this is a useless function, it is nevertheless a valid function as it provides all the necessary components of a function. The second function, on lines 13 through 19, is more complicated so we will merely say that this function returns an integer value (i.e., an int) and takes an integer argument that is called bar. To return something from a function, one must use a return statement which appears in line 18 of this function (return is another keyword that cannot be used for the name of a function).

                    // Input nothing and return nothing.
                    void do_nothing()
                      // Returning nothing,
                      // because this is a
                      // void function.
                    /* Function that accepts an integer argument
                       and return an integer.  The type of the argument
                       must be specified in the argument list together 
                       with the argument's name.  */
                    int foo(int bar)
                      // Increment the given argument by one.
                      bar = bar + 1;
                      // Return the incremented value.
                      return bar;

To execute the statements in a function, we call it. We may also say we invoke it, run it, or execute it. To do this we simply write the function name, together with its actual arguments (enclosed in parentheses), at the point in our sketch where we want the function to be executed. After the function has run, execution resumes from the point where the function was called. If we call a function that takes no arguments, we must still provide the parentheses following the name, but the parentheses will not contain anything.

Important Points:

  • Functions must have a return type, a name, an argument list, and a body.
  • If a function does not return a value, its return type is void.
  • The function name can consist of letters, digits, and the underscore character but cannot start with a digit or correspond to a keyword.
  • The argument list is used to pass information into the function and may be empty.
  • The body of a function is a block of code, i.e., code enclosed in braces.
  • A return statement is used to specify the information that a function returns.

  • Other product and company names mentioned herein are trademarks or trade names of their respective companies. © 2014 Digilent Inc. All rights reserved.