Quelle est la signification de cette déclaration?

Je ne suis pas un spécialist en C / C ++.

J'ai trouvé cette déclaration aujourd'hui:

typedef NS_OPTIONS(NSUInteger, PKRevealControllerType) { PKRevealControllerTypeNone = 0, PKRevealControllerTypeLeft = 1 << 0, PKRevealControllerTypeRight = 1 << 1, PKRevealControllerTypeBoth = (PKRevealControllerTypeLeft | PKRevealControllerTypeRight) }; 

Pouvez-vous traduire les valeurs que chaque valeur aura?

opertor << est un opérateur de décalage vers la gauche. Décale tous les bits vers la gauche un nombre de fois spécifié: (décalage arithmétique à gauche et bit de signe de réserve)

 m << n 

Décale tous les bits de m à gauche un certain nombre de fois. ( remarquez un quart == multipliez par deux ).

1 << 0 signifie pas de décalage donc son égal à 1 seulement.

1 << 1 signifie un décalage donc son égal à 1*2 = 2 seulement.

J'explique avec un octet: un en un octet est comme:

  MSB +----+----+----+---+---+---+---+---+ | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 +----+----+----+---+---+---+---+---+ 7 6 5 4 3 2 1 / 0 | / 1 << 1 | | ▼ ▼ +----+----+----+---+---+---+---+---+ | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 2 +----+----+----+---+---+---+---+---+ 7 6 5 4 3 2 1 0 

Alors que 1 << 0 ne fait rien d'autre que son semblable. (Notez le bit 7 est copié pour préserver le signe)

OU opérateur: faire un peu sage ou

  MSB PKRevealControllerTypeLeft +----+----+----+---+---+---+---+---+ | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | == 1 +----+----+----+---+---+---+---+---+ 7 6 5 4 3 2 1 0 | | | | | | | | OR MSB PKRevealControllerTypeRight +----+----+----+---+---+---+---+---+ | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | == 2 +----+----+----+---+---+---+---+---+ 7 6 5 4 3 2 1 0 = MSB PKRevealControllerTypeBoth +----+----+----+---+---+---+---+---+ | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | == 3 +----+----+----+---+---+---+---+---+ 7 6 5 4 3 2 1 0 

| est un opérateur peu sage. dans le code ci-dessous or 1 | 2 1 | 2 == 3

 PKRevealControllerTypeNone = 0, // is Zero PKRevealControllerTypeLeft = 1 << 0, // one PKRevealControllerTypeRight = 1 << 1, // two PKRevealControllerTypeBoth = (PKRevealControllerTypeLeft | PKRevealControllerTypeRight) // three 

Il n'y a pas plus de raison technique pour initialiser des valeurs comme celle-ci, en définissant comme cela que les choses s'alignent joliment lire cette réponse: définir QUELQUE CHOSE (1 << 0)

l'optimization du compilateur les convertit en plus simple pour comme: ( je ne suis pas sûr pour le troisième, mais je pense que le compilateur l'optimisera aussi )

 PKRevealControllerTypeNone = 0, // is Zero PKRevealControllerTypeLeft = 1, // one PKRevealControllerTypeRight = 2, // two PKRevealControllerTypeBoth = 3, // Three 

Edit: @ merci à Till. lisez cette réponse Les états d'application avec les indicateurs BOOL montrent l'utilité des déclarations que vous avez obtenues en utilisant des opérateurs bit-wise.

C'est une énumération de drapeaux de bits:

 PKRevealControllerTypeNone = 0 // no flags set PKRevealControllerTypeLeft = 1 << 0, // bit 0 set PKRevealControllerTypeRight = 1 << 1, // bit 1 set 

Et alors

 PKRevealControllerTypeBoth = (PKRevealControllerTypeLeft | PKRevealControllerTypeRight) 

est juste le résultat d'un OU binary des deux autres drapeaux. Donc, le bit 0 et le bit 1 sont définis.

L'opérateur << est l'opérateur de décalage gauche. Et le | l'opérateur est au niveau du bit OU.

En résumé, les valeurs résultantes sont:

 PKRevealControllerTypeNone = 0 PKRevealControllerTypeLeft = 1 PKRevealControllerTypeRight = 2 PKRevealControllerTypeBoth = 3 

Mais il est beaucoup plus logique d'y penser en termes de drapeaux de bits. Ou en tant qu'set où l'set universel est: {PKRevealControllerTypeLeft, PKRevealControllerTypeRight}

Pour en savoir plus, vous devez vous renseigner sur les énumérations, les opérateurs de décalage et les opérateurs au niveau du bit.

Cela ressemble à Objective C et pas C ++, mais indépendamment:

 1 << 0 

est juste un bit à gauche (en haut) par 0 positions. Tout entier "<< 0" est juste lui-même.

Alors

 1 << 0 = 1 

De même

 1 << 1 

est juste un bitbifted à gauche par 1 position. Lequel vous pouvez visualiser un certain nombre de façons, mais le plus simple est de multiplier par 2. [Note 1]

Alors

 x << 1 == x*2 

ou

 1 << 1 == 2 

Enfin, l'opérateur de tuyau unique est un bit ou .

Alors

 1 | 2 = 3 

tl; dr:

 PKRevealControllerTypeNone = 0 PKRevealControllerTypeLeft = 1 PKRevealControllerTypeRight = 2 PKRevealControllerTypeBoth = 3 

[1] Il y a quelques limitations sur cette généralisation, par exemple quand x est égal ou supérieur à 1/2 la plus grande valeur pouvant être stockée par le type de données.

Tout cela revient à l'arithmétique bit à bit.

PKRevealControllerTypeNone a une valeur de 0 (binary 0000)

PKRevealControllerTypeLeft a une valeur de 1 (binary 0001)

PKRevealControllerTypeRight a une valeur de 2 (binary 0010) car 0001 décalé vers la gauche 1 bit est 0010

PKRevealControllerTypeBoth a une valeur de 3 (binary 0011) depuis 0010 | 0001 (ou fonctionne comme addition) = 0011

Dans le context, cela est très probablement utilisé pour déterminer une valeur. La propriété est & (ou bitwise-and ) fonctionne de manière similaire à la multiplication. Si 1 ets avec un nombre, alors le nombre est conservé, si 0 et avec un nombre, alors le nombre est effacé.

Ainsi, si vous voulez vérifier si un controller particulier est spécifiquement de type Left et qu'il a une valeur de 0010 (ie type Right ) 0010 & 0001 = 0 qui est faux comme prévu (donc, vous avez déterminé qu'il n'est pas du type correct ). Cependant, si le controller est à la Both 0011 & 0001 = 1 , le résultat est vrai, ce qui est correct puisque nous avons déterminé qu'il s'agit des Both types.