En C++, les struct
permettent d’agréger des variables (donc des données) avec des services dédiés à la manipulation de ces données (qu’on appelle des méthodes, mais qui sont de simples fonctions). Cette implémentation est la mise en oeuvre du paradigme de la programmation orientée objet. Le C++ introduit également le mot-clef class
, qui se distingue du mot-clef struct
, pour désigner des objets qui sont sémantiquement identiques, mais avec des règles d’encapsulation différentes… Je ne vais pas rentrer dans ces détails ici, pour ne pas compliquer les choses, et considérer que, pour le moment, tu peux t’en tenir aux struct
. Mais, oui, tu as tout intérêt à creuser ces notions fondamentales de ton côté !
Maintenant pour en revenir aux “bouts de code que tu ne comprends pas”, c’est pas compliqué. C++ te permet de définir ce que l’on appelle des macros qui seront traitées par le préprocesseur, qui va modifier le code source avant la compilation. Par exemple, dans mon code, j’ai défini la macro GEOMETRIC
ainsi :
/**
* 0 for an arithmetical progression
* 1 for a geometrical progression
*/
#define GEOMETRIC 0
Autrement dit, si je veux que le changement de taille de la raquette suive une progression arithmétique, je dois écrire ceci :
#define GEOMETRIC 0
Mais si je veux qu’il suive une progression géométrique, je dois écrire cela :
#define GEOMETRIC 1
Le préprocesseur va analyser le code source et y apporter des modifications en fonction des directives de précompilation qu’il va y trouver. Par exemple, partout où il trouvera la chaîne GEOMETRIC
, il la substituera avec la valeur qu’elle représente (donc 0
ou 1
, en fonction de ce que tu auras défini dans la macro).
Mais il remplacera aussi ce bout de code :
#if GEOMETRIC
float_t fh;
#endif
en fonction de la valeur représentée par GEOMETRIC
, donc :
-
si
GEOMETRIC
vaut 1, il substituera le code ci-dessus par un simple :float_t th;
-
et si
GEOMETRIC
vaut 0, alors il le remplacera par… rien du tout ! Autrement dit, le bout de code compris entre#if
et#endif
sera tout simplement supprimé.
Même chose pour ce qui se passe dans la méthode update()
. Autrement dit :
-
si
GEOMETRIC
vaut0
, la fonctionupdate()
se réduit à :void update() { if (sizing) { if (h == th) sizing = false; else h += th - h < 0 ? -2 : 2; } uint8_t h2 = .5f * h; if (y < h2) y = h2; else if (y + h2 > SCREEN_H) y = SCREEN_H - h2; }
-
par contre, si
GEOMETRIC
vaut1
, alors la fonctionupdate()
devient :void update() { if (sizing) { float_t dh = th - fh; if (abs(dh) < 1) { h = th; sizing = false; } else { fh += .5f * dh; if (abs(fh - h) > 1.5f) h += fh < h ? -2 : 2; } } uint8_t h2 = .5f * h; if (y < h2) y = h2; else if (y + h2 > SCREEN_H) y = SCREEN_H - h2; }
Pratique, nan ?