• Aucun résultat trouvé

Compilation conditionnelle

N/A
N/A
Protected

Academic year: 2022

Partager "Compilation conditionnelle"

Copied!
22
0
0

Texte intégral

(1)

Compilation conditionnelle

• 

Sélectionne des parties du code à omettre lors de la compilation si une condition est remplie.

• 

Ces parties peuvent contenir des déclarations et/

ou des actions

Qui sont spécifiques à un matériel

•  Utiles au débuggage uniquement.

(2)

Compilation conditionnelle (2)

• 

Utiliser les directives:

#if, #ifdef, #elif, #else, #endif

• 

Les conditions de test

• 

Sont sur des constantes entières

• 

Evaluées comme Vrai/Faux

• 

Peuvent contenir des opérateurs s ’ ils sont

évalués sur des constantes entières

(3)

Compilation conditionnelle (3)

#include <stdio.h>

#define DEBUG 2

int main(void){

#if DEBUG ==2

printf(``DEBUG est à 2\n``);

#else

printf(``DEBUG n’est pas à 2\n``);

#endif return 0;

}

(4)

Compilation conditionnelle (4)

• 

Si on effectue gcc –E fichier.c, on obtient le résultat de l ’ action du préprocesseur :

int main(void){

printf(``DEBUG est à 2\n``);

return 0;

}

• 

L ’ option –E permet d ’ appeler le préprocesseur

mais n ’ effectue pas la compilation.

(5)

Compilation conditionnelle (5)

• 

Aide au débuggage d ’ un programme

• 

On peut donner n ’ importe quel nom aux identifiants

• 

Chaque directive #if doit recevoir une directive

#endif

(6)

Définitions

• 

Concerne les directives #ifdef et #ifndef

• 

Utilisées pour déterminer si un symbole est connu du préprocesseur.

#ifdef identificateur vérifie si identificateur a été défini

•  #ifndef identificateur vérifie si il na pas été défini

• 

Une directive par ligne

(7)

Définitions et compilation conditionnelle

• 

Permet d ’ éviter de définir plusieurs fois le même identifiant ou symbole et de résoudre des conflits quand il y a :

Insertion multiple dun même fichier den-tête

•  Déclaration multiple dun identifiant

•  Redéfinition dun identifiant

• 

Pour un fichier entête classic.h :

#ifndef CLASSIC.H

#define CLASSIC.H

….

#endif

(8)

Autre directives

• 

#error ``message``

Emet une erreur de compilation avec pour message message si activée.

• 

#line numero_de_ligne ``nom_de_fichier``

•  __LINE__ est réinitialisé à numero_de_ligne

•  __FILE__ est réinitialisé à nom_de_fichier

• 

Une ligne de la forme # n ’ a aucun effet

(9)

Fonctions à arguments variables

•  La norme ANSI définit des mécanismes permettant de traiter de façon portable des listes d'arguments variables telles qu'on en trouve par exemple dans les fonctions

printf et scanf

int printf (const char *format, ...);

•  Pour pouvoir traiter des listes d'arguments variables, il faut inclure le fichier stdarg.h :

#include <stdarg.h>

(10)

Fonctions à arguments variables

•  On dispose alors d'un type, va_list, et de trois macros sur des objets de ce type : va_arg, va_end et va_start.

va_start initialise une liste d’arguments variable. Elle prend en paramètre la liste et le dernier paramètre de la fonction avant le début de la liste.

(donc les listes d’arguments variables sont toujours à la fin des paramètres)

•  va_end doit être appelée obligatoirement avant le retour de la fonction.

Elle prend la liste en paramètre.

va_arg permet d’accéder à l’élément courant de la liste. Elle prend en paramètre la liste et un nom de type (celui de l’élément courant).

(11)

Fonctions à arguments variables

•  Exemple :

•  Soit une fonction qui doit calculer la somme d'une liste variable de nombres entiers, le nombre exact de nombres à additionner étant fourni en paramètre. L'entête de la fonction s'écrit :

int somme (int n, ...)

•  Les trois points "..." indiquent que la fonction admet une liste d'arguments variable

(12)

Fonctions à arguments variables

•  Dans cette fonction il faut alors déclarer une variable de type va_list, en fait une variable qui va pointer sur les différents arguments de la liste :

int somme (int n, ...) { va_list liste; ...}

•  La variable de type va_list doit être initialisée à l'aide de l'opération va_start qui a besoin pour cela du

paramètre qui précède la liste d'arguments variable :

int somme (int n, ...) { va_list liste;

va_start (liste, n); ...

}

(13)

Fonctions à arguments variables

•  On peut ensuite accéder successivement aux différents arguments de la liste d'arguments variables à l'aide de la macro va_arg qui retourne à chaque fois l'argument

pointé par liste et fait pointer celle-ci sur l'argument suivant.

•  Enfin, quand elle a fini son traitement, la fonction doit utiliser l'opération va_end pour clore l'accès à la liste d'arguments variable.

