Je suis curieux de connaître ce code:
cout << 'test'; // Note the single quotes.
me donne une sortie de 1952805748
.
Ma question: la sortie est-elle une adresse en mémoire ou quelque chose?
C'est un littéral multi-caractères. 1952805748
est 0x74657374
, qui se décompose en
0x74 -> 't'
0x65 -> 'e'
0x73 -> 's'
0x74 -> 't'
Edit:
norme C++, §2.14.3/1 - Littéraux de caractères
(...) Un littéral de caractère ordinaire contenant plus d'un c-char est un littéral à plusieurs caractères. Un littéral multicaractère a une valeur de type int et une valeur définie par implémentation.
Non, ce n'est pas une adresse. C'est le soi-disant caractère multi-octets.
En règle générale, il s’agit des valeurs ASCII) des quatre caractères combinés.
't' == 0x74; 'e' == 0x65; 's' == 0x73; 't' == 0x74;
Donc 0x74657374 est 1952805748.
Mais cela peut aussi être 0x74736574 sur un autre compilateur. Les normes C et C++ indiquent toutes deux que la valeur des caractères multi-octets est définition d'implémentation. En règle générale, son utilisation est fortement déconseillée.
Un littéral de caractère ordinaire contenant plus d'un c-char est un littéral à plusieurs caractères. Un littéral multicaractère a une valeur de type int et une valeur définie par 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 valorise une constante de caractère multi-caractère, un caractère à la fois, en décalant la valeur précédente laissée par le nombre de bits par caractère cible, puis en reprenant le motif de bits du nouveau caractère tronqué à la largeur d'une cible. personnage. Le modèle de bits final est de type int et est donc signé, que les caractères soient signés ou non.
Consultez l'explication dans cette page pour plus de détails
Ils sont vraiment juste int
s. Ils sont largement utilisés dans l'énum de l'API Core Audio, par exemple, dans le CoreAudioTypes.h
En tête de fichier,
enum
{
kAudioFormatLinearPCM = 'lpcm',
kAudioFormatAC3 = 'ac-3',
kAudioFormat60958AC3 = 'cac3',
kAudioFormatAppleIMA4 = 'ima4',
kAudioFormatMPEG4AAC = 'aac ',
kAudioFormatMPEG4CELP = 'celp',
} ;
Il y a beaucoup de discussions sur le fait que cela n'est pas "indépendant de la plate-forme", mais lorsque vous utilisez une API qui est faite pour une plate-forme spécifique, qui se soucie de la portabilité. Vérifier l'égalité sur la même plate-forme n'échouera jamais. Ces enum
'd valeurs sont plus faciles à lire et contiennent réellement leur identité dans leur valeur, ce qui est plutôt joli.
Ce que j’ai essayé de faire ci-dessous, c’est d’envelopper un littéral 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 en dessous.
#include <stdio.h>
#define MASK(x,BYTEX) ((x&(0xff<<8*BYTEX))>>(8*BYTEX))
struct Multibyte
{
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);
}
char operator[]( 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, const char * argv[])
{
Multibyte( 'abcd' ).println() ;
Multibyte( 'x097' ).println() ;
Multibyte( '\"\\\'\'' ).println() ;
Multibyte( '/*|' ).println() ;
Multibyte( 'd' ).println() ;
return 0;
}
Ce type de fonctionnalité est vraiment utile lorsque vous construisez des analyseurs syntaxiques. Considère ceci:
byte* buffer = ...;
if(*(int*)buffer == 'GET ')
invoke_get_method(buffer+4);
Ce code ne fonctionnera probablement que sur une endianess spécifique et pourrait traverser différents compilateurs