Constantes ou enum() ?

muqaddarmuqaddar Administrateur
Je me demande parfois quand il vaut mieux utiliser un enum() ou des constantes.

Exemple:

typedef enum {<br />	DisplayTypeList=0,<br />	DisplayTypeCellar,<br />	DisplayTypeGrid<br />} DisplayType;


ou

#define DISPLAY_TYPE_LIST&nbsp; &nbsp; &nbsp; &nbsp; 0<br />#define DISPLAY_TYPE_CELLAR&nbsp;  1<br />#define DISPLAY_TYPE_GRID&nbsp; &nbsp; &nbsp;  2


pour transmettre des infos d'un contrôleur à  un autre par exemple

controller.displayType = DisplayTypeGrid;


ou

controller.displayType = DISPLAY_TYPE_GRID;

Réponses

  • CéroceCéroce Membre, Modérateur
    septembre 2011 modifié #2
    La première forme est meilleure parce qu'elle est typée:

    - (void) setDisplayType:(DisplayType)type<br />{<br /><br />}
    


    Et en plus, elle t'évite des bêtises, comme utiliser deux fois un même index, ou ajouter un ; superflu à  la fin du #define...
  • muqaddarmuqaddar Administrateur
    14:07 modifié #3
    Ok.

    Vu que un énum est équivalent à  un int, je peux aussi écrire des choses comme :

    [sender tag] == DisplayTypeList
    


    Dernière question:

    typedef enum {<br />	DisplayTypeList=0,<br />	DisplayTypeCellar,<br />	DisplayTypeGrid<br />} DisplayType;
    


    est équivalent à  :

    typedef enum {<br />	DisplayTypeList=0,<br />	DisplayTypeCellar=1,<br />	DisplayTypeGrid=2<br />} DisplayType;
    


    On est d'accord ? On ne l'écrit pas pour aller plus vite?
  • AliGatorAliGator Membre, Modérateur
    14:07 modifié #4
    Oui. Tu peux même faire sauter le "=0" sur le premier.

    C'est utile de les détailler surtout si tu veux faire des sauts entre les différentes valeurs d'enum pour pas qu'ils ne soient tous consécutifs, ce qui peut être utile en particulier si tes enums servent comme masques pour des flags (du coup pour pouvoir être combinés proprement il ne faut pas que les bits de la représentation binaire se chevauchent entre les valeurs, enfin ça dépend de ce que tu veux faire mais bon)
  • CéroceCéroce Membre, Modérateur
    14:07 modifié #5
    Pour finir une astuce. Il est fréquent d'avoir besoin de connaà®tre le nombre de constantes d'une énumération:

    typedef enum {<br />	DisplayTypeList=0,<br />	DisplayTypeCellar=1,<br />	DisplayTypeGrid=2,<br />	DisplayTypes<br />} DisplayType;
    


  • muqaddarmuqaddar Administrateur
    14:07 modifié #6
    dans 1316010564:

    Oui. Tu peux même faire sauter le "=0" sur le premier.

    C'est utile de les détailler surtout si tu veux faire des sauts entre les différentes valeurs d'enum pour pas qu'ils ne soient tous consécutifs.


    Ok !

    dans 1316010964:

    Pour finir une astuce. Il est fréquent d'avoir besoin de connaà®tre le nombre de constantes d'une énumération:

    typedef enum {<br />	DisplayTypeList=0,<br />	DisplayTypeCellar=1,<br />	DisplayTypeGrid=2,<br />	DisplayTypes<br />} DisplayType;
    



    On peut mettre ton pluriel en début de liste ?

    typedef enum {<br />&nbsp; &nbsp; &nbsp; &nbsp; DisplayTypes<br />	DisplayTypeList=0,<br />	DisplayTypeCellar=1,<br />	DisplayTypeGrid=2,	<br />} DisplayType;
    

  • CéroceCéroce Membre, Modérateur
    14:07 modifié #7
    Bien sûr que non, ça profite du fait qu'une constante sans affectation vaut la constante précédente + 1 (rien à  voir avec le pluriel, on l'appelle comme on veut).
  • muqaddarmuqaddar Administrateur
    14:07 modifié #8
    dans 1316011295:

    Bien sûr que non, ça profite du fait qu'une constante sans affectation vaut la constante précédente + 1 (rien à  voir avec le pluriel, on l'appelle comme on veut).


    Ok, j'ai cru à  une convention de nommage avec le pluriel. Je fais trop de Rails.
  • AliGatorAliGator Membre, Modérateur
    14:07 modifié #9
    dans 1316011295:

    Bien sûr que non, ça profite du fait qu'une constante sans affectation vaut la constante précédente + 1 (rien à  voir avec le pluriel, on l'appelle comme on veut).
    J'utilise la même astuce (sauf que je l'appelle "...Count" :D) ;)
  • muqaddarmuqaddar Administrateur
    14:07 modifié #10
    dans 1316024051:

    dans 1316011295:

    Bien sûr que non, ça profite du fait qu'une constante sans affectation vaut la constante précédente + 1 (rien à  voir avec le pluriel, on l'appelle comme on veut).
    J'utilise la même astuce (sauf que je l'appelle "...Count" :D) ;)


    C'est plus propre et moins ambigà¼e. ;)
  • muqaddarmuqaddar Administrateur
    14:07 modifié #11
    Encore une question sur le enum() tant que j'y suis.

    typedef enum _ASIAuthenticationType {<br />&nbsp;  ASIStandardAuthenticationType = 0,<br />&nbsp;  ASIProxyAuthenticationType = 1<br />} ASIAuthenticationType;
    


    A quoi sert le _ASIAuthenticationType après le enum ?
  • AliGatorAliGator Membre, Modérateur
    septembre 2011 modifié #12
    A pas grand chose puisqu'on peut tout aussi bien faire des enum anonymes du moment qu'on a un typedef.

    Je rappelle (je l'avais déjà  expliqué dans un autre thread je crois) que la syntaxe du typedef est : [tt]typedef {type détaillé} {alias pour le type}[/tt]

    1) Un enum n'a pas forcément de nom. On peut tout à  fait déclarer une variable de type enum sans donner de nom à  l'enum :
    <br />enum { ValA, ValB, ValC } valeurABC;<br />valeurABC = ValA;<br />...
    


    Mais bien souvent c'est pas pratique car ce type on va le manipuler à  plusieurs endroits dans le code on va déclarer des variables intermédiaires ou des paramètres de méthodes pour faire passer la valeur de valeurABC d'un bout du code à  l'autre, donc on va devoir réutiliser le type qu'on a décrit via l'enum. Du coup on donne un nom à  l'enum, c'est la syntaxe 2

    2) Pour donner un nom quand on déclares l'enum, on utilise la syntaxe suivante :
    enum _ASIAuthenticationType {<br />&nbsp;  ASIStandardAuthenticationType = 0,<br />&nbsp;  ASIProxyAuthenticationType = 1<br />}
    
    Ici tu déclares juste un enum, avec un nom (mais pas de typedef donc pas d'alias sur le "nom complet du type").
    Du coup pour l'utiliser, tu es obligé d'utiliser le nom complet, y compris avec le mot clé "enum". Par exemple pour déclarer une variable avec ce type, tu es obligé de répéter le type complet, avec le mot clé "enum" comme ceci :
    enum _ASIAuthenticationType maVariable;
    


    3) Du coup comme c'est chiant de répéter "enum" à  chaque fois (et pareil pour les types "union" et "struct" c'est le mm problème), on fais en général un typedef :
    typedef enum _ASIAuthenticationType {<br />&nbsp;  ASIStandardAuthenticationType = 0,<br />&nbsp;  ASIProxyAuthenticationType = 1<br />} ASIAuthenticationType;
    
    Du coup avec cette syntaxe, on peut toujours utiliser le type complet "enum _ASIAuthenticationType", mais ou peut aussi utiliser son "alias" qu'on a défini avec typedef, et qu'on a appelé "ASIAuthenticationType" tout simplement. Plus facile à  manipuler

    4) Mais du coup, vu qu'on a défini un alias pour cet enum, on a plus forcément besoin de lui donner un nom pour son nom complet ! Donc du coup autant dans la déclaration du typedef laisser tomber le nom interne de l'enum, comme on a fait en (1), si on ne compte le manipuler qu'au travers de son alias qu'on donne via typedef ! Autrement dit on déclare juste un alias/nom court pour un type (via typedef) en disant que cet alias correspond à  un enum... qui du coup est anonyme car n'a pas besoin de nom complet :
    typedef enum /* nom anonyme */ {<br />&nbsp;  ASIStandardAuthenticationType = 0,<br />&nbsp;  ASIProxyAuthenticationType = 1<br />} ASIAuthenticationType; /* ASIAuthenticationType est l&#039;alias qu&#039;on veut donné, via typedef, à  ce type qu&#039;est l&#039;enum anonyme */
    
  • muqaddarmuqaddar Administrateur
    14:07 modifié #13
    Merci. C'est très clair. Comme d'habitude !
  • devulderdevulder Membre
    14:07 modifié #14
    dans 1316010964:

    Pour finir une astuce. Il est fréquent d'avoir besoin de connaà®tre le nombre de constantes d'une énumération:

    typedef enum {<br />	DisplayTypeList=0,<br />	DisplayTypeCellar=1,<br />	DisplayTypeGrid=2,<br />	DisplayTypes<br />} DisplayType;
    



    Bonjour,

    Pour les constantes qui servent pour des test de branchements, je n'utilise jamais la valeur zéro pour éviter
    une erreur dans le cas d'une variable non initialisée par exemple.

    typedef enum {<br />	DisplayTypeList = 5000,<br />	DisplayTypeCellar,<br />	DisplayTypeGrid,<br />	DisplayTypes<br />} DisplayType;<br /><br />switch(test)<br />{<br />&nbsp; &nbsp; case DisplayTypeList: //code... break;<br />&nbsp; &nbsp; case DisplayTypeCellar: //code... break;<br />}<br /><br />
    

  • AliGatorAliGator Membre, Modérateur
    14:07 modifié #15
    Moi je l'utilise la valeur zéro... pour mettre la valeur unknown (car il faut bien justement initialiser ta variable test à  qqch !
    typedef enum {<br />&nbsp; DisplayTypeUnknown,<br />&nbsp; DisplayTypeCellar,<br />&nbsp; DisplayTypeGrid,<br />&nbsp; ////<br />&nbsp; DisplayTypeCount<br />} DisplayType
    
  • 14:07 modifié #16
    dans 1316073237:

    Moi je l'utilise la valeur zéro... pour mettre la valeur unknown (car il faut bien justement initialiser ta variable test à  qqch !
    typedef enum {<br />&nbsp; DisplayTypeUnknown,<br />&nbsp; DisplayTypeCellar,<br />&nbsp; DisplayTypeGrid,<br />&nbsp; ////<br />&nbsp; DisplayTypeCount<br />} DisplayType
    



    Hmm j'ai du mal à  voir pourquoi.. Si par défaut tu souhaites utiliser un type Cellar, pourquoi ne pas mettre Cellar en premier et virer "Unknown". Tu n'aurais même pas besoin de faire "displayType = DisplayTypeCellar" dans le setup du controlView.
  • AliGatorAliGator Membre, Modérateur
    septembre 2011 modifié #17
    Ah bah ça dépend du cas bien sûr.

    Oui en effet l'exemple du displayType (à  vrai dire j'ai bêtement recopié le contenu de l'enum sans trop chercher à  savoir à  quoi ça correspondait en vrai, mais maintenant que tu le dis...) dans ce cas y'a pas d'intérêt.

    C'est plutôt dans un cas genre
    typedef enum {<br />&nbsp; SexUnknown=0,<br />&nbsp; SexMale,<br />&nbsp; SexFemale,<br />} Sex;
    
    que là  ça a du sens.
  • muqaddarmuqaddar Administrateur
    14:07 modifié #18
    En effet, c'est beaucoup plus parlant !
Connectez-vous ou Inscrivez-vous pour répondre.