next up previous
Next: La compilation Up: Initiation au langage C Previous: Structure d'un programme C

Sous-sections

Les bibliothèques standards

  En C, il n'existe aucune commande spécifique pour faire communiquer le programme avec l'extérieur. On utilise des fonctions externes fournies par le système sur lequel le programme doit fonctionner.

La norme C impose que tous les compilateurs fournissent un certain nombre de fonctions standards dont le fonctionnement et les paramètres sont définis par la norme. Chaque système peut proposer ses propres fonctions spécifiques en plus des fonctions standards.

              Dans ces fonctions standards, on trouve entre autre des fonctions de calcul mathématique (log, cos, sin, sqrt, etc.), des fonctions d'entrées/sorties (printf, fprintf, scanf, fscanf, getc, putc, etc.), des fonctions d'accès aux fichiers (fopen, fclose, fread, fwrite, etc.), des fonctions de manipulation de chaînes de caractères (strlen, strcpy, strcat, etc.) et des fonctions de gestion de la mémoire (malloc, free, calloc, etc.).

Sous UNIX, le système propose une page de manuel en ligne (via la commande man) pour chacune de ces fonctions. Cette page précise à chaque fois le nom du fichier d'en-tête à inclure pour faire connaître au compilateur la déclaration de la fonction ainsi que le nom de l'éventuelle bibliothèque contenant sa définition. Si aucune bibliothèque n'est nécessaire, cela signifie que la définition de cette fonction externe est présente dans la bibliothèque C. Cette bibliothèque est mise automatiquement à disposition du compilateur lors de l'édition des liens d'un programme.

Nous ne détaillerons pas toutes ces fonctions. Nous nous focaliseront sur printf, scanf pour les entrées/sorties et sur malloc et free pour l'allocation de mémoire dynamique.

la fonction printf

  printf est une fonction externe inclue dans la bibliothèque de fonctions C standards. Elle permet d'afficher à l'écran des informations provenant du programme.

Elle prend un nombre d'arguments variable. Son premier argument est une chaîne de caractères spécifiant le format d'affichage. Les arguments suivants sont les valeurs qu'il faudra afficher. C'est le contenu du format qui permet de dire comment les arguments suivants seront affichés :

printf(format, arg1, ... , argN);

  Le format est interprété de la manière suivante :


 
 
Tableau 9.1: Séquences spéciales dans un printf.
Séquence l'argument remplaçant la séquence doit être
% c un caractère seul
% s une chaîne de caractère
% d un entier (affiché en décimal)
% o un entier (affiché en octal)
% x un entier (affiché en héxadécimal)
% u un entier non signé (affiché en décimal)
% f un réel (affiché normalement)
% e un réel (affiché en notation exponentielle)
% g un réel (au mieux entre f et e)

On peut introduire entre le % et le caractère de spécification de format d'affichage quelques caractères de contrôles d'affichage :

Exemples :

double a=3.141592653589793115997963;
    
printf("Pi = %e n", a);
printf("Pi = %f n", a);
printf("Pi = %15f n", a);
printf("Pi = %18.13f n", a);
printf("Pi = %+.13f n", a);
printf("Pi = %-+18.13f n", a);
printf("Pi = %.25f n", a);

Affiche :

        Pi = 3.141593e+00
        Pi = 3.141593
        Pi =        3.141593
        Pi =    3.1415926535898
        Pi = +3.1415926535898
        Pi = +3.1415926535898  
        Pi = 3.1415926535897931159979635
Il faut inclure le fichier d'en-tête standard stdio.h avant de pouvoir utiliser la fonction printf :

#include <stdio.h>

la fonction scanf

  Nous ne détaillerons pas complètement la fonction scanf dont le fonctionnement n'est pas réellement évident. Nous ne donnerons que quelques exemples.

scanf permet de lire et d'interpréter du texte saisie par l'utilisateur au clavier. Comme printf, cette fonction utilise un format suivi d'un nombre variable d'arguments que scanf devra lire. Comme ces arguments vont être modifiés par la fonction, il faut toujours lui envoyer des pointeurs sur les variables à lire.

  Dans le format, c'est encore le caractère % qui spécifie l'utilisation des arguments. Nous donnons dans le tableau 9.2 la liste des principales séquences utilisables.


 
 
