Что делают одиночные кавычки в С++ при использовании нескольких символов?

Мне интересен этот код:

cout << 'test'; // Note the single quotes.

дает результат 1952805748.

Мой вопрос: выводится ли адрес в памяти или что-то в этом роде?

Ответ 1

Это многосимвольный литерал. 1952805748 0x74657374, который разлагается как

0x74 -> 't'
0x65 -> 'e'
0x73 -> 's'
0x74 -> 't'

Edit:

Стандарт С++, §2.14.3/1 - Литералы символов

(...) Литерал обычного характера, который содержит больше, чем один c- char является многоканальным литералом. Многоканальный литерал имеет тип int и его реализация значение.

Ответ 2

Нет, это не адрес. Это так называемый многобайтовый символ.

Как правило, это значения ASCII четырех символов.

't' == 0x74; 'e' == 0x65; 's' == 0x73; 't' == 0x74; 

Итак, 0x74657374 - 1952805748.

Но он также может быть 0x74736574 на другом компиляторе. Стандарты C и С++ говорят, что значение многобайтовых символов определяется реализацией. Поэтому обычно его использование сильно не рекомендуется.

Ответ 3

Литерал обычного характера, содержащий более одного c- char, является многоканальным литералом. Многоканальный литерал имеет тип int и значение, определяемое реализацией.

Выполнение, определенное определением, требуется для документирования реализация. например, в gcc вы можете найти здесь

Компилятор задает многосимвольную символьную константу символ за раз, сдвинув предыдущее значение влево по количеству бит на целевой символ, а затем или-ing в битовой схеме нового символа, усеченного к ширине целевого символа. Финал бит-шаблон задан тип int и, следовательно, подписан, независимо от того, подписаны ли одиночные символы или не.

Подробнее об этом объясните в этой странице.

Ответ 4

Они действительно просто 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;
}

Ответ 5

Эта функция очень хороша, когда вы создаете парсеры. Рассмотрим это:

byte* buffer = ...;
if(*(int*)buffer == 'GET ')
  invoke_get_method(buffer+4);

Этот код, скорее всего, будет работать только на конкретную endianess и может разбиться на разные компиляторы