tipo - ¿Qué hacen las comillas simples en C++ cuando se usan en múltiples caracteres?
diferencia entre comillas simples y dobles en c (5)
Un literal de caracteres ordinarios 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 la implementación debe ser documentado por la implementación. por ejemplo en gcc puedes encontrarlo here
El compilador valora una constante de caracteres de múltiples caracteres, un carácter a la vez, desplazando el valor anterior dejado por el número de bits por carácter de destino, y luego oring en el patrón de bits del nuevo carácter truncado al ancho de un objetivo personaje. El patrón de bits final tiene el tipo int, y por lo tanto está firmado, independientemente de si los caracteres individuales están firmados o no.
Verifique la explicación en esta página para más detalles.
Tengo curiosidad por 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í?
Es un literal de múltiples caracteres. 1952805748
es 0x74657374
, que se descompone como
0x74 -> ''t''
0x65 -> ''e''
0x73 -> ''s''
0x74 -> ''t''
Editar:
Norma C ++, §2.14.3 / 1 - Literales de caracteres
(...) Un literal de caracteres ordinarios 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.
Este tipo de característica es realmente buena cuando estás construyendo analizadores. Considera esto:
byte* buffer = ...;
if(*(int*)buffer == ''GET '')
invoke_get_method(buffer+4);
Es probable que este código solo funcione en una endianess específica y podría dividirse en diferentes compiladores
No, no es una dirección. Es el llamado personaje multibyte.
Normalmente, 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 eso en general se desaconseja su uso.
Son realmente sólo int
s. Se usan ampliamente en las enumeración de Core Audio API, por ejemplo, en el archivo de encabezado CoreAudioTypes.h
,
enum
{
kAudioFormatLinearPCM = ''lpcm'',
kAudioFormatAC3 = ''ac-3'',
kAudioFormat60958AC3 = ''cac3'',
kAudioFormatAppleIMA4 = ''ima4'',
kAudioFormatMPEG4AAC = ''aac '',
kAudioFormatMPEG4CELP = ''celp'',
} ;
Existe una gran cantidad de comentarios acerca de que esto no es "independiente de la plataforma", pero cuando se usa una API creada para una plataforma específica, a quién le importa la portabilidad. Comprobar la igualdad en la misma plataforma nunca fallará. Estos valores de enum
son más fáciles de leer y en realidad contienen su identidad en su valor , lo cual es bastante bueno.
Lo que he tratado de hacer a continuación es envolver un literal de caracteres de varios bytes para que pueda imprimirse (en Mac funciona). Lo extraño es que, si no usas 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;
}