Tengo curiosidad sobre este código:
cout << 'test'; // Note the single quotes.
me da una salida de 1952805748
.
Mi pregunta: ¿Es la salida una dirección en la memoria o algo así?
Tengo curiosidad sobre este código:
cout << 'test'; // Note the single quotes.
me da una salida de 1952805748
.
Mi pregunta: ¿Es la salida una dirección en la memoria o algo así?
Respuestas:
Es un literal de varios caracteres. 1952805748
es decir 0x74657374
, que se descompone como
0x74 -> 't'
0x65 -> 'e'
0x73 -> 's'
0x74 -> 't'
Editar:
Estándar C ++, §2.14.3 / 1 - Literales de caracteres
(...) Un literal de caracteres ordinario que contiene más de un c-char es un literal de varios caracteres. Un literal de varios caracteres tiene el tipo int y el valor definido por la implementación.
sizeof(int)
su implementación también está definida. Por lo tanto, no solo se define la implementación de la orden de almacenamiento, sino también la longitud máxima de estos.
No, no es una dirección. Es el llamado personaje multibyte.
Por lo general, son los valores ASCII de los cuatro caracteres combinados.
't' == 0x74; 'e' == 0x65; 's' == 0x73; 't' == 0x74;
Entonces 0x74657374 es 1952805748.
Pero también puede ser 0x74736574 en algún otro compilador. Los estándares C y C ++ dicen que el valor de los caracteres multibyte está definido por la implementación . Por lo general, su uso está fuertemente desaconsejado.
int
son 4 bytes en la mayoría de las máquinas, no creo que tenga sentido usar más de 4 bytes. Sí, estaba destinado a ser una forma conveniente de escribir algunas constantes, pero desafortunadamente diferentes compiladores lo han estado interpretando de manera diferente, por lo que hoy en día la mayoría de los estilos de codificación desalientan su uso.
==
debería
Un literal de caracteres ordinario que contiene más de un c-char es un literal de varios caracteres. Un literal de varios caracteres tiene el tipo int y el valor definido por la implementación.
El comportamiento definido de implementación debe ser documentado por la implementación. por ejemplo en gcc puedes encontrarlo aquí
El compilador valora un carácter de varios caracteres constante un carácter a la vez, desplazando el valor anterior dejado por el número de bits por carácter de destino, y luego ordenando el patrón de bits del nuevo carácter truncado al ancho de un objetivo personaje. El patrón de bits final recibe el tipo int y, por lo tanto, está firmado, independientemente de si los caracteres individuales están firmados o no.
Consulte la explicación en esta página para obtener más detalles.
En realidad son solo int
s. Se usan ampliamente en la enumeración de Core Audio API, por ejemplo, en el CoreAudioTypes.h
archivo de encabezado,
enum
{
kAudioFormatLinearPCM = 'lpcm',
kAudioFormatAC3 = 'ac-3',
kAudioFormat60958AC3 = 'cac3',
kAudioFormatAppleIMA4 = 'ima4',
kAudioFormatMPEG4AAC = 'aac ',
kAudioFormatMPEG4CELP = 'celp',
} ;
Se habla mucho de que esto no sea "independiente de la plataforma", pero cuando estás usando una API hecha para una plataforma específica, a quién le importa la portabilidad. Verificar la igualdad en la misma plataforma nunca fallará. Estos enum
valores 'd son más fáciles de leer y en realidad contienen su identidad en su valor , lo cual es bastante agradable.
Lo que he intentado hacer a continuación es envolver un literal de caracteres multibyte para que se pueda imprimir (en Mac, esto funciona). Lo extraño es que, si no usa los 4 caracteres, el resultado se vuelve incorrecto a continuación.
#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;
}
Este tipo de característica es realmente buena cuando está creando analizadores. Considera esto:
byte* buffer = ...;
if(*(int*)buffer == 'GET ')
invoke_get_method(buffer+4);
Es probable que este código solo funcione en aplicaciones específicas y podría dividirse en diferentes compiladores