Jestem ciekawy tego kodu:
cout << 'test'; // Note the single quotes.
daje mi wyjście 1952805748
.
Moje pytanie: czy wyjście ma adres w pamięci czy coś takiego?
Jestem ciekawy tego kodu:
cout << 'test'; // Note the single quotes.
daje mi wyjście 1952805748
.
Moje pytanie: czy wyjście ma adres w pamięci czy coś takiego?
Odpowiedzi:
To dosłowny znak złożony z wielu znaków. 1952805748
jest 0x74657374
, który rozkłada się jako
0x74 -> 't'
0x65 -> 'e'
0x73 -> 's'
0x74 -> 't'
Edytować:
Standard C ++, §2.14.3 / 1 - Literały znakowe
(...) Zwykły literał znakowy zawierający więcej niż jeden znak c jest literałem wieloznakowym. Literał wieloznakowy ma typ int i wartość zdefiniowaną w implementacji.
sizeof(int)
zdefiniowano również implementację. Tak więc nie tylko zdefiniowano implementację kolejności pamięci, ale także jej maksymalną długość.
Nie, to nie jest adres. Jest to tak zwana postać wielobajtowa.
Zazwyczaj są to wartości ASCII czterech połączonych znaków.
't' == 0x74; 'e' == 0x65; 's' == 0x73; 't' == 0x74;
Więc 0x74657374 to 1952805748.
Ale może to być także 0x74736574 na innym kompilatorze. Oba standardy C i C ++ mówią, że wartość znaków wielobajtowych jest zdefiniowana implementacja . Tak więc ogólnie jego użycie jest zdecydowanie odradzane.
int
na większości maszyn są 4 bajty, nie sądzę, aby warto było używać więcej niż 4 bajtów. Tak, miał to być wygodny sposób na zapisanie niektórych stałych, ale niestety różne kompilatory interpretują go inaczej, więc w dzisiejszych czasach większość stylów kodowania zniechęca do jego używania.
==
powinno sprawdzić
Zwykły literał znakowy, który zawiera więcej niż jeden znak c-char, jest literałem wieloznakowym. Literał wieloznakowy ma typ int i wartość zdefiniowaną w implementacji.
Zachowanie zdefiniowane w implementacji musi być udokumentowane przez implementację. na przykład w gcc można go znaleźć tutaj
Kompilator ceni znak wieloznakowy na raz stałą, przesuwając poprzednią wartość o liczbę bitów na znak docelowy, a następnie orientując się we wzorcu bitowym nowego znaku obciętego do szerokości celu postać. Ostateczny wzorzec bitowy ma typ int i dlatego jest podpisany, niezależnie od tego, czy pojedyncze znaki są podpisane, czy nie.
Sprawdź wyjaśnienia na tej stronie, aby uzyskać więcej informacji
To naprawdę tylko int
s. Są szeroko stosowane w enumie Core Audio API, na przykład w CoreAudioTypes.h
pliku nagłówkowym,
enum
{
kAudioFormatLinearPCM = 'lpcm',
kAudioFormatAC3 = 'ac-3',
kAudioFormat60958AC3 = 'cac3',
kAudioFormatAppleIMA4 = 'ima4',
kAudioFormatMPEG4AAC = 'aac ',
kAudioFormatMPEG4CELP = 'celp',
} ;
Wiele mówi się o tym, że nie jest się „niezależnym od platformy”, ale kiedy używasz interfejsu API stworzonego dla konkretnej platformy, która dba o przenośność. Sprawdzanie równości na tej samej platformie nigdy nie zawiedzie. Te enum
wartości są łatwiejsze do odczytania i faktycznie zawierają swoją tożsamość w wartości , co jest całkiem miłe.
To, co próbowałem zrobić poniżej, to owinięcie literału znaku wielobajtowego, aby można go było wydrukować (działa na Macu). Dziwne jest to, że jeśli nie zużyjesz wszystkich 4 znaków, wynik staje się błędny poniżej ...
#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;
}
Ten rodzaj funkcji jest naprawdę dobry, gdy budujesz parsery. Rozważ to:
byte* buffer = ...;
if(*(int*)buffer == 'GET ')
invoke_get_method(buffer+4);
Ten kod prawdopodobnie będzie działał tylko na konkretnej endianowości i może działać w różnych kompilatorach