É 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.
Você não mencionou que esta é uma implementação definida.
Thomas Bonini
2
Suponho que a coisa mais engraçada sobre essa definição é que a 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.
bobobobo
74
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.
O tamanho de um caractere de vários bytes está restrito a 4 bytes? Ou seja, representa um int escrito como caracteres?
Giorgio
2
@Giorgio: O padrão diz apenas que sua implementação está definida, sem mais detalhes. Na prática, como 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.
chys
2
@ chys: E o fato de ser definido como implementação significa que nem é necessário que seja consistente. Um compilador em conformidade pode fornecer a todos os literais de vários caracteres o valor 0, por exemplo (embora isso não seja amigável).
Keith Thompson
2
É preciso perguntar por que esse recurso maluco existe no padrão. Parece que um caso de uso tão raro, é a implementação definida de qualquer maneira, e pode ser feita de maneira bastante clara com a troca de bits comum ou se necessário.
Boann 23/02
1
@ Boann Sim , meus sentimentos exatamente. Mas você pode usá-lo com segurança em switches e outros enfeites, como comparação direta para ==deve verificar
bobobobo
18
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,
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))structMultibyte{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);}charoperator[](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,constchar* argv[]){Multibyte('abcd').println();Multibyte('x097').println();Multibyte('\"\\\'\'').println();Multibyte('/*|').println();Multibyte('d').println();return0;}
"A verificação da igualdade na mesma plataforma nunca falha." Poderia. Atualize para o Visual Studio xyz e morda sua língua. Esta biblioteca tomou uma decisão terrível .
Lightness Races in Orbit
@LightnessRacesinOrbit "Atualize para o Visual Studio xyz e morda sua língua." A API de áudio principal é a API de áudio do sistema do OS X, portanto, isso não é relevante.
Jean-Michaël Celerier
5
@ Jean-MichaëlCelerier: Ótimo; atualize sua versão do OSX Clang e morda sua língua ...
Lightness Races in Orbit
1
Esse tipo de recurso é realmente bom quando você está construindo analisadores. Considere isto:
Respostas:
É um literal com vários caracteres.
1952805748
é0x74657374
, que se decompõe comoEditar:
fonte
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.
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.
fonte
int
sã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É 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
fonte
Eles são realmente apenas
int
s. Eles são usados extensivamente nas enum da API de áudio principal, por exemplo, noCoreAudioTypes.h
arquivo de cabeçalho,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
enum
valores 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 ..
fonte
Esse tipo de recurso é realmente bom quando você está construindo analisadores. Considere isto:
Esse código provavelmente funcionará apenas em endianess específico e pode ser dividido em diferentes compiladores
fonte