在多个字符上使用C++时,单引号有什么作用?

luc*_*ity 279 c++ quotes

我对这段代码感到好奇:

cout << 'test'; // Note the single quotes.
Run Code Online (Sandbox Code Playgroud)

给我一个输出1952805748.

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

K-b*_*llo 283

这是一个多字符文字.19528057480x74657374,分解为

0x74 -> 't'
0x65 -> 'e'
0x73 -> 's'
0x74 -> 't'
Run Code Online (Sandbox Code Playgroud)

编辑:

C++标准,§2.14.3/ 1 - 字符文字

(...)包含多个c-char的普通字符文字是多字符文字.多字符文字具有int类型和implementation-de fi ned值.

  • 你没有提到这是实现定义的. (11认同)
  • 我想这个定义最有趣的是`sizeof(int)`也是实现定义的.因此,不仅定义了存储顺序实现,而且最大长度也是如此. (2认同)

chy*_*hys 74

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

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

't' == 0x74; 'e' == 0x65; 's' == 0x73; 't' == 0x74; 
Run Code Online (Sandbox Code Playgroud)

所以0x74657374是1952805748.

但它在某些其他编译器上也可能是0x74736574.C和C++标准都说多字节字符的值是实现定义的.因此,强烈建议不要使用它.

  • @Giorgio:标准只说它的实现定义,没有更多的细节.实际上,因为在大多数机器上`int`是4个字节,所以我认为使用超过4个字节是不合理的.是的,它旨在成为编写一些常量的便捷方式,但不幸的是,不同的编译器已经以不同的方式解释它,所以现在大多数编码风格都不鼓励使用它. (2认同)
  • @chys:它实现定义的事实意味着它甚至不需要保持一致.例如,符合标准的编译器可以为所有多字符文字赋值0(尽管这将是不友好的). (2认同)
  • 人们不得不问为什么标准中存在这种疯狂的特征.这似乎是一种罕见的用例,无论如何都是实现定义的,并且如果需要的话,可以通过普通的位移和/或非常清楚地完成. (2认同)

Mou*_*hna 18

包含多个c-char的普通字符文字是多字符文字.多字符文字具有int类型和implementation-de fi ned值.

实现需要记录实现定义的行为.例如在gcc中你可以在这里找到它

编译器一次为一个字符定义一个多字符字符常量,将前一个值左移每个目标字符的位数,然后在截断到目标宽度的新字符的位模式中输入字符.最终的位模式为int类型,因此无论单个字符是否有符号都是有符号的.

有关详细信息,请查看此页面中的说明


bob*_*obo 10

他们真的只是int.它们被广泛用于Core Audio API枚举中,例如,在CoreAudioTypes.h头文件中,

enum
{
    kAudioFormatLinearPCM               = 'lpcm',
    kAudioFormatAC3                     = 'ac-3',
    kAudioFormat60958AC3                = 'cac3',
    kAudioFormatAppleIMA4               = 'ima4',
    kAudioFormatMPEG4AAC                = 'aac ',
    kAudioFormatMPEG4CELP               = 'celp',
} ;
Run Code Online (Sandbox Code Playgroud)

有很多关于这不是"平台独立"的喋喋不休,但是当你使用特定平台制作的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;
}
Run Code Online (Sandbox Code Playgroud)

  • _"在同一平台上检查相等性永远不会失败."_可能.升级到Visual Studio _xyz_并咬你的舌头.这个库做出了一个糟糕的决定. (6认同)
  • @ Jean-MichaëlCelerier:很好; 升级你的OSX Clang版本并咬你的舌头...... (5认同)