我对这段代码很好奇:

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

输出为1952805748。

我的问题是:输出是内存中的地址还是什么?


当前回答

它们实际上只是整数。它们在CoreAudio API枚举中被广泛使用,例如,在CoreAudioTypes.h头文件中,

enum
{
    kAudioFormatLinearPCM               = 'lpcm',
    kAudioFormatAC3                     = 'ac-3',
    kAudioFormat60958AC3                = 'cac3',
    kAudioFormatAppleIMA4               = 'ima4',
    kAudioFormatMPEG4AAC                = 'aac ',
    kAudioFormatMPEG4CELP               = 'celp',
} ;

有很多人认为这不是“平台独立的”,但当你使用一个为特定平台制作的api时,谁会关心可移植性呢?在同一个平台上检查是否相等永远不会失败。这些枚举值更容易读取,它们实际上在值中包含了它们的标识,这非常好。

我在下面尝试做的是将一个多字节字符文字包装起来,这样它就可以打印(在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;
}

其他回答

不,这不是地址。这就是所谓的多字节字符。

通常,它是四个字符的ASCII值的组合。

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

所以0x74657374等于1952805748。

但是在其他编译器上它也可以是0x74736574。C和c++标准都说多字节字符的值是实现定义的。所以一般来说,它的使用是强烈反对的。

包含多个c-char的普通字符字面量是多字符字面量。多字符文字具有类型int和实现定义的值。

实现定义的行为需要由 实现。例如,在GCC中,你可以在这里找到它

编译器为一个多字符字符常量赋值 一次一个字符,将先前的值向左移动 通过每个目标字符的比特数,然后 在截断的新字符的位模式中的Or-ing 到目标字符的宽度。最后一个 位模式的类型为int,因此有符号, 不管单个字符是有符号还是 不是。

查看本页的解释了解更多细节

它们实际上只是整数。它们在CoreAudio API枚举中被广泛使用,例如,在CoreAudioTypes.h头文件中,

enum
{
    kAudioFormatLinearPCM               = 'lpcm',
    kAudioFormatAC3                     = 'ac-3',
    kAudioFormat60958AC3                = 'cac3',
    kAudioFormatAppleIMA4               = 'ima4',
    kAudioFormatMPEG4AAC                = 'aac ',
    kAudioFormatMPEG4CELP               = 'celp',
} ;

有很多人认为这不是“平台独立的”,但当你使用一个为特定平台制作的api时,谁会关心可移植性呢?在同一个平台上检查是否相等永远不会失败。这些枚举值更容易读取,它们实际上在值中包含了它们的标识,这非常好。

我在下面尝试做的是将一个多字节字符文字包装起来,这样它就可以打印(在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);

这段代码可能只适用于特定的字节数,并且可能在不同的编译器之间中断

它是一个多字符的文字。1952805748是0x74657374,它分解为

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

编辑:

c++标准,§2.14.3/1 -字符字面值 (…)包含多个字符的普通字符字面量 一个c-char是一个多字符字面值。多字符字面值具有类型int和实现定义 价值。