Programming in C: the basics of the language
16. April 2024
The C language has been the choice of many programmers for decades. In this article, we'll delve into the foundations that underpin this language and discover why it continues to be an undisputed reference in the world of technology for new projects.
Origin of the C programming language
Origins and development of the C language
The C programming language was developed in the early 1970s by Dennis Ritchie at Bell Labs. Although it's been over half a century since its creation, the C language has been continually updated and improved by working groups of the International Organization for Standardization (ISO). These updates include for example the addition of arithmetic operations using floating-point variables. Today, C is one of the most popular and widely used programming languages in the world, according to the TIOBE index.
C's influence on other programming languages
The C language has significantly influenced other programming languages, such as Java, Perl, PHP, Python, C#, among others. Not forgetting the direct influence on languages such as Objective-C, or C++ which, in particular, began as an extension of the C language.
C is often chosen as the base language to teach programming. For this reason, it is often said that knowing how to program in C can make it easier to learn other languages such as Java, C++, C#, Python, due to their very similar syntaxes.
Basic fundamentals of C programming
Structure of a C program: declaration of libraries and main() function
The most common practical example in programming languages is the message "Hello World!", as we can see in the example below using the C language.
#include <stdio.h>
int main{
printf("Hello World!");
return 0;
}
Programs developed with C are implemented using two types of files. On one hand we have .c files - which contain the source code, and on the other hand we have .h files (headers) - which acts as a sort of list or library of functions to be implemented in the .c file, and may also contain definitions of structures, variables, etc.
In a program developed using C language, it is essential to have at least one .c file with the main() function, like the one shown in the example above. This function is the origin, the starting point of our program and therefore the first to be executed.
In this example, we can also see that a library is been included, specifically stdio.h, which allows us to use the "printf" function to write messages to the console.
Basic syntax: declaration of variables, operators, expressions.
The declaration of variables follows a specific nomenclature:
variable_type variable_name = value;
The common variable types in C are char, int, float and double, but the variable type can be something else such as (struct), enum, boolean (included in C99), or an extension of some of the most common variables with the keyword long.
The name of a variable is up to the programmer, but there are rules that must be followed, such as that it cannot contain spaces, special characters or start with a number.
The final part of the expression (= value) is not mandatory, but is considered a good practice.
Control structures in C
Use of conditional structures: if-else, switch-case
Logical conditions can be used to perform a certain task, and this task can consist of one or more operations.
The if-else structure allows you to execute a task if something happens (if- logical condition) or execute another task if it doesn't (else). The syntax of if-else is:
if (logical_condition){
Operation(s);
}else{
Operation(s);
}
The logical_condition is implemented based on the logical operations of mathematics: less than (a<b); less than or equal to (a<=b); greater than (a>b); greater than or equal to (a>=b); equal (a==b); or not equal (a!=b).
The switch-case structure makes it possible to group together and simplify the use of several if-then-else structures that are interconnected, such as the range of an integer variable (from 0 to 100, task 1; de 101 to 200, task 2, etc.) or even different tasks for each letter of the alphabet (if a executa tarefa 1; if b is pressed, task 2 is executed, etc.).
The switch-case syntax is
switch (expression) {
case x: Operation(s);
break;
case y: Operation(s);
break;
default: Operation(s);
}
The expression can be, for example, a variable, and its value will be compared with the values specified in each case. The operations in a block are executed when the variable value match. The keyword break closes the block of operations.
A good practice in deciding when to use if-else or switch-case is to consider the number of conditions to be evaluated. If we're using more than two if-else-if, then it's a good indication to use switch-case. This will make the code cleaner, easier to understand and potentially more efficient.
Using loop structures: for, while, do-while
The for, while and do-while loop structures allow you to perform a set of operations until a condition is verified.
The syntax is as follows:
|
|
|
In the case of the for loop structure, a expression1 initializes the control variable and it is executed only once and before the operations within the for loop. expression2 defines the control condition that ends the for loop. When this condition is false, the for loop structure ends. The expression3, is executed at each iteration in the end of the operations.
In the while and do-while loop structures we have the control, condition, which allows us to define when and while this cycle should be executed.
Here are some examples of their application:
In this example, we look at a case where the numbers from 0 to 10 are printed on the screen using 3 different loop structures:
|
|
|
Arrays and pointers in C
Declaring and using arrays
Arrays are used to store multiple values in a single variable. An array can, for example, be of type char, int, float and double.
An array can be declared in two ways: with initial values or just by defining the desired size:
int arrayName[] = { 0, 10, 20, 30, 40};
int arrayName2[5];
To get or change a value in an array use square brackets ([ ]) with the desired index. For example, if you want the third value in the array arrayName, i.e. the value 20, you get it using arrayName[2]. It's important to note that indexing in the C programming language starts at 0 (zero).
In order to talk about pointers , we need to mention that each time we instantiate a variable, that variable is placed in an available memory position and occupies a certain amount of memory depending on the type of that variable.
As an example, the char type occupies 1 byte, int occupies 2 or 4 bytes, float occupies 4 bytes, and double occupies 8 bytes.
You can get the memory location of a variable by using the '&' operator before the variable name:
int X = 10;
printf(“%p”, &X);
The memory location of a variable depends on the system in which we are implementing our program and the variables already created.
A pointer is a variable that allows us to store the memory address of another variable. A pointer variable is created with the '*' operator and is of the same type as the variable for which it will store the memory location.
Let's look at an example with a variable of type char:
char character = ‘b’;
char *ptr = &character;
printf(“%p”, ptr);
You can also get the value of the variable using the pointer:
printf(“%c”, *ptr); //- Output: b
The concept of pointers and their application in C
Pointers are one of the features that make the C language different from other languages such as Python and Java, as they allow data to be manipulated directly in memory, which reduces code size and improves program performance.
However, some caution is needed when working with pointers, because as mentioned, they allow you to change data directly in memory and therefore damage other memory addresses.
Pointers are widely used to access the positions of large arrays, as they improve performance, to access strings (which in practice are character arrays), to access files and in functions, when you want to change the values of variables outside the block of that function.
C functions and procedures
Defining and using functions in C
A function is a piece of code that is executed when it is called. Functions play an important role in any program, as it allows you to organize your code, but more importantly, it allows you to reuse code without having to write it again.
In the previous examples we have already seen the use of functions, in particular the printf() function, which allows information to be displayed on the screen.
To create or instantiate a function, use the following syntax:
type_to_return function_name (parameter_list) {
Operation(s);
}
A function may or may not return a value, so type_to_return can be void if you don't want the function to return a value, or it can be the type of a variable such as char, int, etc.
The name of the function (function_name) is up to the programmer, but there are rules to follow, such as that it cannot contain spaces, special characters or start with a number.
The parameter list (parameter_list) is not mandatory, so it can be left empty or use void; if there are parameters, they are enclosed in commas.
Parameters are variables, i.e. char, int, pointers, etc, followed by the name of the variable.
As an example, we show how to declare a function with the name Sum, which performs the sum of two integers and returns the result of the operation:
int Sum(int a, int b) {
return a + b;
}
Passing parameters by value and by reference
In the previous example, the Sum function uses two input parameters (a and b). In turn, these are being passed by value. When a function is invoked with values, these are called arguments, and it's important to understand this distinction. Let's look at the Sum function. It can be called as Sum(5, 10) or as Sum(Arg1, Arg2), where Arg1 and Arg2 are two variables of type int.
The arguments are 5, 10, Arg1 and Arg2, which in reality their values end up being copy to the parameters (in this case a and b), which are only available within the scope of the function.
| Resultado: |
The image above shows the execution of our example, where you can see that the Arg1 and Arg2 arguments are in different memory locations to the a and b parameters.
Another way of passing values to functions is by reference. By using this method we are indicating the memory location where the arguments are being stored.
Returning to the previous example, we'll adapt it to receive the parameter b by reference, and as well as returning the sum we'll also return the number of times b fits into a, by using the parameter b to return this value.
| Resultado: |
Analysing the result, we can confirm that the Arg1 argument and parameter a are in different memory locations, while the Arg2 argument and parameter b point to the same memory location.
As the type of the variables is int the result is an integer, as the result of dividing two integers is only the integer part of that division.
In an increasingly digitalized and connected world, the C programming language remains a benchmark in modern technology. Used in a wide range of applications, its versatility and efficiency have made it an indispensable choice for programmers all over the world.
In recent years, we have seen a steady growth in the popularity of C, not only among experienced programmers, but also among younger people joining the technological sphere. What's more, the global community continues to contribute to the evolution of the language, ensuring that it continually adapts to the needs and volatility of industries.
For the future, the outlook is promising and with the growing demand for efficient, low-level computing systems, as well as the advance of new technologies such as IoT, Artificial Intelligence and cloud computing, the need for programmers in this language will tend to increase.
In short, its versatility, efficiency and continued relevance ensure that C will remain an essential tool for those looking to build the future of technology.
Wilde Artikel
What is Outsystems and how is it transforming software development
Java - What makes this language so popular among programmers?
The importance of good practices in .NET programming
Linux: a versatile and powerful operating system
COBOL - Is this language relevant today?
Implementing a Business Intelligence system