Mich interessiert dieser Code:
cout << 'test'; // Note the single quotes.
gibt mir eine Ausgabe von 1952805748
.
Meine Frage: Ist die Ausgabe eine Adresse im Speicher oder so?
Luzidrealität
Mich interessiert dieser Code:
cout << 'test'; // Note the single quotes.
gibt mir eine Ausgabe von 1952805748
.
Meine Frage: Ist die Ausgabe eine Adresse im Speicher oder so?
K-ballo
Es ist ein Literal mit mehreren Zeichen. 1952805748
ist 0x74657374
die zerfällt als
0x74 -> 't'
0x65 -> 'e'
0x73 -> 's'
0x74 -> 't'
Bearbeiten:
C++-Standard, §2.14.3/1 – Zeichenliterale
(…) Ein gewöhnliches Zeichenliteral, das mehr als ein c-char enthält, ist ein Mehrzeichenliteral . Ein aus mehreren Zeichen bestehendes Literal hat den Typ int und einen durch die Implementierung definierten Wert.
Sie haben nicht erwähnt, dass dies implementierungsdefiniert ist.
– Thomas Bonini
18. September 2011 um 15:23 Uhr
Ich nehme an, das Witzigste an dieser Definition ist das sizeof(int)
ist auch die Implementierung definiert. Es wird also nicht nur die Implementierung der Speicherreihenfolge definiert, sondern auch deren maximale Länge.
– bobobobo
28. Dezember 2013 um 16:32 Uhr
chys
Nein, es ist keine Adresse. Es ist das sogenannte Multibyte-Zeichen.
Typischerweise sind es die ASCII-Werte der vier kombinierten Zeichen.
't' == 0x74; 'e' == 0x65; 's' == 0x73; 't' == 0x74;
0x74657374 ist also 1952805748.
Aber es kann auch 0x74736574 auf einem anderen Compiler sein. Die C- und C++-Standards sagen beide, dass der Wert von Multibyte-Zeichen ist Umsetzung definiert. So allgemein ist seine Verwendung stark entmutigt.
Ist die Länge eines solchen Multibyte-Zeichens auf 4 Bytes beschränkt? Dh stellt es ein als Zeichen ausgeschriebenes int dar?
– Giorgio
18. September 2011 um 8:47 Uhr
@Giorgio: Der Standard sagt nur, dass seine Implementierung definiert ist, ohne weitere Details. In der Praxis seit int
auf den meisten Maschinen 4 Bytes beträgt, halte ich es nicht für sinnvoll, mehr als 4 Bytes zu verwenden. Ja, es sollte ein bequemer Weg sein, um einige Konstanten zu schreiben, aber leider haben verschiedene Compiler es unterschiedlich interpretiert, so dass heutzutage die meisten Codierungsstile von seiner Verwendung abraten.
– Chys
18. September 2011 um 8:52 Uhr
@chys: Und die Tatsache, dass es implementierungsdefiniert ist, bedeutet, dass es nicht einmal konsistent sein muss. Ein konformer Compiler könnte beispielsweise allen Literalen mit mehreren Zeichen den Wert 0 geben (obwohl das unfreundlich wäre).
– Keith Thompson
18. September 2011 um 19:28 Uhr
Man muss sich fragen, warum dieses verrückte Feature im Standard existiert. Es scheint ein so seltener Anwendungsfall zu sein, ist die Implementierung sowieso definiert und kann bei Bedarf ganz klar mit gewöhnlicher Bitverschiebung und ODER-Verknüpfung durchgeführt werden.
– Boanne
23. Februar 2013 um 2:11 Uhr
@Bann Jawohl, meine Gefühle genau. Aber Sie können es sicher in Schaltern und so weiter verwenden, als direkten Vergleich für ==
sollte auschecken
– bobobobo
21. Dezember 2013 um 2:07 Uhr
Mouna Cheikhna
Ein gewöhnliches Zeichenliteral, das mehr als ein c-char enthält, ist ein Mehrzeichenliteral. Ein aus mehreren Zeichen bestehendes Literal hat den Typ int und einen durch die Implementierung definierten Wert.
Implementierungsdefiniertes Verhalten muss von der Implementierung dokumentiert werden. zum Beispiel in gcc finden Sie es Hier
Der Compiler wertet eine Mehrzeichen-Zeichenkonstante zeichenweise aus, verschiebt den vorherigen Wert um die Anzahl der Bits pro Zielzeichen nach links und führt dann eine ODER-Verknüpfung im Bitmuster des neuen Zeichens durch, das auf die Breite eines Ziels gekürzt wird Charakter. Das endgültige Bitmuster erhält den Typ int und ist daher vorzeichenbehaftet, unabhängig davon, ob einzelne Zeichen vorzeichenbehaftet sind oder nicht.
Überprüfen Sie die Erklärung in diese Seite für mehr Details
Sie sind wirklich gerecht int
S. Sie werden ausgiebig in den Enums der Core Audio API verwendet, zum Beispiel in der CoreAudioTypes.h
Header-Datei,
enum
{
kAudioFormatLinearPCM = 'lpcm',
kAudioFormatAC3 = 'ac-3',
kAudioFormat60958AC3 = 'cac3',
kAudioFormatAppleIMA4 = 'ima4',
kAudioFormatMPEG4AAC = 'aac ',
kAudioFormatMPEG4CELP = 'celp',
} ;
Es wird viel darüber geredet, dass dies nicht “plattformunabhängig” ist, aber wenn Sie eine API verwenden, ist das so gemacht für eine bestimmte Plattform, die sich um Portabilität kümmert. Die Prüfung auf Gleichheit auf derselben Plattform wird niemals fehlschlagen. Diese enum
‘d Werte sind einfacher zu lesen und sie enthalten tatsächlich ihre Identität in ihrem Wertwas ziemlich nett ist.
Was ich unten versucht habe, ist, ein Multibyte-Zeichenliteral zu verpacken, damit es gedruckt werden kann (auf dem Mac funktioniert das). Das Merkwürdige ist, wenn man nicht alle 4 Zeichen aufbraucht, wird das Ergebnis unten falsch..
#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;
}
Diese Art von Funktion ist wirklich gut, wenn Sie Parser erstellen. Bedenken Sie:
byte* buffer = ...;
if(*(int*)buffer == 'GET ')
invoke_get_method(buffer+4);
Dieser Code funktioniert wahrscheinlich nur mit bestimmten Endianness und kann über verschiedene Compiler hinweg brechen
Beachten Sie, dass der tatsächliche Wert implementierungsdefiniert ist stackoverflow.com/questions/3960954/c-multicharacter-literal
– FireAphis
18. September 2011 um 7:46 Uhr