Initiation au langage C


précédentsommairesuivant

II. Instruction, programme et fonction

II-A. Structure générale d'un programme C

II-A-1. Un premier programme

Nous allons écrire un programme qui affiche Hello, world en langage C.

hello.c
Sélectionnez
#include <stdio.h>

int main()
{
    printf("Hello, world\n");
    return 0;
}

Voici la sortie de ce programme (c'est-à-dire, ce que nous, utilisateurs, verrons affiché sur le périphérique de sortie standard) :

 
Sélectionnez
 
Hello, world
 

Le caractère '\n' dans la chaîne de caractères "Hello, world\n" représente le caractère de fin de ligne. Il permet d'insérer une nouvelle ligne (new line).

En langage C, la « brique » qui permet de créer un programme est la fonction. Un programme écrit en C est donc constitué d'une ou plusieurs fonctions, une fonction étant généralement composée d'une ou plusieurs instructions, chaque instruction élémentaire devant se terminer par un point-virgule.

printf est une fonction qui permet d'afficher du texte sur la sortie standard, par défaut l'écran. main est également une fonction, c'est celle qui sera automatiquement appelée à l'exécution. On l'appelle le point d'entrée du programme ou encore la fonction principale. Ici, elle est seulement composée de deux instructions :

  1. printf("Hello, world\n");
  2. return 0;

Selon la norme officielle du langage C, main est une fonction qui doit retourner un entier (int). Chez de nombreux systèmes (dont Windows et UNIX), cet entier est appelé le code d'erreur de l'application. En langage C, bien que cela ne soit pas forcément le cas pour le système d'exploitation, on retourne 0 pour dire que tout s'est bien passé.

Le langage C impose (à quelques exceptions près que nous verrons plus bas) qu'une fonction doit avoir été déclarée avant de pouvoir être utilisé (nous verrons plus tard ce que c'est qu'une déclaration). Dans notre exemple, puisque nous utilisons la fonction printf, nous devons tout d'abord la déclarer. Le moyen le plus simple de le faire est d'inclure le fichier stdio.h, qui contient entre autres la déclaration de cette fonction, à l'aide de la directive include :

 
Sélectionnez
 
#include <stdio.h>
 

II-A-2. Les commentaires

On peut insérer des commentaires n'importe où dans du code C à l'aide des délimiteurs /* et */. Les commentaires permettent de rendre les programmes plus lisibles. Voici un exemple d'utilisation de commentaires :

hello.c
Sélectionnez
#include <stdio.h>

int main()
{
    /* Ce programme affiche "Hello, world" */
    printf("Hello, world\n");
    return 0;
}

II-A-3. Sensibilité à la casse

Le C est sensible à la casse : il fait la distinction entre les majuscules et les minuscules. Printf et printf sont deux choses complètement différentes et qui n'ont strictement rien à voir ...

II-A-4. Le format libre

En langage C, les espaces (y compris les tabulations et les retours à la ligne) peuvent être utilisées à volonté (ou pas du tout) avant ou après un séparateur (# < > ( ) { } ; …). On traduit ce fait en disant que le C est un langage au format libre. Une chaîne ("...") doit cependant toujours tenir sur une seule ligne (nous reviendrons sur ce point plus tard). Ainsi, notre programme qui affiche "Hello, world" aurait également pu s'écrire :

 
Sélectionnez
#   include    <stdio.h>
int
main ( )
{   printf    (
        "Hello, world\n"
    );return
    
    0
    
;}

Dans certains cas, les espaces peuvent cependant être utilisés de manière précise. Par exemple, avec :

 
Sélectionnez
 
#include < stdio.h >
 

Vous demandez d'inclure le fichier <espace>stdio.h<espace> (qui a de fortes chances de ne pas exister, ce qui génèrerait des erreurs à la compilation ...) et non le fichier stdio.h !

II-B. Du fichier source à l'exécutable

II-B-1. La compilation

Avant de définir la compilation, il y a deux expressions qu'il faut déjà avoir défini. Il s'agit de "fichier source" et "fichier exécutable".

  • Un fichier source est un fichier contenant, dans le cas qui nous intéresse, des lignes de code écrits en C. Le code contenu dans le fichier source est appelé du code source. Les fichiers sources C portent généralement l'extension ".c" (par exemple : hello.c).

  • Un fichier exécutable est un fichier contenant, entre autres, du code directement exécutable par le processeur. Ce code est appelé code machine. L'extension portée par les fichiers exécutables varient selon le système. Sous Windows par exemple, ils portent généralement l'extension ".exe" (par exemple : hello.exe). Sous Linux, ils ne portent généralement pas d'extension.

La compilation c'est, en première approximation, le processus pendant lequel le fichier source (qui ne contient que du texte) est transformé en fichier exécutable (qui contient du code compréhensible par le processeur). Une définition plus précise sera donnée dans les cours plus avancés.

Puisque les programmes C doivent être compilés avant de pouvoir être exécutés, on dit que le C est un langage compilé. Le programme qui effectue la compilation est appelé compilateur.

Nombreux programmeurs utilisent cependant un EDI (Environnement de Développement Intégré) au lieu d'un simple compilateur pour compiler leurs programmes. Un EDI est un logiciel qui intègre un éditeur de texte pour taper les codes sources, un compilateur pour les traduire en exécutable ainsi que d'autres outils aidant à la mise au point et à la distribution des programmes. Il existe de nombreux EDIs pour le langage C. Certains sont gratuits (Code::Blocks Studio, Visual C++ Express, etc.), d'autres payants (CodeGear RAD Studio, Microsoft Visual Studio, etc.). Téléchargez ou achetez et installez le logiciel qui vous convient donc avant de continuer. Pour les manipulations pratiques, nous supposerons dans la suite que nous travaillons sous Windows, mais que cela ne vous empêche de lire ce tutoriel même si vous utilisez un autre système.

II-B-2. Applications consoles

Le C voulant être un langage entièrement portable, la création d'interfaces graphiques n'est pas supportée en standard par le langage. En effet, la notion d'interface graphique n'existe pas forcément dans tous les systèmes. Dans les systèmes proposant un environnement graphique, comme Windows par exemple, les applications qui en sont dépourvues sont souvent appelées applications consoles. Ces applications, quand elles sont lancées, s'exécutent dans une fenêtre (la fameuse "console") dans laquelle l'utilisateur n'utilise que le clavier pour commander le programme). Dans ce tutoriel, c'est toujours ce type d'applications que allons développer.

II-B-3. Manipulations avec Visual C++ et Code::Blocks

II-B-3-a. Avec Visual C++ 6
  1. Lancez Visual C++.

  2. Créez un projet d'application console que vous allez nommer helloworld en choisissant File > New > Project > Win32 Console Application. Un dossier nommé helloworld est alors créé. Ce sera votre répertoire par défaut. Deux fichiers, entre autres, sont également créés : helloworld.prj (votre projet) et helloworld.dsw (votre espace de travail).

  3. Choisissez An empty project pour qu'aucun fichier ne soit automatiquement ajouté à notre projet.

  4. Ajoutez au projet un nouveau fichier que vous allez nommer hello.c avec la commande Project > Add to Project > New > C++ source file. Nommez-le bien hello.c car si vous omettez l'extension, VC6 va automatiquement ajouter l'extension .cpp et vous aurez donc un fichier source C++ (hello.cpp) au lieu d'un fichier source C, à moins bien sûr que c'est justement ce que vous cherchiez ...

  5. Dans l'explorateur de projet (normalement c'est sur votre gauche), cliquez sur File View pour afficher une vue des fichiers qui constituent votre projet. Ouvrez ensuite le dossier Source Files puis double cliquez sur hello.c pour l'ouvrir dans l'éditeur.

  6. Saisissez maintenant le code puis compilez avec la commande Build > Build helloworld.exe (F7). Le fichier helloworld\Debug\helloworld.exe est alors créé.

  7. Pour tester votre programme sans quitter VC, choisissez Build > Execute helloworld.exe (Ctrl + F5). Le message de type "Appuyez sur une touche pour continuer" ne fait évidemment pas partie de votre programme. C'est juste un message provenant de votre EDI pour éviter la fermeture immédiate de la console à la fin de l'exécution du programme, ce qui ne vous aurait pas permis de "contempler" sa sortie.
II-B-3-b. Avec Visual Studio .NET

La procédure est presque les même que sous VC6. Créez un nouveau projet d'application Windows (Win32 Project) puis dans l'étape Applications Settings de l'assistant, choissez Console Application puis Empty Project. Compilez puis testez.

II-B-3-c. Avec Code::Blocks 1.0
  1. Lancez Code::Blocks.

  2. Créez un nouveau projet d'application console que vous aller nommer helloworld en choisissant File > New Project > Console Application. Enregistrez-le dans un répertoire de votre choix qui sera alors votre répertoire par défaut. Avant de valider, cochez l'option Do not create any files afin qu'aucun fichier ne soit automatiquement ajouté à notre projet. Une fois que vous avez validé, un fichier helloworld.cbp (votre projet) sera créé dans le répertoire de votre projet.

  3. Créez un nouveau fichier que vous allez nommer hello.c avec la commande File > New File. Acceptez que ce fichier soit ajouté au projet.

  4. Saisissez maintenant le code puis compilez avec la commande Build > Build (Ctrl + F9). Le fichier helloworld.exe est alors créé.

  5. Pour tester votre programme sans quitter Code::Blocks, choisissez Build > Run (Ctrl + F10). Le message de type "Appuyez sur une touche pour continuer" ne fait évidemment pas partie de votre programme. C'est juste un message provenant de votre EDI pour éviter la fermeture immédiate de la console à la fin de l'exécution du programme, ce qui ne vous aurait pas permis de "contempler" sa sortie.

II-C. Les fonctions

II-C-1. Introduction

Comme nous l'avons déjà dit plus haut, les fonctions sont les briques avec lesquelles on construit un programme en langage C. La vie d'un programmeur C se résume donc à créer puis utiliser des fonctions. Vous allez adorer ! Nous allons donc maintenant voir de plus près ce que c'est qu'une fonction.

II-C-2. Exemple avec une fonction "mathématique"

En mathématiques, on définit une fonction comme suit :

 
Sélectionnez
 
f(x) =- 3
 

Cela signifie que f est une fonction qui reçoit en argument un réel x et qui retourne un réel : x2 - 3.

Ecrivons une fonction C que nous appellerons f, qui reçoit en argument un entier x et qui retourne également un entier : x2 - 3.

 
Sélectionnez
int f(int x)
{
    return x*x - 3;
}

Le code ci-dessus constitue ce qu'on appelle la définition ou encore l'implémentation de la fonction f. Voyons maintenant un exemple d'utilisation de cette fonction.

 
Sélectionnez
#include <stdio.h>

int f(int); /* declaration de la fonction f */

int main()
{
    int x = 4;
    printf("f(%d) = %d\n", x, f(x));
    return 0;
}

int f(int x)
{
    return x*x - 3;
}

La ligne :

 
Sélectionnez
int f(int);

tient lieu de déclaration de la fonction f. Sans le point-virgule, on a ce qu'on appelle le prototype ou la signature de la fonction f. Ici, le prototype (la signature) indique que "f est une fonction qui nécessite en argument un int (int f(int)) et qui retourne un int (int f(int))". Un prototype suivi d'un point-virgule constitue ce qu'on appelle une déclaration (mais ce n'est pas la seule forme possible de déclaration d'une fonction).

Attention ! Nous avons vu jusqu'ici qu'une instruction élémentaire se termine par un point-virgule. Cela ne signifie en aucun cas que tout ce qui se termine par un point-virgule est donc une « instruction ». Une déclaration est une déclaration, pas une instruction. Nous définirons ce que c'est exactement une instruction encore plus loin.

Le %d dans la chaîne passée en premier argument de printf est ce qu'on appelle un spécificateur de format. Il renseigne sur la manière dont nous souhaitons afficher le texte. Ici, on veut afficher les nombres 4 et 13 (f(4)). Nous disons donc à printf d'utiliser le format « nombre entier » (%d) pour les afficher. Le premier %d correspond au format que nous voulons utiliser pour afficher x et le deuxième pour f(x). Nous y reviendrons un peu plus loin.

Sachez également que la variable x dans la fonction main n'a absolument rien à voir avec la variable x en paramètre de la fonction f. Chaque fonction peut avoir ses propres variables et ignore complètement ce qui se passe chez les autres fonctions. On vient ainsi d'introduire le concept de "variables locales" que nous étudierons également plus tard.

II-C-3. Exemple avec une "procédure"

Certains langages de programmation (Pascal, VB (Visual Basic), etc.) font la distinction entre "fonction" et "procédure". En langage C et ses dérivés, il n'y a pas cette distinction. Ce que chez certains langages on appelle procédure est en effet ni plus ni moins qu'une fonction qui effectue un traitement mais qui ne retourne pas de valeur, c'est-à-dire une fonction qui ne retourne rien. En langage C, ce "rien" est indiqué par le mot-clé void (terme anglais signifiant "vide"). Voici un exemple de fonction qui ne requiert aucun argument et qui ne retourne rien : une fonction qui affiche "Bonjour." 3 fois (en 3 lignes).

 
Sélectionnez
#include <stdio.h>

void Bonjour3Fois(void);

int main()
{
    /* Ce programme affiche Bonjour 6 fois */
    Bonjour3Fois();
    Bonjour3Fois();
    return 0;
}

void Bonjour3Fois(void)
{
    printf("Bonjour.\n");
    printf("Bonjour.\n");
    printf("Bonjour.\n");
}

II-C-4. Remarques

Dans une déclaration on peut :

  • Mettre le nom des arguments de la fonction (bon uniquement pour la déco et rien d'autre). Par exemple :
    exemple de déclaration d'une fonction
    Sélectionnez
     
    int Surface(int Longueur, int largeur);
     
    
  • Ne pas préciser les arguments de la fonction (déconseillé). Dans ce cas, il faut aller à la définition de la fonction pour connaître les arguments qu'elle requiert. Attention ! Ne pas préciser les arguments d'une fonction n'est pas la même chose que déclarer une fonction qui ne requiert aucun argument. Exemple :
    exemple de déclaration incomplète d'une fonction (déconseillé)
    Sélectionnez
     
    int Surface(); /* Surface est une fonction, point. Voir sa definition pour plus de details. */
     
    
    exemple de déclaration d'une fonction qui ne requiert aucun argument
    Sélectionnez
     
    int Surface(void);
     
    

De plus on peut :

  • Ne pas déclarer une fonction retournant un int (déconseillé).

  • La déclaration d'une fonction n'est nécessaire que lorsque son utilisation précède sa définition. En effet, une fois définie, la fonction est entièrement connue et donc n'a plus besoin d'être déclarée. Il est cependant toujours conseillé de ne définir une fonction qu'après son utilisation (ce qui requiert donc une déclaration) ne serait-ce que pour la lisibilité du programme (en effet c'est le programme qu'on veut voir à première vue, pas les petits détails).

Dans une définition:

  • On peut ne pas préciser le type de retour d'une fonction (déconseillé). Dans ce cas celle-ci est supposée retourner un int.

  • Si la fonction a déjà été déclarée à l'aide d'une déclaration complète (c'est-à-dire avec prototype), une paire de parenthèses vide signifie que la fonction n'accepte aucun argument. Sinon, les parenthèses vides signifient que les arguments requis par la fonction ne sont pas renseignés. Cette manière de définir une fonction est à éviter sauf pour des fonctions qui ne sont jamais appelées depuis le programme comme main() par exemple.

II-D. Les macros

II-D-1. Le préprocesseur

Avant d'être effectivement compilés, les fichiers sources C sont traités par un préprocesseur qui résout certaines directives qui lui sont données comme l'inclusion de fichier par exemple. Le préprocesseur, quoi qu'étant un programme à priori indépendant du compilateur, est un élément indispensable du langage.

Une directive donnée au préprocesseur commence toujours par #. Nous avons déjà rencontré la directive include qui permet d'inclure un fichier. La directive define permet de définir des macros.

II-D-2. Définition

Une macro, dans sa forme la plus simple, se définit de la manière suivante :

 
Sélectionnez
#define <macro> <le texte de remplacement>

Par exemple :

 
Sélectionnez
#define N 10

commande au préprocesseur de remplacer toutes les occurrences de le lettre N par 10. Bien sûr il n'y a pas que les lettres et les nombres qu'on peut utiliser, rien ne nous empêche par exemple d'écrire :

 
Sélectionnez
#define PLUS +

Ainsi, toutes les occurrences de PLUS seront remplacés par +.

Dans certaines circonstances, les macros peuvent également avantageusement remplacer les fonctions. Par exemple :

 
Sélectionnez
#define carre(x) x * x

Dans ce cas, une expression telle que

 
Sélectionnez
carre(3)

sera remplacé par :

 
Sélectionnez
3 * 3

Si cela semble fonctionner à première vue, voyons un peu ce qu'on obtiendrait avec :

 
Sélectionnez
carre(1 + 1)

Et bien, on obtiendrait :

 
Sélectionnez
1 + 1 * 1 + 1

soit 1 + 1 + 1 soit 3 car la multiplication est prioritaire par rapport à l'addition. Nous verrons plus tard l'ordre de priorité des opérateurs. C'est pourquoi on utilise généralement beaucoup de parenthèses dans le corps d'une macro. Ainsi, dans l'exemple précédent, on aurait du par exemple écrire :

 
Sélectionnez
#define carre(a) ((a) * (a))

Ce qui nous donnerait pour carre(1 + 1) par exemple :

 
Sélectionnez
((1 + 1) * (1 + 1))

II-E. Exercices

II-E-1. La lettre X

Ecrire un programme qui dessine la lettre dans une grille de dimensions 5 x 5 en utilisant des espaces et le caractère '*'. Cela signifie qu'on veut avoir comme sortie :

 
Sélectionnez
*   *
 * * 
  *
 * * 
*   *

II-E-2. Périmètre d'un rectangle

Ecrire une fonction qui permet d'avoir le périmètre d'un rectangle de longueur et largeur données en arguments et utiliser cette fonction dans un programme arbitraire pour afficher le périmètre d'un rectangle de dimensions 100 x 60. Exemple de sortie :

 
Sélectionnez
 
Le perimetre d'un rectangle de longueur 100 et de largeur 60 est 320.
 

précédentsommairesuivant

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2008 Melem. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.