Une variable qui en contient d'autres en C

Vous en avez marre d’avoir des fonctions C avec un maximum de paramètres qui rendent le code illisible. Par exemple :

char *prompt (int afficher_nom, int afficher_host, int afficher_pwd, int couleurs);
/* ou les afficher_* valent 0 ou 1 suivant si on veut que l'action s'éxecute.) */

Clairement en plus d’être imbuvable votre prototype n’est pas bon en terme de mémoire, un int est beaucoup trop grand pour contenir une variable booléenne. Il y a une technique pour n’utiliser qu’une seule variable de type unsigned int qu’on appellera flags (ce nom vous dit peut être déjà quelque chose). On va pouvoir transmettre plusieurs informations dans cette unique variable.

NOTA : Je vais juste vous expliquer comment faire dans la pratique, mais je ne vais pas expliquer pourquoi ça marche. La technique s’appuie sur les opérateurs binaires et sur l’algèbre de Boole.

Donc on va mettre ceci dans notre header, le prototype de notre fonction est beaucoup plus lisible :

#ifndef H_HEADER
#define H_HEADER
#define NOM      (0)
#define HOST     (1)
#define PWD      (2)
#define COULEURS (4)
/* Notez que tous les flags doivent être une puissance de 2
* 0  1 2  4  8  16  32  64  128  512  1024 etc */
/* Prototype de la fonction */
char *prompt(unsigned int flags);
#endif /* H _HEADER */
/* Pour avoir que flags contienne juste NOM et COULEURS, on fait comme ceci : */
flags = NOM | COULEURS;
/* Si on veut rajouter un flags (HOST par exemple) : */
flags |= HOST;
/* Si par la suite on veut supprimer un flags (NOM par exemple) : */
flags &= ~NOM;
/* Pour tester si un flags est dans notre variable (COULEURS par exemple) : */
if (flags & COULEURS)
{
/* Ce test sera vrai seulement si COULEURS est dans flags */
}

Un dernier petit code pour l’exemple :

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
unsigned int toto = COULEURS | NOM | PWD;
char *pwd = get_current_dir_name();
char *prompt;
if(pwd)
free(pwd);
/* On enlève PWD */
else
toto &= ~PWD;
/* On rajoute HOST */
toto |= HOST;
/* On appelle la fonction */
prompt = prompt(toto);
/* .... */
return 0;
}
/* suite du code */

Voilà, abusez de cette technique infiniment pratique.

Voir à ce sujet ce tutoriel.