Pas de dépendances
#include <stdio.h> #define OPTION_1 1 #define OPTION_2 2 #define OPTION_3 4 void fonc(int flags) { if (flags&OPTION_1) printf("Option 1 activee\n"); if (flags&OPTION_2) printf("Option 2 activee\n"); if (flags&OPTION_3) printf("Option 3 activee\n"); } int main() { fonc(OPTION_1|OPTION_3); return 0; }
Voici une façon astucieuse de passer des flags dans une fonction sans surcharger plein de parametres. Note : on appelle flag une valeur qui n'est que vraie ou faux (un flag est une variable sur 1 seul bit) Regardons le main : Le parametre passé est : OPTION_1|OPTION_3 Tiens, si vous avez déja fait le tuto sur SDL sur ce meme site, vous avez vu qu'on passait déja des trucs comme ça : SDL_HWSURFACE|SDL_FULLSCREEN par exemple. Voici maintenant comment faire ce genre de fonctions : Regardez la définition de fonc : elle n'attend qu'un seul int. Un int, dans notre cas, c'est 32 bits (si vous etes tres a cheval sur les types qui peuvent changer en fonction du processeurs, c'est que vous etes assez calé pour adapter vous meme) Bref, un int, c'est 32 bits, ça peut donc - en théorie - stocker 32 flags, donc 32 options (vrai/fausses). Voici l'astuce : A coup de #define, on va définir nos flags, mais pas n'importe comment. On va leur donner comme valeur : 1,2,4,8,16,32,64,128,256,512,1024,2048.... -> Que des puissances de 2. Maximum 2^31 = 2147483648 pour 32 bits. Pourquoi des puissances de 2 ? Parce que, en binaire cela s'écrit ainsi : 1 = 00000001 2 = 00000010 4 = 00000100 8 = 00001000 16= 00010000 32= 00100000 etc... Du coup, et la est l'astuce : quand vous faites OPTION_1|OPTION_3, le | est bien sur le OU logique. Et OPTION_1|OPTION_3 = 00000001|00000100 = 00000101 Vous accumulez ainsi plusieurs flags dans un seul int :) Ainsi, vous passez a la fonction OPTION_1|OPTION_3 = 00000101 = 5. Note : dans cette optique, un + a la place du | ferait exactement la meme chose : mais le + serait un chouia plus lent car il testerait les retenues, chose qui n'est pas testéé pour un |, que le processeur effectue plus vite. Récupération dans la fonction : *************************************** Bon, maintenant, on a envoyé "5" dans la fonction fonc, on veut récupérer que c'est 1 | 4 = OPTION_1|OPTION_3 Nous nous servons de l'opérateur & avec les memes options. Ainsi, on obtiendra, soit 0 si le flag n'est pas activé, soit nu nombre >0 si le flag est activé. Rappelez vous que if(0) donne faux, et que if (1) ou if (x) donne vrai (avec x>0) Si cela vous gene, c'est absolument équivalent à : if ((flags&OPTION_1)!=0) Note : attention, mettez bien les parentheses, cas si vous mettez : if (flags&OPTION_1!=0), le compilo comprendra : if (flags&(OPTION_1!=0)) et ça ne fera pas ce que vous attendez... Voila cette astuce pour la gestiond de flags que je trouve élégante, et qui est surtout ultra rapide (les opérations sur les bits comme | et & sont les plus rapides qu'un processeur sache faire...) De plus, passer juste un int au lieu de 30 char est bien sur infiniment plus rapide. Nous avons affaire la a une astuce qui, non content d'etre élégante, est également puissante en terme d'optimisations. A consommer sans modérations.