当用于多个字符时,单引号在 C++ 中有什么作用?

What do single quotes do in C++ when used on multiple characters?

提问人:lucidreality 提问时间:9/18/2011 最后编辑:Tamara Wijsmanlucidreality 更新时间:7/6/2017 访问量:20946

问:

我对这段代码很好奇:

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

给了我一个输出。1952805748

我的问题是:输出是内存中的地址还是其他东西?

C++ 行情

评论

10赞 FireAphis 9/18/2011
注意实际值是实现定义的 stackoverflow.com/questions/3960954/c-multicharacter-literal

答:

287赞 K-ballo 9/18/2011 #1

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

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

编辑:

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

(...)包含超过 一个 c-char 是多字符文本。多字符文本的类型为 int 和 implementation-defined 价值。

评论

11赞 Andreas Bonini 9/18/2011
你没有提到这是定义的实现。
2赞 bobobobo 12/29/2013
我想这个定义最有趣的地方是,它也是定义的实现。因此,不仅定义了存储订单实现,还定义了存储订单的最大长度。sizeof(int)
77赞 chys 9/18/2011 #2

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

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

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

所以0x74657374 1952805748。

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

评论

0赞 Giorgio 9/18/2011
这种多字节字符的长度是否限制为 4 个字节?即它是否表示写成字符的 int?
2赞 chys 9/18/2011
@Giorgio:标准只说它的定义是实现,没有更多细节。在实践中,由于大多数机器上是 4 个字节,我认为使用超过 4 个字节是没有意义的。是的,它本来是用来编写一些常量的便捷方式,但不幸的是,不同的编译器对它的解释方式不同,所以现在大多数编码风格都不鼓励使用它。int
2赞 Keith Thompson 9/19/2011
@chys:事实上,它是实现定义的,这意味着它甚至不需要保持一致。例如,符合要求的编译器可以为所有多字符文本提供值 0(尽管这是不友好的)。
2赞 Boann 2/23/2013
人们不得不问为什么这个疯子功能存在于标准中。这似乎是一个罕见的用例,无论如何都是定义的实现,并且可以在需要时通过普通的位移和 or'ing 非常清楚地完成。
1赞 bobobobo 12/21/2013
@Boann 是的,正是我的观点。但是您可以安全地在开关等中使用它,因为应该检查的直接比较==
18赞 Mouna Cheikhna 9/19/2011 #3

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

实现定义的行为需要记录在 实施。例如,在 GCC 中,您可以在此处找到它

编译器对多字符字符常量进行值 一次一个字符,将前一个值向左移动 按每个目标字符的位数,然后 在新字符的位模式中被截断的 or-ing 设置为目标字符的宽度。决赛 bit-pattern 的类型为 int,因此是有符号的, 无论单个字符是否带符号或 不。

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

10赞 bobobobo 12/29/2013 #4

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

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

有很多关于这不是“独立于平台”的喋喋不休,但是当您使用为特定平台制作的 API 时,谁会关心可移植性。在同一平台上检查平等永远不会失败。这些值更易于阅读,并且它们实际上在其值中包含其身份,这非常好。enum

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

评论

7赞 Lightness Races in Orbit 7/31/2015
“在同一个平台上检查平等永远不会失败。”它可能。升级到 Visual Studio xyz 并咬住你的舌头。这个图书馆做出了一个可怕的决定。
0赞 Jean-Michaël Celerier 7/16/2016
@LightnessRacesinOrbit“升级到 Visual Studio xyz 并咬住你的舌头。Core Audio API 是 OS X 的系统音频 API,因此这无关紧要。
7赞 Lightness Races in Orbit 7/17/2016
@Jean-MichaëlCelerier:很好;升级你的OSX Clang版本,咬你的舌头......
1赞 MooseBoys 7/7/2022
@LightnessRacesinOrbit 或者完全使用不同的编译器。该行为与编译器相关,与平台无关。平台依赖项假定在默认环境中,始终存储以 开头的值。如果库总是与它的依赖项同时编译,这不是一个可怕的想法(只是一个坏主意),但二进制格式仍然存在,供某人依赖,这是一场等待发生的噩梦。$HOME/Users/
1赞 Ayende Rahien 7/6/2017 #5

当你在构建解析器时,这种功能真的很好。 考虑一下:

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

此代码可能仅适用于特定的 endianess,并且可能会跨不同的编译器中断