Estou curioso sobre este código:
cout << 'test'; // Note the single quotes.
me dá uma saída de 1952805748.
Minha pergunta: a saída é um endereço na memória ou algo assim?
Estou curioso sobre este código:
cout << 'test'; // Note the single quotes.
me dá uma saída de 1952805748.
Minha pergunta: a saída é um endereço na memória ou algo assim?
Respostas:
É um literal com vários caracteres. 1952805748é 0x74657374, que se decompõe como
0x74 -> 't'
0x65 -> 'e'
0x73 -> 's'
0x74 -> 't'
Editar:
Padrão C ++, §2.14.3 / 1 - Literais de caracteres
(...) Um literal de caractere comum que contém mais de um c-char é um literal de vários caracteres. Um literal de vários caracteres possui o tipo int e o valor definido pela implementação.
sizeof(int)implementação é definida também. Portanto, não apenas a implementação da ordem de armazenamento é definida, mas também o comprimento máximo deles.
Não, não é um endereço. É o chamado caractere multibyte.
Normalmente, são os valores ASCII dos quatro caracteres combinados.
't' == 0x74; 'e' == 0x65; 's' == 0x73; 't' == 0x74;
Então 0x74657374 é 1952805748.
Mas também pode ser 0x74736574 em algum outro compilador. Os padrões C e C ++ dizem que o valor dos caracteres multibyte é definido pela implementação . Portanto, geralmente seu uso é fortemente desencorajado.
intsão 4 bytes na maioria das máquinas, não acho que faça sentido usar mais de 4 bytes. Sim, ele pretendia ser uma maneira conveniente de escrever algumas constantes, mas, infelizmente, diferentes compiladores a interpretaram de maneira diferente; portanto, hoje em dia a maioria dos estilos de codificação desencoraja seu uso.
==deve verificar
Um literal de caractere comum que contém mais de um c-char é um literal de vários caracteres. Um literal de vários caracteres possui o tipo int e o valor definido pela implementação.
É necessário que o comportamento definido da implementação seja documentado pela implementação. por exemplo, no gcc, você pode encontrá-lo aqui
O compilador valoriza um caractere de vários caracteres, constante um caractere de cada vez, alterando o valor anterior deixado pelo número de bits por caractere de destino e, em seguida, inserindo o padrão de bits do novo caractere truncado para a largura de um destino personagem. O padrão de bits final recebe o tipo int e, portanto, é assinado, independentemente de caracteres únicos serem assinados ou não.
Verifique a explicação nesta página para mais detalhes
Eles são realmente apenas ints. Eles são usados extensivamente nas enum da API de áudio principal, por exemplo, no CoreAudioTypes.harquivo de cabeçalho,
enum
{
kAudioFormatLinearPCM = 'lpcm',
kAudioFormatAC3 = 'ac-3',
kAudioFormat60958AC3 = 'cac3',
kAudioFormatAppleIMA4 = 'ima4',
kAudioFormatMPEG4AAC = 'aac ',
kAudioFormatMPEG4CELP = 'celp',
} ;
Há muita conversa sobre isso não ser "independente de plataforma", mas quando você usa uma API feita para uma plataforma específica, que se preocupa com a portabilidade. A verificação da igualdade na mesma plataforma nunca falha. Esses enumvalores são mais fáceis de ler e, na verdade, contêm sua identidade em seu valor , o que é bastante bom.
O que tentei fazer abaixo é agrupar literalmente um caractere multibyte para que possa ser impresso (no Mac, isso funciona). O estranho é que, se você não usar todos os 4 caracteres, o resultado ficará errado abaixo ..
#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;
}
Esse tipo de recurso é realmente bom quando você está construindo analisadores. Considere isto:
byte* buffer = ...;
if(*(int*)buffer == 'GET ')
invoke_get_method(buffer+4);
Esse código provavelmente funcionará apenas em endianess específico e pode ser dividido em diferentes compiladores