A Simple Makefile

Makefiles are a simple way to organize code compilation. This tutorial does not even scratch the surface of what is possible using make, but is intended as a starters guide so that you can quickly and easily create your own makefiles for small to medium-sized projects.

A Simple Example

Let’s start off with the following three files, hellomake.c, hellofunc.c, and hellomake.h, which would represent a typical main program, some functional code in a separate file, and an include file, respectively.

hellomake.c hellofunc.c hellomake.h
#include 

int main() {
  // call a function in another file
  myPrintHelloMake();

  return(0);
}
#include 
#include 

void myPrintHelloMake(void) {

  printf("Hello makefiles!\n");

  return;
}
/*
example include file
*/

void myPrintHelloMake(void);

Normally, you would compile this collection of code by executing the following command:

gcc -o hellomake hellomake.c hellofunc.c -I.

This compiles the two .c files and names the executable hellomake. The -I. is included so that gcc will look in the current directory (.) for the include file hellomake.h. Without a makefile, the typical approach to the test/modify/debug cycle is to use the up arrow in a terminal to go back to your last compile command so you don’t have to type it each time, especially once you’ve added a few more .c files to the mix.

Unfortunately, this approach to compilation has two downfalls. First, if you lose the compile command or switch computers you have to retype it from scratch, which is inefficient at best. Second, if you are only making changes to one .c file, recompiling all of them every time is also time-consuming and inefficient. So, it’s time to see what we can do with a makefile.

The simplest makefile you could create would look something like: Continue reading

The Main Function

In C, the “main” function as every function, has a return type (and in some cases accepts inputs via parameters). The only difference is that the main function is “called” by the operating system when the user runs the program. Thus the main function is always the first code executed when a program starts.

Example: A program that accepts two inputs and displays the greates. Save it as “main.c” after compilation run it as “main.exe  1   2”.

#include <stdio.h>
int main(int argc, char *argv[]){/* Accept parameter with main */

        //call the max function, if main has accepted two parameters
      if(argc >= 2)
          max(argv[1], argv[2]);
return 0;
}

int max(char *a, char *b){
     if(a > b)
         printf("%s\n",a);
     else
         printf("%s\n",b);
return 0;
}

Output:
2

Return statement and return types

Return statement

A function may or may not return a value. A return statement returns a value to the calling function and transfers control to the calling function by terminating execution of the current function. If a function does not return a value, the return type in the function definition and declaration is specified as void.

Return Type

The return type of a function defines the size and type of the value returned by a function.

The following are return types that a C function can use:

  • int — 16, 32, 64 bits
  • short – 16
  • long – 32
  • long long – (not all compilers see this as a valid type).
  • float
  • double
  • long double

Function Prototypes

All functions in C need to be declared before they are used as it applies to variables and identifiers. For functions the declaration needs to be before the first call of the function. A full declaration includes the return type and the number and type of the arguments.

Function prototypes: are declaration of functions before the function is actually called.

Having the prototype available before the first use of the function allows the compiler to check that the correct number and type of arguments are used in the function call and that the returned value, if any, is being used properly.

The function definition itself can act as an implicit function declaration. This was used in the below example and was why sum was put before main. If the order was reversed the compiler would not recognize sum as a function.

Example 1. A simple program with a function prototype

#include <stdio.h>    
    int sum (int, int); /* Function prototype. */   

    int main (void)
    {
        int total;
    
        total = sum (2, 3);
        printf ("Total is %d\n", total);
    
        return 0;
    }
    
    int sum (int a, int b)
    {
        return a + b;
    }

Continue reading

2. Function declaration

A function declaration tells the compiler about a function’s name, return type, and parameters.

Note: A function declaration must come before function definition.

A function declaration has the following parts:

return_type function_name( parameter list );

For the above defined function max(), the following is the function declaration:

int max(int num1, int num2);

The parameter names can be omitted that finally yield

int max(int , int);

The C standard library provides numerous built-in functions that your program can call. For example, function strcat() to concatenate two strings, memcpy() to copy one memory location to another location and many more functions. A function is known with various names like a method or a sub-routine or a procedure, etc.

4. Functions

A function is a group of statements that together perform a task. Every C program has atleast one function, which is main() where execution starts from, and additional functions(if needed).

You can divide up your code into separate functions. How you divide up your code among different functions is up to you, but logically the division usually depends on what the function is intended to perform(specific task).

When using functions, there are two things that every function should have. These are:

  1. Function declaration and
  2. Function definition
  1. Function definition

A function definition provides the actual body of the function. The general form of a function definition in C is as follows:

return_type function_name(parameter list )
  {
     body of the function
     return value; /* no return value if return_type is void  */
  }

A function definition consists of a function header and a function body. Here are all the parts of a function: Continue reading