Bases du langage

Écrit le 10/11/2004 par Wikibooks
Dernière mise à jour : 01/02/2006

Hello world!

L'un des plus petits programmes en langage C est :

#include <stdio.h>

int main(int argc, char **argv)
{
    printf("hello world!\n");
    return 0;
}

Ce programme minimaliste est un classique, d'ailleurs une légende voulait que les systèmes Unix avaient un mécanisme pour détecter si un programme était dérivé du hello-world de Kernighan et Ritchie et renvoyaient l'erreur ENONSEQUETOR si ce n'était pas le cas. Ce programme affiche tout simplement le texte « hello world! » à l'écran. Analysons le ligne par ligne :

#include <stdio.h>

Cette ligne sert à utiliser une bibliothèque, stdio, qui contient entre autres la fonction printf que nous allons utiliser pour afficher du texte.

int main(int argc, char **argv)

Cette ligne déclare la fonction main qui prend deux arguments, que nous ne détaillerons pas pour l'instant. Tout ce que l'on doit savoir pour l'instant, est que tout programme en C doit définir cette fonction.

printf("hello world!\n");

On appelle la fonction printf en lui passant en argument le texte que l'on veut afficher, dans notre cas le classique hello world!. Le \n à la fin de la chaîne sert à indiquer que l'on effectue un retour à la ligne après avoir affiché le texte.

Compilation

Pour pouvoir exécuter un programme C, vous devez le compiler.

Tapez le code source du programme hello world! dans un éditeur de texte et sauvegardez le sous le nom hello_world.c. Ouvrez une fenêtre de commandes (terminal sous Unix, commandes MS-DOS sous Windows, ...), placez-vous dans le repértoire où est sauvegardé votre fichier et tapez :

cc hello_world.c

La compilation de votre programme s'effectue et produit un fichier exécutable (a.out sous Unix, a.exe sous Windows, ...) que vous pouvez maintenant utiliser (en tapant ./a.out sous Unix, a sous Windows).

Éléments de syntaxe

Identificateurs

Les identificateurs commencent par une lettre ou un caractère souligné et peuvent contenir des lettres des chiffres et le caractère souligné. Tous les mot-clés ainsi que les symboles (variables, fontions, champs, etc.) sont sensibles à la casse des lettres. Quelques exemples d'identificateurs valides :

toto

_coin_coin76

Mots réservés du langage

Le langage possède 32 mots réservés (ou mots clefs) qui ne peuvent pas être utilisés comme identificateurs et s'écrivent en minuscule :

auto break case char const continue default do
double else enum extern float for goto if
int long register return short signed sizeof static
struct switch typedef union unsigned void volatile while

Commentaires

Les commentaires commencent par /* et se terminent par */, ils ne peuvent pas être imbriquées :

/* ceci est un commentaire */

/*

ceci est aussi un commentaire

* /

/* /* ceci est encore un commentaire */

/* /* */ ceci n'est pas un commentaire */

Inclure des commentaires pertinents dans un programme est un art subtil. Cela nécessite un peu de pratique pour savoir guider les lecteurs et attirer leur attention sur certaines parties délicates du code. Pour faire court, on ne saurait trop que rappeler ce célèbre vers de Nicolas Boileau, qui disait que « ce que l'on conçoit bien, s'ennonce clairement et les mots pour le dire arrivent aisément » (Art Poétique, 1674). Ou pour être encore plus pragmatique : si on a du mal à commenter (expliquer, spécifier) le fonctionnement d'une partie du code, c'est que quelque part le code est mal conçu et que vous gagnerez à le réécrire plus lisiblement.

Il y a aussi un domaine où les commentaires ne devraient pas être employés, c'est pour désactiver certaines parties du code. Cette technique dissuade d'en inclure du fait qu'on ne peut pas imbriquer les commentaires, alors que c'est justement l'erreur à éviter. Pour cela, le préprocesseur dispose d'instructions dédiées, qui permettent heureusement de les laisser.

Instructions

