Discover the basic concepts of the C programming language and gain confidence in understanding and using it. 

C is considered an older programming language, but due to its speed, is still widely used today, especially in system programming and embedded environments. 

This introductory guide will provide a head start in understanding and using C programming code. 

For a guide to the most popular C programming language concepts, check out our Getting Started with C article. In this particular guide, we'll be focusing on the basic constructs of the language. 

Variables

A minimal variable declaration must consist of the type and name. C is a strongly typed language, so the type can't be changed later on. 

Also, C isn't object-oriented, which means that variables lack an access modifier. They can, however, be marked as static or as constants: 

        [static] [const] data_type variable_name [= value];
    

The static keyword doesn't mean that a variable belongs to a class rather than an object of the class (remember: C is not object-oriented!) 

It means that the variable is valid in a global scope (rather than a function). 

For example:

        #include <stdio.h>

int declare()
{
	static int global_count = 0;
	global_count++;
    
	printf("%d\n", global_count);
}

int main()
{
	declare();
	declare();
	declare();

	return 0;
}
    

This code will print numbers from one to three. 

Note: The variable is only initialized once and it retains its value throughout the program. 

Besides other effects, static variables (and methods) are only visible to the class itself (more precisely, the same compilation unit) and cannot be accessed outside of it. 

Methods in C

A minimal method declaration consists of its name. 

The return type of a minimal method isn't explicitly defined and neither are the parameters and it will, therefore, accept any parameters and might return any value (even though the implicit default return type is an integer).

You should always define a return type (use void if your function doesn't return a value), and it will, therefore, accept any parameters and might return any value. 

You should always define a return type (use void if your function doesn't return a value), and also the parameters of a method (use void to define an empty parameter list). 

Additionally, methods can be marked as static. 

Some examples:

        // Will accept any number of parameters
// and might return anything
// Not recommended!
voidfunc()
{
	return -1589430;
}

void no_return_no_parameters(void)
{
	// Do something
}

static int function(int param1, int param2)
{
	return param1 + param2;
}

int main()
{
	int ret = voidfunc("test", 29, 0, -1, "anything");
	int sum = function(10, 14);
    
	no_return_no_parameters();
    
	printf("%i\n", ret);
	printf("%i\n", sum);

	return 0;
}
    

Pointers and Arrays

You can declare and de-reference a pointer in C using an asterisk. To get the address, use an ampersand as demonstrated below:

        int year = 2018;
int month = 12;

// Pointer declaration
int *pointer = NULL;
    
// Make the pointer point at the address of
// the year-variable and assign a new value
// directly to the address
pointer = &year;

// De-reference the pointer to change the value
// stored at the address the pointer points at
*pointer = 2019;
    

Arrays can be defined by using square brackets. 

In C, arrays have a fixed type and length: 

        char* months[12] = {"JAN", "FEB", "MAR", "APR",
                    	"MAY", "JUN", "JUL", "AUG",
                    	"SEP", "OCT", "NOV", "DEC"
};
    

Pointers are often used with arrays to quickly access certain elements. Elements can also be accessed using their index: 

        // Print the third month (Indices start with 0)
printf(“%s\n”, months[2]);
    

Structs

Because C isn't object-oriented, it can be tricky to represent coherent values that aren't separated. However, using structs is a great method to use for this purpose since they define variables that belong together: 

        struct Tree
{
	float height;
	int year_planted;
	char* fruit;
};
    

You can then create a pointer for the struct, allocate memory for it, and define the values:

        struct Tree* appleTree = malloc(sizeof(struct Tree));
    
appleTree->height = 3.2f;
appleTree->year_planted = 1999;
    
appleTree->fruit = malloc(sizeof(char) * 6);
appleTree->fruit = "Apple";
    

The values can then be used the same way:

        printf("This tree bears %ss ", appleTree->fruit);
printf("and it is %f meters high!\n", appleTree->height);
    

After you're done using the struct, make sure to free the allocated memory! 

Control Structures 

If statements allow you to define alternate paths depending on whether a value evaluates to true or false:

        if(sum == 24)
{
    printf("Sum is 24!\n");
}
else if(sum < 24)
{
    printf("Sum is less than 24!\n");
}
else
{
    printf("Sum is greater than 24!\n");
}
    

The else if and else blocks are optional. The switch-statement is an alternative way of checking for a larger range of possible values. 

        switch(sum)
{
    case 0:
        	printf("Sum is 0\n");
        	break;
       	 
    case 24:
        	printf("Sum is 24\n");
        	break;
       	 
    default:
        	printf("Sum is anything else\n");
        	break;
}
    

The default block is optional and the code is executed when another case isn’t matched. 

The breaks aren’t necessary, but they enable the program to step out of the switch statement after the first case matches.

For- and While- Loops

For- loops can be used to repeat code a fixed number of times. You typically have to define a starting value, ending condition, and an action that's repeated after each iteration.

However, any of these instructions can be omitted.

Some examples:

        // Start counting at zero
// Condition: start is less than 65
// Increment start after each iteration by one
for(int start = 0; start < 65; start++)
{
    // Do something
}
    
// while-like behaviour
int flag = 1;
for(; flag != 0; )
{
    // Do something
    // After you're done: set flag to 0
    flag = 0;
}
    
// endless loop (while(true)-like behaviour)
for(;;)
{
    // Do something
    // Use break after you're done to end the loop
    break;
}
    

The code inside of a while-loop will always be executed, as long as the condition defined in the loop’s head, is true. 

        // The same as the second for-loop from above
int flag = 1;
while(flag != 0)
{
    // Set the flag to zero after you're done
    // to prevent an infinite loop
    flag = 0;
}
    

Writing to the Console 

 To write for the console, use the printf()-command, which stands for print formatted. 

Since we’re unable to can’t connect strings with other values in C, you’ll need to define placeholders that are replaced once you print the output.

See an example below: 

        printf("This tree bears %ss and it is %f meters high!\n", appleTree->fruit,
appleTree->height);
    

The %s and %f signs are placeholders and you have to supply the values as a list of parameters after a formatted string. 

Note: it's important to supply the right type of placeholder in the right order. The most common placeholders are: 

%d or %i for integer types
%f for floating-point numbers
%s for strings

Supplying the wrong placeholder type could cause an incorrectly formatted output. To write the output for a file, use fprintf() and supply a pointer to the receiving file:

        fprintf(file_pointer, “\s\n”, any_string);
    

Are you interested in exploring other programming languages? Check out these other tutorials:


Daniel Herczeg
Hi! I am a software engineer and owner of nerdhut.de who always loved to experiment with electronics, gadgets and tech in general.