Мне любопытен этот код:
cout << 'test'; // Note the single quotes.
дает мне результат 1952805748
.
Мой вопрос: вывод - это адрес в памяти или что-то в этом роде?
Мне любопытен этот код:
cout << 'test'; // Note the single quotes.
дает мне результат 1952805748
.
Мой вопрос: вывод - это адрес в памяти или что-то в этом роде?
Это многосимвольный литерал. 1952805748
- это 0x74657374
, который разлагается как
0x74 -> 't'
0x65 -> 'e'
0x73 -> 's'
0x74 -> 't'
Изменить:
Стандарт C ++, §2.14.3 / 1 - Символьные литералы
(...) Обычный символьный литерал, содержащий более одного c-char, является многосимвольным литералом. Многосимвольный литерал имеет тип int и значение, определяемое реализацией.
sizeof(int)
также определяется реализацией. Таким образом, определяется не только реализация порядка хранения, но и максимальная их длина.
- person bobobobo; 28.12.2013
Нет, это не адрес. Это так называемый многобайтовый символ.
Обычно это значения ASCII четырех вместе взятых символов.
't' == 0x74; 'e' == 0x65; 's' == 0x73; 't' == 0x74;
So 0x74657374 is 1952805748.
Но это также может быть 0x74736574 на другом компиляторе. В стандартах C и C ++ говорится, что значение многобайтовых символов определяется реализацией. Поэтому, как правило, его использование категорически не рекомендуется.
int
на большинстве машин составляет 4 байта, я не думаю, что имеет смысл использовать более 4 байтов. Да, это было задумано как удобный способ написания некоторых констант, но, к сожалению, разные компиляторы интерпретируют его по-разному, поэтому в настоящее время большинство стилей кодирования не поощряют его использование.
- person chys; 18.09.2011
==
должно проверить
- person bobobobo; 21.12.2013
Обычный символьный литерал, содержащий более одного символа c-char, является многосимвольным литералом. Многосимвольный литерал имеет тип int и значение, определяемое реализацией.
Поведение, определяемое реализацией, должно быть задокументировано реализацией. например, в gcc вы можете найти его здесь
Компилятор оценивает многосимвольную символьную константу по одному символу за раз, сдвигая предыдущее значение влево на количество бит на целевой символ, а затем вставляя или вставляя битовый шаблон нового символа, усеченного до ширины целевого символа. персонаж. Конечному битовому шаблону присваивается тип int, и поэтому он подписан, независимо от того, подписаны ли отдельные символы или нет.
Ознакомьтесь с объяснением в эта страница для получения дополнительной информации.
Они действительно просто int
s. Они широко используются в перечислениях Core Audio API, например, в заголовочном файле CoreAudioTypes.h
,
enum
{
kAudioFormatLinearPCM = 'lpcm',
kAudioFormatAC3 = 'ac-3',
kAudioFormat60958AC3 = 'cac3',
kAudioFormatAppleIMA4 = 'ima4',
kAudioFormatMPEG4AAC = 'aac ',
kAudioFormatMPEG4CELP = 'celp',
} ;
Много говорят о том, что это не «платформенно-независимый», но когда вы используете api, созданный для конкретной платформы, кого волнует переносимость. Проверка на равенство на одной платформе никогда не завершится ошибкой. Эти enum
'd значения легче читать, и они фактически содержат свою идентичность в своем значении, что довольно приятно.
То, что я пытался сделать ниже, - это обернуть многобайтовый символьный литерал, чтобы его можно было распечатать (на Mac это работает). Странно то, что если не использовать все 4 символа, результат ниже будет неверным ...
#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;
}
Такая функция действительно хороша при создании парсеров. Учти это:
byte* buffer = ...;
if(*(int*)buffer == 'GET ')
invoke_get_method(buffer+4);
Этот код, скорее всего, будет работать только с определенным порядком байтов и может не работать в разных компиляторах.