Sono curioso di questo codice:
cout << 'test'; // Note the single quotes.
mi dà un output di 1952805748
.
La mia domanda: l'output è un indirizzo in memoria o qualcosa del genere?
Sono curioso di questo codice:
cout << 'test'; // Note the single quotes.
mi dà un output di 1952805748
.
La mia domanda: l'output è un indirizzo in memoria o qualcosa del genere?
Risposte:
È un letterale multi-personaggio. 1952805748
è 0x74657374
, che si decompone come
0x74 -> 't'
0x65 -> 'e'
0x73 -> 's'
0x74 -> 't'
Modificare:
Standard C ++, §2.14.3 / 1 - Letterali dei caratteri
(...) Un letterale carattere ordinario che contiene più di un c-char è un letterale multicaratterico. Un letterale multicharacter ha tipo int e valore definito dall'implementazione.
sizeof(int)
sia definita anche l'implementazione. Quindi non solo viene definita l'implementazione dell'ordine di archiviazione, ma anche la lunghezza massima di questi.
No, non è un indirizzo. È il cosiddetto personaggio multibyte.
In genere, sono i valori ASCII dei quattro caratteri combinati.
't' == 0x74; 'e' == 0x65; 's' == 0x73; 't' == 0x74;
Quindi 0x74657374 è 1952805748.
Ma può anche essere 0x74736574 su qualche altro compilatore. Gli standard C e C ++ affermano entrambi che il valore dei caratteri multibyte è definito dall'implementazione . Quindi generalmente il suo uso è fortemente scoraggiato.
int
sono 4 byte sulla maggior parte delle macchine, non penso che abbia senso usare più di 4 byte. Sì, doveva essere un modo conveniente per scrivere alcune costanti, ma sfortunatamente compilatori diversi l'hanno interpretato in modo diverso, quindi oggigiorno la maggior parte degli stili di codifica ne scoraggia l'uso.
==
dovrebbe verificare
Un letterale personaggio ordinario che contiene più di un c-char è un letterale multicaratterico. Un letterale multicharacter ha tipo int e valore definito dall'implementazione.
Il comportamento definito dall'implementazione deve essere documentato dall'implementazione. ad esempio in gcc puoi trovarlo qui
Il compilatore valuta una costante di carattere multi-carattere un carattere alla volta, spostando il valore precedente lasciato dal numero di bit per carattere di destinazione e quindi inserendo il modello di bit del nuovo carattere troncato alla larghezza di una destinazione carattere. Il bit-pattern finale è di tipo int, ed è quindi firmato, indipendentemente dal fatto che i singoli caratteri siano firmati o meno.
Controlla la spiegazione in questa pagina per maggiori dettagli
Sono davvero solo int
s. Sono ampiamente utilizzati nell'enum API Core Audio, ad esempio nel CoreAudioTypes.h
file header,
enum
{
kAudioFormatLinearPCM = 'lpcm',
kAudioFormatAC3 = 'ac-3',
kAudioFormat60958AC3 = 'cac3',
kAudioFormatAppleIMA4 = 'ima4',
kAudioFormatMPEG4AAC = 'aac ',
kAudioFormatMPEG4CELP = 'celp',
} ;
Ci sono molte chiacchiere sul fatto che questo non sia "indipendente dalla piattaforma", ma quando si utilizza un API creato per una piattaforma specifica, a cui interessa la portabilità. Il controllo dell'uguaglianza sulla stessa piattaforma non fallirà mai. Questi enum
valori sono più facili da leggere e in realtà contengono la loro identità nel loro valore , il che è piuttosto carino.
Quello che ho provato a fare di seguito è avvolgere letteralmente un carattere multibyte in modo che possa essere stampato (su Mac funziona). La cosa strana è che se non si utilizzano tutti e 4 i caratteri, il risultato diventa errato di seguito.
#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;
}
Questo tipo di funzionalità è davvero utile quando si creano parser. Considera questo:
byte* buffer = ...;
if(*(int*)buffer == 'GET ')
invoke_get_method(buffer+4);
Questo codice probabilmente funzionerà solo su endianess specifici e potrebbe essere suddiviso tra diversi compilatori