Notre premier programme C

Maintenant que nous avons introduit le langage C et installé les outils nécessaires, il est temps de plonger dans le vif du sujet et de compiler notre premier programme. :)

Premier programme

Bien, il est à présent temps d’écrire et de compiler notre premier programme ! Pour ce faire, ouvrez votre éditeur de texte et entrez les lignes suivantes.

int main(void)
{
    return 0;
}

Ensuite, enregistrez ce fichier dans un dossier de votre choix et nommez-le « main.c ».

Rappelez-vous, sous Windows, le dossier /home/utilisateur (où « utilisateur » correspond à votre nom d’utilisateur) correspond au dossier C:\msysxx\home\utilisateur (où « xx » est 32 ou 64 suivant la version de MSys2 que vous avez installée).

Une fois ceci fait, rendez-vous dans le dossier contenant le fichier à l’aide d’un terminal et exécutez la commande ci-dessous.

gcc -Wall -Wextra -pedantic -std=c11 -fno-common -fno-builtin main.c

À quoi correspond tout ce texte entre gcc et main.c ?

Il s’agit d’options qui modifient le comportement de GCC. Nous n’allons pas toutes les détailler, mais basiquement nous demandons à GCC de nous avertir si certains points de notre code sont potentiellement problématiques ou s’ils ne respectent pas la norme C11.

Si tout se passe bien, vous devriez obtenir un fichier « a.exe » sous Windows et un fichier « a.out » sinon. Vous pouvez exécuter ce programme en tapant ./a.exe ou ./a.out.

Si vous rencontrez des erreurs lors de la compilation, référez-vous à la section « Erreur lors de la compilation ».

Je viens de le faire, mais il ne se passe rien…

Cela tombe bien, c’est exactement ce que fait ce programme : rien. :p
Voyons cela plus en détails.

Ce bout de code est appelé une fonction qui est la brique de base de tout programme écrit en C. Une fonction se compose d’une ou plusieurs instructions placées entre deux accolades ({ et }). Chaque instruction est terminée par un point-virgule (;). Ici, notre fonction se nomme main. Il s’agit d’une fonction obligatoire dans tout programme C, car il s’agit de la fonction par laquelle l’exécution commence et se termine.

Notre fonction main() ne comporte qu’une seule instruction : return 0;, qui met fin à son exécution (et, par conséquent, à celle du programme) et permet d’indiquer à notre système d’exploitation que l’exécution s’est correctement déroulée (une valeur différente de zéro indiquerait une erreur).

Le nom de la fonction est précédé du mot-clé int (pour integer) qui est un nom de type indiquant que la fonction retourne une valeur entière. À l’intérieur des parenthèses, il y a le mot void qui signifie que la fonction ne reçoit pas de paramètres, nous reviendrons sur tout cela en temps voulu.

Erreur lors de la compilation

Si cela ne vous est pas arrivé lors de la compilation du premier code d’exemple, il vous arrivera de rencontrer des erreurs lors de la compilation. Le plus souvent, ces dernières se produisent à cause d’erreurs de syntaxe.

Par exemple, si vous essayez de compiler le code suivant, vous obtiendrez une erreur.

intxxx main(void)
{
    return 0;
}
gcc -Wall -Wextra -pedantic -std=c11 -fno-common -fno-builtin main.c
main.c:1:1: error: unknown type name 'intxxx'
    1 | intxxx main(void)
      | ^~~~~~

Suivant votre système, le message peut être en anglais ou en français. Dans les deux cas, le compilateur vous indique le fichier où l’erreur s’est produite (main.c) et une indication de la ligne et du caractère (1:1) où se situe l’erreur. Ici le compilateur nous précise que intxxx n’est pas un type connu (nous présenterons la notion de type d’ici peu). En effet, le type correct est int.

Essayons avec un autre exemple incorrect.

int main(void)
{
    return 0
}
gcc -Wall -Wextra -pedantic -std=c11 -fno-common -fno-builtin main.c
main.c: In function 'main':
main.c:3:13: error: expected ';' before '}' token
    3 |     return 0
      |             ^
      |             ;
    4 | }
      | ~

De nouveau, le compilateur nous affiche un message d’erreur et nous précise cette fois qu’il manque visiblement un point-virgule à la fin de la ligne return 0.

Toutefois, en fonction des erreurs, le message fourni par le compilateur n’est pas forcément explicite ou n’indique pas nécessairement la ligne incriminée. Ainsi, si nous oublions d’écrire l’accolade ouvrante, nous obtenons un message un peu plus ésotérique.

int main(void)
    return 0;
}
gcc -Wall -Wextra -pedantic -std=c11 -fno-common -fno-builtin main.c
main.c: In function 'main':
main.c:2:5: error: expected declaration specifiers before 'return'
    2 |     return 0;
      |     ^~~~~~
main.c:3:1: error: expected declaration specifiers before '}' token
    3 | }
      | ^
main.c:4: error: expected '{' at end of input

Cependant, ne paniquez pas si vous obtenez un tel message, relisez calmement votre code et vous tomberez assez rapidement sur la ligne qui pose problème. ;)

Les commentaires

Il est possible d’ajouter des commentaires dans un code source, par exemple pour décrire des passages un peu moins lisibles ou tout simplement pour offrir quelques compléments d’information au lecteur du code. Nous en utiliserons souvent dans la suite de ce cours pour rendre certains exemples plus parlant.

Un commentaire est ignoré par le compilateur, il n’est pas présent dans l’exécutable final. Il ne sert qu’au programmeur et aux lecteurs du code.

Un commentaire en C est écrit soit en étant précédé de deux barres obliques //, soit en étant placé entre les signes /* et */. Dans le dernier cas, le commentaire peut alors s’étendre sur plusieurs lignes.

// Ceci est un commentaire.
/* Ceci est un autre commentaire. */
/* Ceci est un commentaire qui
   prends plusieurs lignes. */

En résumé
  • Il est possible de compiler un programme écrit en C à l’aide de la commande gcc.
  • Il est possible que la compilation échoue, auquel cas un message d’erreur est fourni par le compilateur. Ce message n’est pas toujours limpide, mais une relecture attentive vous permettra de trouver la source de l’erreur.
  • Il est possible d’ajouter des commentaires dans un code source, soit en précédent la ligne de deux barres obliques (//), soit en plaçant une ou plusieurs lignes entre /* et */.