• Aucun résultat trouvé

D-2 - Fonctions utilitaires : stdlib.h

Des parties importantes de la bibliothèque standard ont déjà été expliquées ; notamment :

VIII- D-2 - Fonctions utilitaires : stdlib.h

scanf("%d", &x);

assert(0 <= x && x <= N); /* NON ! */

...

La vérification que 0 <= x && x <= N porte sur une valeur lue à l'exécution et garde tout son intérêt dans le programme final, lorsque les assert sont désarmés. C'est pourquoi elle doit plutot être programmée avec du « vrai » code :

...

scanf("%d", &x);

if( ! (0 <= x && x <= N)) {

fprintf(stderr, "Erreur. La valeur de x doit être comprise entre 0 et %d\n", N);

exit(-1);

} ...

*

71Sous UNIX il n'est même pas nécessaire d'ajouter une ligne au programme : il su±t de composer la commande gcc en spécifiant une option « -D », comme ceci : gcc -DNEBUG -o monprog monprog.c etc.

VIII-D-2 - Fonctions utilitaires : stdlib.h

int atoi(const char *s), long atol(const char *s), double atof(const char *s)

Ces fonctions calculent et rendent l'int (resp. le long, le double) dont la chaine s est l'expression écrite. Exemple

int i;

char *s;

...

affectation de s ...

i = atoi(s);

maintenant i a la valeur numérique dont la chaine s est l'expression textuelle

Note. Pour faire le travail inverse de atoi ou une autre des fonctions précédentes on peut employer sprintf selon le schéma suivant :

int i;

char s[80];

...

affectation de i ...

sprintf(s, "%d", i);

maintenant la chaine s est l'expression textuelle de la valeur de i

int rand(void)

Le ieme appel de cette fonction rend le ieme terme d'une suite d'entiers pseudo-aléatoires compris entre 0 et la valeur de la constante RAND MAX, qui vaut au moins 32767. Cette suite ne dépend que de la valeur de la semence donnée lors de l'appel de srand, voir ci-dessous. Si srand n'a pas été appelée, la suite obtenue est celle qui correspond à srand(1).

Voyez srand ci après.

void srand(unsigned int semence)