Les instructions se terminent par un point-virgule (;), on peut placer autant d'instructions que l'on veut sur une même ligne (même si ce n'est pas conseillé pour la lisibilité du code). Les blocs d'instructions commencent par une accolade ouvrante ({) et se terminent par une accolade fermante (}). Les instructions doivent obligatoirement être déclarées dans une fonction : il est impossible d'appeler une fonction pour initialiser une variable globale par exemple (contrairement au C++).

/* une instruction */
i = 1;

/* plusieurs instructions sur la même ligne */
i = 1; j = 2; printf("bonjour\n");

/* un bloc */
{
    int i;
    i = 5;
}

/* l'instruction vide */
;

Dans la mesure où le compilateur ne se soucie pas des blancs (espaces et retours à la ligne), vous pouvez formatter votre code comme vous l'entendez. Il y a beaucoup de religion concernant les styles d'indentation, mais pour faire court et éviter les guerres saintes, on ne saurait trop conseiller que d'utiliser le même nombre de blanc par niveau d'imbrication de bloc.

À noter que l'instruction vide étant valide en C, on peut donc pratiquement rajouter autant de point-virgule que l'on veut. Le point-virgule ne sert pas uniquement à marquer la fin des instructions, les compilateurs l'utilisent généralement comme caractère de synchronisation, suite à une erreur dans un programme source. En fait, en général, lorqu'une erreur est détectée, les compilateurs ignorent tout jusqu'au prochain point-virgule. Ce qui peut avoir des conséquences assez dramatiques, comme dans l'exemple suivant :

/* Ce code contient une erreur grossière et volontaire */
int traite_arguments( int nb, char * argv[] )
{
    /* ... */
    return 0
}

int main( int nb, char * argv[] )
{
    int retour;

    retour = traite_arguments( nb, argv );

    /* ... */
}

On notera l'absence de point-virgule à la fin de l'instruction return à la fin de la fonction traite_arguments. Ce que la plupart des compilateurs feront dans ce cas est d'ignorer tout jusqu'au prochain point-virgule. On se rend compte du problème : on a sauté une déclaration de fonction (avec ses deux paramètres) et une déclaration de variable. Ce qui veut dire qu'une cascade d'erreurs va suivre suite à l'oubli... d'un seul caractère (;) !

Déclarations de variables

T var1, var2, ..., varN;

Cette instruction déclare les variables var1, var2, ..., varN de type T. Les variables ne sont pas initialisées automatiquement et contiennent donc, après leur déclaration, une valeur aléatoire. Cette valeur est celle présente à l'endroit où la variable a été placée dans l'espace mémoire reservé.

Avant la normalisation ISO C99, les déclarations de variables devaient obligatoirement être placées juste au début d'un bloc (accolade ouvrante) et s'arrêtaient à la première instruction rencontrée. Si une déclaration est faite au-delà, une erreur sera retournée.

Une variable est dite locale, si elle est déclarée à l'intérieure d'une fonction et globale si déclarée en dehors. Une attention particulière doit être portée aux variables globales, souvent source de confusion et d'erreur. Utilisez des noms explicites, longs si besoin et limitez leur usage au seul fichier où elles sont déclarées, en les déclarants statiques.

Traitements des ambiguïtés

Le C utilise un mécanisme élégant pour lever des constructions syntaxiques en apparence ambiguës. L'analyse des mots (lexèmes, token en anglais) se fait systématiquement de la gauche vers la droite. Si plusieurs lexèmes peuvent correspondre à une certaine position, le plus grand aura priorité. Considérez l'expression valide suivante :

a+++b;

Ce genre de construction hautement illisible et absconde étant bien évidemment à éviter, mais illustre parfaitement bien ce mécanisme. Dans cet exemple, le premier lexème trouvé est bien sûr l'identificateur 'a' puis le compilateur a le choix entre l'opérateur unaire '++', ou l'opérateur binaire '+'. Le plus grand étant le premier, c'est celui-ci qui aura priorité. L'instruction peut donc se décomposer en :

(a ++) + b;

Cet article provient de Wikibooks et est sous licence GNU Free Documentation License. Il a été écrit par plusieurs personnes et est constamment mis à jour. Cet article est la version du 17 janvier 2005 à 02:47. L'article d'origine se trouve à http://fr.wikibooks.org/wiki/Programmat ... du_langage.