wiki:InsiaProgCSyntaxe5

Sommaire

Syntaxe - C avancé

1. Goto et labels

Dans la famille des langages structurés, comme le C, le flux d'exécution du programme et définit par des blocs et des articulations entre ces blocs (if, for, while, etc.). Le langage C a gardé une construction qui est considérée comme un abus de langage et très souvent fortement déconseillée. Toutefois, en l'absence de mécanisme d'exception en C (gestion des erreurs), cette instruction peut s'avérer utile.

L'instruction goto permet de sauter directement et inconditionnellemnent à l'instruction qui suit le label du même nom. Il n'est pas possible de sortir d'une fonction avec goto, les labels sont nécessairement locaux. Dans l'exemple suivant, le message n'est jamais affiché:

int main(int argc, char** argv) {
  goto no_message;
  printf("Ceci est un message\n");

no_message:
  return 0;
}

Le nom du label suit les mêmes restrictions que celles des variables. Il peut se placer avant n'importe quelle instruction. On représente souvent un label en retrait de l'indentation normale afin de mieux l'identifier et de marquer son rôle "structurel".

2. Fonctions: paramètres variables

Il est possible de définir une fonction qui peut prendre un nombre d'arguments variable en C. C'est en particulier le cas de la fameuse fonction printf. Pour cela il suffit de mettre en dernier argument du prototype de la fonction le symbole ... (3 points), et d'utiliser les macros définies dans stdarg(3).

float moyenne_classe(int nb_eleves, ...) {
  va_list args;
  int i, somme = 0;

  va_start(args, nb_eleves);
  for (i = 0; i < nb_eleves; i++) somme += va_arg(args, int);
  va_end(args);

  return (float)somme / nb_eleves;
}

Ce mécanisme a plusieurs limites:

  • la fonction doit posséder au moins un paramètre fixe (il est nécessaire pour la macro va_start)
  • la façon de déduire le nombre d'arguments et leur type est à la discrétion du programmeur

A noter que la plupart des compilateurs savent reconnaître une chaîne de formatage "à la printf" et vérifier sommairement si le nombre d'arguments et leur type correspond à ce qui est décrit dans cette chaîne.

On peut aussi se retrouver dans le cas où l'on "surcharge" une fonction existante et on veut simplement faire passer les arguments variables à une autre fonction. En général une fonction qui accepte un nombre variable de paramètres est également disponible sous une forme où elle accepte directement un type va_list (comme printf et vprintf):

void log_info(char* message, ...) {
  va_list args;

  if (log_level < DEBUG) return;

  va_start(args, message);
  vprintf(message, args);
  va_end(args);
}

log_info("reseau: adresse %s invalide", adresse);

3. Directives de compilation

Les mots-clés suivants influent sur la façon dont certains éléments (variables et fonctions) sont compilés et en particulier ont un effet sur l'édition des liens. Ils sont couramment utilisés dans des programmes avancés.

static

Ce mot-clé n'est présent que dans les fichiers .c et signifie que la variable globale ou la fonction désignée ne peut pas être utilisée depuis un autre fichier C du même projet (l'édition des liens sera refusée). C'est une façon d'affirmer que sa fonction est "privée" et son usage limité au fichier C courant.

static int x;
static void test() {
  printf("test\n");
}

Note: static a un sens précis sur les variables locales en C++, tandis que ceci n'est tout simplement pas autorisé en C.

extern

Ce mot-clé précède la déclaration d'une variable globale ou d'une fonction, et signale que l'implémentation n'est pas fournie dans le fichier C en cours de compilation. L'élément sera recherché dans l'ensemble du projet (fichiers C, bibliothèques supplémentaires) au moment de l'édition des liens. C'est en fait le mécanisme sous-entendu pour chaque déclaration de prototype du C.

inline

Normalement la compilation d'une fonction donne lieu a un code machine distinct qui peut être appelé depuis n'importe quelle partie du programme. Pour des fonctions simples et spécialisées, il est parfois plus rapide de remplacer un appel à la fonction, par la fonction elle-même:

inline int produit(int a, int b) { return a * b; }

Il est important de comprendre que dans ce cas la fonction doit être considérée comme "static", car celle-ci ne produit pas de code générique (appelable selon le mécanisme standard) et donc ne peut pas intervenir dans l'édition des liens.

Note: comme une fonction "inline" ne génère pas de code propre, il est possible de la déclarer dans les fichiers .h. On a alors un mécanisme comparable aux macros, mais syntaxiquement plus sophistiqué.

4. Illustration

Il se passe beaucoup de choses quand vous quittez votre programme C, que ce soit explicitement avec exit() ou en utilisant return dans la fonction "main". Jetons un petit coup d'oeil dans linux/kernel/exit.c...

Last modified 14 years ago Last modified on Dec 18, 2006, 10:49:44 AM

Attachments (1)

Download all attachments as: .zip