Fundamental C - Functions
Written by Harry Fairhead   
Monday, 19 March 2018
Article Index
Fundamental C - Functions
Void, Pass-by-Value

You can't get far in creating C programs without using functions. The good news is that in C functions are simple and efficient and there is no reason not to use them. In this chapter we look at functions, parameters, pass-by-value, return values, prototypes, local and global variables.

Fundamental C: Getting Closer To The Machine

Now available as a paperback and ebook from Amazon.

  1. About C
      Extract Dependent v Independent
                  & Undefined Behavio
  2. Getting Started With C Using NetBeans
  3. Control Structures and Data
  4. Variables
      Extract Variables
  5. Arithmetic  and Representation
      Extract Arithmetic and Representation
  6. Operators and Expression
      Extract: Expressions
      Extract Side Effects, Sequence Points And Lazy Evaluation
      First Draft of Chapter: Low Down Data
  7. Functions Scope and Lifetime
  8. Arrays
      Extract  Simple Arrays
      Extract  Ennumerations
  9. Strings
      Extract  Simple Strings
     
    Extract: String I/O ***NEW!!
  10. Pointers
      Extract  Starting Pointers
      Extract  Pointers, Cast & Type Punning
  11. Structs
      Extract Basic Structs
      Extract Typedef
  12. Bit Manipulation
      Extract Basic Bits
      Extract Shifts And Rotates 
  13. Files
     Extract Files
     
    Extract Random Access Files 
  14. Compiling C – Preprocessor, Compiler, Linker
     Extract Compilation & Preprocessor

Also see the companion volume: Applying C

<ASIN:1871962609>

<ASIN:1871962463>

<ASIN:1871962617>

<ASIN:1871962455>

 

Cbookcover

 

C is a very small language in the sense that it has very few pre-defined keywords. Many of the things that you use in C are provided by libraries of functions. For example, C doesn't have a print command it makes use of the printf function provided by the stdio library. As we will discover functions can be added and existing functions modified and this makes C a more powerful language.

Now we need to discover what a function is exactly and how to create one.

What Is A Function

A function is just a collection of C instructions that you can execute by simply using the functions name. For example, printf is a function and it is comprised of quite a few lines of C statements. You can call up those lines of C by simply typing printf. In this sense you have already been using functions since your first C program.

A function is a block of C code that you give a name. We already know how to create a block of C code you simply write it between curly brackets - a compound statement. A function assigns a name to this block of code using the syntax:

functionName(){ block of code}

For example, if you start a new C99 project and following main enter:

hello(){
    printf("Hello Function World");
}

This defines a function called "hello" which simply prints to the console the message.

You can use the function by typing its name followed by parentheses:

hello();

You can think of this as transferring control to the start of the function which then executes each instruction to the last instruction when the part of the program that called the function is resumed.

The entire program is:

hello(){
    printf("Hello Function World");
}

int main(int argc, char** argv) {
    hello();
    return (EXIT_SUCCESS);
}

If you run this you will see the message displayed in the console.

Notice that you have to place the hello function before the main program because functions have to be defined before they are used.

Why Functions?

You can see that this is a powerful idea. You have effectively added a new command to C - the hello command.

This idea of extending the language by writing functions is a basic approach to creating larger programs.

In top down programming you write functions that do big things by calling other functions that do smaller things by calling other functions that do even smaller things - until the program is complete.

In bottom up programming you write small functions that might be useful and then use them to build functions that do bigger things by using them and so on up to the final program.

Most programmers thing that top down is the right way to go because it is easier to see what you need at each level.

Of course you don't need functions. You can write your program as a single block of basic C instructions. However trying to work out what this monolithic bock of code does when you come back to it after even a few hours can be very difficult. Splitting a program up into small functions makes it much easier to understand and this is called modular programming. Your program shouldn't be one huge chunk of code it should be made of modules each one doing a clear and understandable job. In C functions are your modules.

Of course there is always the efficiency objection.

Using a function is slower than just writing the instructions because the flow of control has to transfer to the function and then back again to the program that called the function. There is an overhead in calling a function but it is small enough to be ignored in most situations. Of course there are time when developing programs on small devices that you need every drop of performance. Even in this situation it is still worth using functions unless you are forced not to.

Thinking in functions should be your default that you only give up when efficiency forces you to.

Parameters

You might have been wondering what the parentheses are for in the definition of a function? The answer is that you can include parameters that the calling code and use to tell the function what to do. For example:

hello(int times) {
    for (int i = 0; i < times; i++) {
        printf("Hello Function World \n");
    }
}

 

You can see the intent here. The function has an integer parameter, times which is used in the for loop to repeat the message that number of times. The \n at the end is the symbol for a newline and this separates our messages onto separate lines.

To use the function in its new form you would write:

hello(3);

to display the message three times.

What happens is as if a new variable has been created and set to 3 within the function i.e. as if:

int times=3;

was the first instruction in the function.

This is a completely general mechanism and you can pass in multiple parameters to a function each one separated by a comma.

For example

add(int a, int b) {
    int c = a + b;
    printf("%d", c);
}

This adds the two specified parameters together and prints the result. You call the function using:

add(1,2);

which displays 3 on the console.

Return Values

Parameters are ways of getting values into functions. There is also a way of getting a result out of a function - its return value. If you write

return value;

in a function it terminates and the value specified is returned.

What does "returned" mean?

A function that has a return value can be used in an expression and assigned to a variable.

So for example is you change the add function to:


add(int a, int b) {
    int c = a + b;
    return c;
}

then it now returns the sum of a and b i.e. the value stored in variable c.

You can now use the add function and the value it returns:

int ans = add(1, 2);
printf("%d",ans);

which prints the value 3.

It is as if add was a variable that had its value determined by the return value of the function.

Notice that while you can send multiple inputs into a function i.e. use multiple parameters, there can only be a single return value. This can cause problems but it is easy enough to over come this limitation.

There is a small complication. Notice that we have to specify the type of the parameters but the return type isn't specified at all. In fact if you don't specify a return type then the compiler (in C99) assumes that the value is an int. In general you should always specify the type of the return value by prefixing the function name with a type.

So the add function should be more properly defined as:

int add(int a, int b) {
    int c = a + b;
    return c;
}

Now we have a function that accepts two ints and returns an int and it is used exactly as it was before. The advantage of typing the parameters and the return value is that the compiler can check that you are working with the right type of data and flag an error if you try to do something silly.

As long as a function returns a value of the correct type it can be used within an expression as if it was a variable of that type.

For example:

int ans=add(1,2)*2;

will store 6 in ans.



Last Updated ( Tuesday, 11 September 2018 )