(14)

Fonctions à arguments variables

int somme (int n, ...) {

va_list liste;

int cpt, resultat=0;

va_start (liste, n);

for (cpt= 0; cpt< n; cpt++)

resultat += va_arg (liste, int);

va_end(liste);

return resultat;

}

Déclaration de la liste d’arguments Initialisation de la liste sur l’élément qui suit n

Accès au 1er

élément de la liste Accès au 2ème élément de la liste Accès au 3ème élément de la liste … Fin d’utilisation de la liste

(15)

Fonctions à arguments variables

•  Exemple d’appel :

somme (4,1,2,3,4);

(16)

Fonctions à arguments variables

•  Question :

•  Est-il possible d’écrire une fonction qui ne prend qu’une liste d’arguments variables ?

int f(…)

(17)

Exercices

•  Concevoir une fonction "moyenne" qui calcule la moyenne d'un nombre n donné mais variable de réels.

•  Concevoir une fonction "concaténation" qui concatène un nombre n donné mais variable de chaînes de caractères et les stocke dans une chaîne destination.

(18)

Solution 1

#include <stdio.h>

#include <stdarg.h>

/* n : le nombre de reels dans la liste d'arguments variable ... : une liste d'arguments de type double variable

Resultat : la moyenne des reels de la liste d'arguments variable */

double moyenne (int n, ...) {

va_list listeReels; int cptrArgs; double somme;

va_start (listeReels, n);

for (somme = cptrArgs = 0; cptrArgs < n; cptrArgs++) somme += va_arg (listeReels, double);

va_end (listeReels);

return (n != 0) ? (somme / n) : 0;

}

(19)

Solution 1

/* Le programme de test */

int main() {

printf("moyenne(2, 4.0, 6.0) = %f\n", moyenne(2, 4.0, 6.0));

printf("moyenne(4, 4.5, 6.0, 7.25, 8.75) = %f\n", moyenne(4, 4.5, 6.0, 7.25, 8.75));

printf("moyenne(0) = %f\n", moyenne(0));

}

(20)

Solution 2

•  Comme il faut d'abord connaître la taille de la chaîne destination, il faut traiter deux fois la liste d'arguments

variable, une fois pour calculer la taille de la destination et une deuxième fois pour y stocker les chaînes.

#include <stdio.h>

#include <string.h>

•  #include <stdarg.h>

•  /* La fonction concat Arguments : n : le nombre de

chaines dans la liste d'arguments variable ... : une liste d'arguments de type char * variable

Resultat : la concatenation des chaines */

(21)

Solution 2

char *concat (int n, char* resultat, size_t taille_max, ...) { va_list liste; int cpt; char* chaine;

size_t taille=strlen(resultat);

va_start(liste, taille_max);

for (cpt = 0; cpt < n; cpt++) { chaine=va_arg(liste, char*);

if (taille+strlen(chaine)<=taille_max) strcat(resultat, chaine);

else{

strncat (resultat, chaine, taille_max-taille);

taille=taille_max;

break;

}

taille+=strlen(chaine);

}

resultat[taille]=‘\0’;

va_end(liste);

return resultat;

}

(22)

Solution 2

int main(int argc, char* argv[]){!

char* s = (char*) malloc(50); !

s=concat(4, s, 49, "ceci", "est", "un", "test");!

printf("s=%s\n",s);!

s=concat(10, s, 49, "ceci", "est", "un", ! "nouveau", "test", "un", "peu", "plus”,!

"long", "colle a la suite de l'autre chaine");!

printf("s=%s\n",s);!

free(s);!

return EXIT_SUCCESS;!

}!

Références

Documents relatifs

La lutte contre les OGM issus de la trangénèse est là aussi pour nous rappeler qu'il a fallu du temps pour obtenir des victoires, victoires qui restent fragiles. Mais nous avons

‘’ pseudo goutteuses ’’ en particulier chez les sujets âgés +++ (cause la plus fréquente d ’ arthrite aiguë à cette période de la vie ) facteurs

Ornella. C’est un nombre avec 8 chiffres. Mais es-tu d’accord pour dire que 1 milliard existe ? Ornella.. Ce problème a été proposé par Jordan Detaille au GEM et développé

Figure 2: Total search time, number of (pro- and con-) arguments and total number of sentences searched for different input document sizes; mean and standard deviation across 10

Des données probantes mises de l’avant dans ce document révèlent que les immigrants, les réfugiés et les groupes ethnoculturels ou racialisés du Canada sont plus exposés

associées, dont on peut estimer qu'elles ont une

(2) En d´ eduire la fonction supprime qui prend en arguments une liste L et un nombre n et supprime le premier ´ el´ ement de la liste ´ egal ` a n.. Cette fonction renverra True si

Si, en parcourant la liste L , X a déjà été lu K fois, et que N représente la longueur déjà reconnue comme la plus longue, pour une certaine valeur V, et si Y est l'élément