C'est un littéral à plusieurs caractères. 1952805748est 0x74657374, qui se décompose en
0x74->'t'0x65->'e'0x73->'s'0x74->'t'
Éditer:
Norme C ++, §2.14.3 / 1 - Littéraux de caractères
(...) Un littéral de caractère ordinaire qui contient plus d'un caractère C est un littéral multicaractère. Un littéral multicaractère a un type int et une valeur définie par l'implémentation.
Vous n'avez pas mentionné qu'il s'agit d'une implémentation définie.
Thomas Bonini
2
Je suppose que le plus drôle de cette définition est que l' sizeof(int)implémentation est également définie. Ainsi, non seulement l'implémentation de l'ordre de stockage est définie, mais la longueur maximale de ceux-ci l'est également.
bobobobo
74
Non, ce n'est pas une adresse. C'est le soi-disant caractère multi-octets.
Il s'agit généralement des valeurs ASCII des quatre caractères combinés.
't'==0x74;'e'==0x65;'s'==0x73;'t'==0x74;
Donc, 0x74657374 est 1952805748.
Mais il peut également s'agir de 0x74736574 sur un autre compilateur. Les normes C et C ++ indiquent que la valeur des caractères multi-octets est définie par l'implémentation . Donc, généralement, son utilisation est fortement déconseillée.
La longueur d'un tel caractère multi-octets est-elle limitée à 4 octets? Est-ce que cela représente un int écrit en caractères?
Giorgio
2
@Giorgio: La norme dit seulement que sa mise en œuvre est définie, sans plus de détails. En pratique, comme il inty a 4 octets sur la plupart des machines, je ne pense pas qu'il soit logique d'utiliser plus de 4 octets. Oui, il était destiné à être un moyen pratique d'écrire certaines constantes, mais malheureusement, différents compilateurs l'ont interprété différemment, donc de nos jours la plupart des styles de codage découragent son utilisation.
chys
2
@chys: Et le fait qu'il soit défini par l'implémentation signifie qu'il n'est même pas nécessaire d'être cohérent. Un compilateur conforme pourrait donner à tous les littéraux multicaractères la valeur 0, par exemple (bien que ce ne soit pas convivial).
Keith Thompson,
2
Il faut se demander pourquoi cette fonctionnalité loufoque existe dans la norme. Cela semble être un cas d'utilisation si rare, l'implémentation est de toute façon définie et peut être effectuée assez clairement avec un décalage de bits ordinaire et / ou si nécessaire.
Boann
1
@Boann Oui , mes sentiments exactement. Mais vous pouvez l'utiliser en toute sécurité dans les commutateurs et ainsi de suite, comme comparaison directe pour le ==vérifier
bobobobo
18
Un littéral de caractère ordinaire qui contient plusieurs caractères C est un littéral multicaractère. Un littéral multicaractère a un type int et une valeur définie par l'implémentation.
Le comportement défini par l'implémentation doit être documenté par l'implémentation. par exemple dans gcc vous pouvez le trouver ici
Le compilateur évalue une constante de caractère à plusieurs caractères un caractère à la fois, décalant la valeur précédente laissée par le nombre de bits par caractère cible, puis -ou dans le modèle binaire du nouveau caractère tronqué à la largeur d'une cible personnage. Le motif binaire final est donné de type int et est donc signé, que les caractères individuels soient signés ou non.
Consultez l'explication de cette page pour plus de détails
Ce sont vraiment des ints. Ils sont largement utilisés dans les énumérations de l'API Core Audio, par exemple, dans le CoreAudioTypes.hfichier d' en- tête,
Il y a beaucoup de bavardages à propos de ce qui n'est pas "indépendant de la plate-forme", mais lorsque vous utilisez une API conçue pour une plate-forme spécifique, qui se soucie de la portabilité. La vérification de l'égalité sur la même plate-forme n'échouera jamais. Ces enumvaleurs sont plus faciles à lire et contiennent en fait leur identité dans leur valeur , ce qui est plutôt agréable.
Ce que j'ai essayé de faire ci-dessous est d'envelopper un littéral de caractères multi-octets pour qu'il puisse être imprimé (sur Mac, cela fonctionne). Ce qui est étrange, c'est que si vous n'utilisez pas les 4 caractères, le résultat devient faux ci-dessous.
#include<stdio.h>#define MASK(x,BYTEX)((x&(0xff<<8*BYTEX))>>(8*BYTEX))structMultibyte{union{int val ;char vals[4];};Multibyte(): val(0){}Multibyte(int in ){
vals[0]= MASK(in,3);
vals[1]= MASK(in,2);
vals[2]= MASK(in,1);
vals[3]= MASK(in,0);}charoperator[](int i ){return val >>(3-i)*8;// works on mac//return val>>i*8 ; // might work on other systems}void println(){for(int i =0; i <4; i++)
putc( vals[i], stdout );
puts("");}};int main(int argc,constchar* argv[]){Multibyte('abcd').println();Multibyte('x097').println();Multibyte('\"\\\'\'').println();Multibyte('/*|').println();Multibyte('d').println();return0;}
"La vérification de l'égalité sur la même plate-forme n'échouera jamais." C'est possible. Passez à Visual Studio xyz et mordez votre langue. Cette bibliothèque a pris une terrible décision.
Courses de légèreté en orbite le
@LightnessRacesinOrbit "Mettez à niveau vers Visual Studio xyz et mordez votre langue." L'API Core Audio est l'API audio système d'OS X, ce n'est donc pas pertinent.
Jean-Michaël Celerier
5
@ Jean-MichaëlCelerier: Très bien; améliorez votre version OSX Clang et mordez votre langue ...
Courses de légèreté en orbite
1
Ce type de fonctionnalité est vraiment bon lorsque vous construisez des analyseurs. Considère ceci:
Réponses:
C'est un littéral à plusieurs caractères.
1952805748
est0x74657374
, qui se décompose enÉditer:
la source
sizeof(int)
implémentation est également définie. Ainsi, non seulement l'implémentation de l'ordre de stockage est définie, mais la longueur maximale de ceux-ci l'est également.Non, ce n'est pas une adresse. C'est le soi-disant caractère multi-octets.
Il s'agit généralement des valeurs ASCII des quatre caractères combinés.
Donc, 0x74657374 est 1952805748.
Mais il peut également s'agir de 0x74736574 sur un autre compilateur. Les normes C et C ++ indiquent que la valeur des caractères multi-octets est définie par l'implémentation . Donc, généralement, son utilisation est fortement déconseillée.
la source
int
y a 4 octets sur la plupart des machines, je ne pense pas qu'il soit logique d'utiliser plus de 4 octets. Oui, il était destiné à être un moyen pratique d'écrire certaines constantes, mais malheureusement, différents compilateurs l'ont interprété différemment, donc de nos jours la plupart des styles de codage découragent son utilisation.==
vérifierLe comportement défini par l'implémentation doit être documenté par l'implémentation. par exemple dans gcc vous pouvez le trouver ici
Le compilateur évalue une constante de caractère à plusieurs caractères un caractère à la fois, décalant la valeur précédente laissée par le nombre de bits par caractère cible, puis -ou dans le modèle binaire du nouveau caractère tronqué à la largeur d'une cible personnage. Le motif binaire final est donné de type int et est donc signé, que les caractères individuels soient signés ou non.
Consultez l'explication de cette page pour plus de détails
la source
Ce sont vraiment des
int
s. Ils sont largement utilisés dans les énumérations de l'API Core Audio, par exemple, dans leCoreAudioTypes.h
fichier d' en- tête,Il y a beaucoup de bavardages à propos de ce qui n'est pas "indépendant de la plate-forme", mais lorsque vous utilisez une API conçue pour une plate-forme spécifique, qui se soucie de la portabilité. La vérification de l'égalité sur la même plate-forme n'échouera jamais. Ces
enum
valeurs sont plus faciles à lire et contiennent en fait leur identité dans leur valeur , ce qui est plutôt agréable.Ce que j'ai essayé de faire ci-dessous est d'envelopper un littéral de caractères multi-octets pour qu'il puisse être imprimé (sur Mac, cela fonctionne). Ce qui est étrange, c'est que si vous n'utilisez pas les 4 caractères, le résultat devient faux ci-dessous.
la source
Ce type de fonctionnalité est vraiment bon lorsque vous construisez des analyseurs. Considère ceci:
Ce code ne fonctionnera probablement que sur un endianess spécifique et pourrait traverser différents compilateurs
la source