Initialise une nouvelle suite pseudo-aléatoire, voir rand ci-dessus. Deux valeurs différentes de la semence { éloignées ou proches, peu importe { donnent lieu à des suites tout à fait différentes, du moins à partir du deuxième terme.

Application. Pour que la suite aléatoire fournie par les appels de rand que fait un programme soit différente à chaque exécution de ce dernier il fait donc commencer par faire un appel de srand en veillant à lui passer un argument différent chaque fois. Une manière d'obtenir cela consiste à utiliser l'heure courante (elle change tout le temps !), par exemple à travers la fonction time 72. Par exemple, le programme suivant initialise et a±che une suite pseudo-aléatoire de dix nombres flottants xi vérifiant 0 · xi · 1 :

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

main() { int i;

float x;

srand(time(NULL)); /* version C de randomize */

rand(); /* le premier tirage est très lié à la semence */

for(i = 0; i < 10; i++) { x = rand() / (float) RAND_MAX;

printf("%f\n", x);

} }

void *malloc(size t taille)

Alloue un espace pouvant mémoriser un objet ayant la taille indiquée, ou NULL en cas d'échec. Cet espace n'est pas initialisé.

void *calloc(size t nombre, size t taille)

Alloue un espace su±sant pour loger un tableau de nombre objets, chacun ayant la taille indiquée, ou NULL en cas d'échec. L'espace alloué est initialisé par des zéros.

void free(void *adresse)

Indique au système que l'espace mémoire ayant l'adresse indiquée n'est plus utile au programme. Cette adresse doit nécessairement provenir d'un appel de malloc, calloc ou realloc.

void *realloc(void *adr, size t taille)

Ré-allocation d'espace. La valeur de adr doit provenir d'un appel de malloc, calloc ou realloc. Cette fonction essaie d'agrandir ou de rétrécir (usage rare) l'espace pointé par adr afin qu'il ait la la taille demandée. Si cela peut se faire sur place alors la fonction renvoie la même adresse adr. Sinon, elle obtient un nouvel espace ayant la taille voulue, y copie le contenu de l'espace pointé par adr, libère cet espace, enfin renvoie l'adresse de l'espace nouvellement alloué.

void exit(int code)

Produit l'arrêt normal (fermeture des fichiers ouverts, etc.) du programme. La valeur du code indiqué est transmise au système d'exploitation, cette valeur est utilisée lorsque le programme a été appelé dans le cadre d'un procédure de commandes (ou script). La signification de ce code dépend du système ; on peut utiliser les constantes :

{ EXIT SUCCESS : la valeur conventionnelle qui indique, pour le système sous-jacent, que le programme a réussi à accomplir sa mission ;

{ EXIT FAILURE : le programme n'a pas réussi.

void abort(void)

Provoque un arrêt anormal du programme (c'est un événement détecté par la fonction signal). int system(const char

*commande)

Suspend momentanément l'exécution du programme en cours, demande à l'interprète des commandes du système d'exploitation d'exécuter la commande indiquée et rend le code donné par cette commande (cette valeur dépend du système). La chaine commande doit être l'expression complète, avec options et arguments, d'une commande légale pour le système utilisé.

Toutes les versions de C n'offrent pas ce service, mais on peut savoir ce qu'il en est : l'appel system(NULL) rend une valeur non nulle si l'interprète de commandes peut effectivement être appelé depuis un pro- gramme, zéro sinon.

Exemple (bien connu des utilisateurs de Dev-C++ ; pause est une commande MS-DOS/Windows) :

system("pause");

char *getenv(char *nom)

Rend la chaine qui est la valeur de la variable d'environnement ayant le nom indiqué, ou NULL si une telle variable n'est pas définie. La notion de variable d'environnement est définie au niveau du système sous-jacent.

void qsort(void *tab, size t nbr, size t taille, int (*comp)(const void *, const void *))

Quick sort, ou tri rapide. Cette fonction trie sur place (c'est-à-dire sans utiliser un tableaux auxiliaire), par ordre croissant, un tableau dont tab donne l'adresse de base, formé de nbr objets chacun ayant la taille indiquée.

Pour comparer les éléments du tableau, qsort utilise la fonction qui est la valeur de l'argument comp.

Cette fonction doit prendre les adresses de deux objets comme ceux dont le tableau est fait, et rendre une valeur négative, nulle ou positive selon que le premier objet est respectivement inférieur, égal ou supérieur au second.

Voir à la section 6.3.2, exemple 2, un modèle d'utilisation de cette fonction.

int bsearch(const void *ptr, const void *tab, size t nbr, size t taille, int (*comp)(const void *, const void *))

Binary search, recherche dichotomique. Cette fonction recherche dans un tableau qui doit être trié, ayant l'adresse de base donnée par tab, formé de nbr objets chacun ayant la taille indiquée, un objet égal à celui ayant ptr pour adresse.

Pour cela, elle utilise la fonction de comparaison donnée par comp, qui est définie comme pour qsort, voir ci-dessus.

int abs(int x), long labs(long x)

Valeur absolue, avec un argument int (resp. long) 73.

*

72La fonction time renvoie le nombre de secondes écoulées depuis le premier janvier 1970. Elle renvoie donc un nombre entier qui change toutes les secondes.

Si on doit écrire un programme devant initialiser plusieurs suites aléatoires distinctes en moins d'une seconde { ce qui est quand même rarissime { on aura un problème, qu'on peut régler en faisant intervenir d'autres fonctions de mesure du temps. Par exemple clock compte le temps (mais c'est un temps relatif au lancement du programme) en fractions de seconde, par exemple des millisecondes.

*

73La fonction correspondante pour les réels s'appelle fabs (cf. section 8.4.5).