在多个字符中使用单引号在C ++中会做什么?


Answers:


283

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

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

编辑:

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

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


11
您没有提到这是实现定义的。
Thomas Bonini 2011年

2
我想关于该定义的最有趣的事情sizeof(int)就是实现定义。因此,不仅定义了存储顺序实现,而且还定义了它们的最大长度。
bobobobo

74

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

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

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

所以0x74657374是1952805748。

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


这样的多字节字符的长度是否限制为4个字节?即它代表以字符形式写出的int吗?
乔治

2
@ Giorgio:该标准仅表示已定义实现,没有更多细节。实际上,由于int大多数计算机上为4字节,所以我认为使用4个以上的字节没有意义。是的,它原本是一种方便的方式来编写一些常量,但是不幸的是,不同的编译器对它的解释有所不同,因此,当今大多数编码样式都劝阻它的使用。
chys 2011年

2
@chys:事实上,它是实现定义的,这意味着甚至不需要保持一致。例如,一个合格的编译器可以将所有多字符文字的值都设置为0(尽管那样会很不友好)。
基思·汤普森

2
不得不问为什么标准中存在这种愚蠢的功能。似乎如此罕见的用例,无论如何都定义了实现,并且可以通过普通的移位和/或必要时非常清楚地完成。
Boann 2013年

1
@Boann 是的,完全我的观点。不过,你可以放心地在交换机和诸如此类的东西使用它,因为直接比较的==应该看看
bobobobo

18

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

实现定义的行为需要由实现记录下来。例如在gcc中,您可以在这里找到它

编译器一次对一个字符的多字符字符进行赋值,将先前的值左移每个目标字符的位数,然后对新字符的位模式进行或运算,将其截断为目标宽度字符。最终的位模式的类型为int,因此,无论是否对单个字符进行签名,都对其进行签名。

查看此页面中的解释以获取更多详细信息


10

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

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

关于这不是“平台独立”的问题,有很多人ter之以鼻,但是当您使用针对特定平台制作的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;
}

6
“在同一平台上检查是否相等永远不会失败。” 它可能。升级到Visual Studio xyz,然后咬住舌头。这个图书馆做出了一个糟糕的决定。
Lightness Races in Orbit

@LightnessRacesinOrbit “升级到Visual Studio xyz并咬住你的舌头。” 核心音频API是OS X的系统音频API,因此与此无关。
吉恩-迈克尔Celerier

5
@Jean-MichaëlCelerier:很好;升级您的OSX Clang版本并咬住您的舌头……
轨道上的Lightness Races

1

当您构建解析器时,这种功能确实非常好。考虑一下:

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

此代码可能仅适用于特定的字节序,并且可能会在不同的编译器上中断

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.