Tableau 9.2: Séquences spéciales dans un scanf.
Séquence interprétation de la saisie type de l'argument
% c un caractère seul char *
% s une chaîne de caractère char *
% d un entier en décimal int *
% o un entier en octal (précédé d'un 0) int *
% x un entier en héxa (précédé de 0x) int *
% u un entier non signé décimal unsigned int *
% f un réel float *
% e un réel float *
% g un réel float *

Attention : il faut faire précéder les caractères spécifiant un entier (d, o, x, u) du caractère l pour spécifier que l'entier est de type long * ou du caractère h pour spécifier que l'entier est de type short *. De même pour les réels, si le caractère est précédé d'un l alors le type est double *.

Exemples :

double a;
int g;
char str[300];
    
printf("Donnez la valeur de a :");
scanf("%lf", &a);
    
printf("Donnez la valeur de g (en octal) :");
scanf("%o", &g);
    
printf("Donnez la valeur de str :");
scanf("%s", str);

Remarque : dans le cas d'un tableau de caractères, il ne faut pas mettre de & devant le nom du tableau puisque ce nom représente déjà un pointeur sur le tableau.

Il faut inclure le fichier d'en-tête standard stdio.h avant de pouvoir utiliser la fonction scanf :

#include <stdio.h>

l'allocation dynamique de la mémoire

 

la fonction malloc

    La fonction malloc permet de demander au système de réserver un espace mémoire afin de l'utiliser dans un programme C. L'allocation de la mémoire se fait de manière dynamique.

Pour pouvoir utiliser la fonction malloc, il faut inclure le fichier d'en-tête standard stdlib.h :

#include <stdlib.h>

Le seul paramètre de malloc est la taille en nombre d'octets du bloc mémoire à allouer. Le résultat de malloc est de type void * (c'est à dire un pointeur générique). Il faut le convertir en un pointeur sur le type de données que l'on veut stocker.

Pour connaître la taille d'un type, on utilise l'opérateur sizeof. L'utilisation de sizeof permet de garantir que le programme se compilera correctement quelque soit la machine utilisée (ne pas oublier qu'un double n'occupe pas obligatoirement la même place sur toutes les machines).

Dans l'exemple suivant, on alloue dynamiquement tout d'abord un int, puis un complexe et enfin un tableau de 100 short :

int * pInt;
complexe * pComplexe;
short * pShortTab;
    
pInt = (int *) malloc(sizeof(int));
pComplexe = (complexe *) malloc(sizeof(complexe));
pShortTab = (short *) malloc(sizeof(short) * 100);

Une fois ces allocations dynamiques effectuées, il est possible de stocker des données dans l'espace mémoire pointé par ces trois pointeurs comme avec n'importe quel autre pointeur.

  La fonction malloc retourne la valeur NULL si il n'y a plus assez de place pour allouer un bloc de la taille demandée. Dans un programme C correct, on doit donc tester la valeur de retour de malloc pour vérifier que l'allocation s'est bien déroulée. En général, s'il n'y a plus assez de mémoire, on arrête le programme grâce à l'instruction exit qui stoppe instantanément le programme :

int * pTabInt;
    
pTabInt = (int *) malloc(sizeof(int) * 10000);
    
if (pTabInt == NULL) {
    printf("Plus assez de mémoire pour continuer !\n");
    exit(1);
}

Ceci étant, si un pointeur contient la valeur NULL, il est obligatoirement invalide et toute tentative d'accéder à son contenu provoquera une erreur.

la fonction free

    Toute la mémoire allouée dynamiquement durant l'exécution d'un programme sera libéré à la fin du programme. Mais, il est plus propre et surtout moins consommateur de ressources mémoire de libérer l'espace mémoire que l'on a réservé dès qu'on n'en a plus besoin. La fonction free permet de libérer un bloc mémoire précédemment alloué via malloc. Cette espace mémoire est rendu au système qui pourra le réutiliser pour un autre usage (par exemple un autre malloc).

Le seul paramètre de free est un pointeur (ce pointeur doit normalement être de type void *. Néanmoins, le compilateur effectue tout seul la conversion si c'est un pointeur d'un autre type). Ce pointeur doit absolument pointé sur un espace mémoire alloué par malloc.

Pour pouvoir utiliser la fonction free, il faut inclure le fichier d'en-tête standard stdlib.h :

#include <stdlib.h>

  En général, après la libération de l'espace mémoire qu'il pointait, on stocke la valeur NULL dans le pointeur afin d'éviter un accès involontaire à l'espace mémoire libéré. De même, tant qu'un pointeur ne pointe vers rien de spécial, on l'initialise avec la valeur NULL :

int * pTabInt = NULL;
/* le contenu de pTabInt n'est pas accessible */
...
pTabInt = (int *) malloc(sizeof(int) * 10);
/* on peut utilises les dix elements du tableau pointés
    par pTabInt : pTabInt[0], ..., pTabInt[9] */
...
free(pTabInt);
pTabInt = NULL;
/* le contenu du pointeur pTabInt n'est plus utilisable */
...


next up previous
Next: La compilation Up: Initiation au langage C Previous: Structure d'un programme C

Copyright © EMAC - 1997 - Paul GABORIT