C/C++中的\x代表什么意思?

48

示例:

char arr[] = "\xeb\x2a";

顺便问一下,以下两者是否相同?

"\xeb\x2a"'\xeb\x2a'

7个回答

44

\x 表示十六进制字符转义。用于指定无法输入的字符(例如空值'\x00')。

"\xeb\x2a" 是一个字面量字符串(类型为char *,3字节,以空字符结尾),而 '\xeb\x2a' 则是一个字符常量(类型为int,2字节,不以空字符结尾,只是另一种写出0xEB2A或60202或0165452的方式)。两者不同 :)


4
类型是 char,2个字节 - 嗯,我认为通常不适合放入 char 中。 - Cascabel
4
'\xeb\x2a'不是类型为char[2]的变量 - 它是一个具有实现定义值的int类型。 - Michael Burr
2
那么 '\xeb\x2a\xeb\x2a\xeb''\xeb\x2a\xeb' 呢? - user198729
你能告诉我"\x01C"是什么意思吗?是1.5个字节吗? - Scott 混合理论
@Scott混合理论 - 这意味着0x1C,一个单字节,因为有前导0。半字节(“nybbles”)非常不常见,可能不是C语言的一部分。 - Seth
显示剩余16条评论

11
正如其他人所说,\x是转义序列,表示一个"十六进制转义序列"。
来自C99标准的一些详细信息:
当在单引号(')内使用时,这些字符是"整型字符常量"的一部分,它是 (6.4.4.4/2 "Character constants"):
一个或多个多字节字符的序列,用单引号括起来,如'x'
还有:
整型字符常量具有int类型。包含映射到单字节执行字符的单个字符的整型字符常量的值,是映射字符的表示解释为整数的数值。包含多个字符(例如,'ab')或包含不映射到单字节执行字符的字符或转义序列的整型字符常量的值是由实现定义的。
因此,你的示例中的序列'\xeb\x2a'是一个实现定义值。它很可能是int值0xeb2a0x2aeb,具体取决于目标平台是大端还是小端,但你必须查看编译器的文档才能确定。
当在双引号(")内使用时,由hex-escape-sequence指定的字符是空字符结尾的字符串字面值的一部分。
来自C99标准6.4.5/3的字符串字面值:
对于字符字符串字面值或宽字符串字面值中序列的每个元素,应用与整型字符常量或宽字符常量中的每个元素相同的考虑,只是单引号'既可以被表示为自身,也可以被转义序列\'表示,但双引号"必须由转义序列\"表示。
附加信息:
在我看来,你应该避免使用"多字符"常量。只有在少数情况下,它们在使用普通的旧int 常量时才提供任何价值。例如,'\xeb\x2a'根据你需要的值,更可移植地指定为0xeb2a0x2aeb
我发现多字符常量有一些用处的地方是,可以创建出在调试器或内存转储中可以识别的聪明枚举值。
enum CommandId {
    CMD_ID_READ  = 'read',
    CMD_ID_WRITE = 'writ',
    CMD_ID_DEL   = 'del ',
    CMD_ID_FOO   = 'foo '
};

上述方法存在少量可移植性问题(除了可能会在使用小整数的平台上出现警告)。无论字符以小端还是大端形式结束,代码仍将正常工作(除非您在枚举值中执行其他不可描述操作)。如果字符以不符合您期望的字节序列方式进入值,则可能会使调试器中的值变得更难读取,但“正确性”不受影响。


'\xeb\x2a'char[0]='\xeb',char[1]='\x2a'是一样的吗? - user198729
不,正如答案所述,'\xeb\x2a'是一个具有实现定义值的int。该值几乎肯定为0xeb2a或0x2aeb;哪一个几乎肯定取决于平台的字节序。我想一些编译器可能会将'\xeb\x2a'转换为0xffffeb2a,如果它们决定进行符号扩展的话。我不知道这有多大可能性。 - Michael Burr
我还想指出,在C++中,'\x50'是类型为 char 而不是 int,这与C语言不同。 - Searene

3
当你说:
“BTW,这两个是一样的吗:‘\xeb\x2a’ vs '\xeb\x2a'”
实际上它们不同。第一个创建了一个字符字符串文字,以零字节结尾,包含您提供的十六进制表示的两个字符。第二个创建了一个整数常量。

1
你能详细说明一下 '\xeb\x2a' 吗? - user198729
'\xeb' 是一个单个字符(=一个字节),所以 '\xeb\x2a' 是两个字节 = 16位 = 短整型。 - Martin Beckett
@Martin Beckett:不,包含多个字符的字符常量仍然是int,而不是short int。它的值是实现定义的。 - CB Bailey
@user198729,就像Charles所说的那样。在C语言中,单引号之间的任何内容都会被转换为整数。因此,在ASCII码中,'A'会被转换为65。如果你输入'AB',那么它可能会被转换为(65 << 8) + 66。或者也可能不会——这种转换是由具体实现定义的。 - anon
@Charles Bailey - 抱歉,我想说的是两个数字的 \x 是一个字节,所以两个字节组成了一个 16 位值(即 short int)。但是在 C 中,即使只有 '0' 也是一个 'integer'。 - Martin Beckett
@Martin Beckett:不用道歉,我只是想纠正我看起来像是一个事实观点的错误。 - CB Bailey

1

1
最好在这里提供完整的答案,而不是将OP链接到一个他们可以找到答案的地方 - 而且那个链接没有比“十六进制转义字符”更多的解释。 - Cascabel

1

\x 表示十六进制字符转义。因此,\xeb 将表示十六进制中的字符 eb,或者在十进制中为 235。请参阅 http://msdn.microsoft.com/en-us/library/6aw8xdf2.aspx 以获取更多信息。

至于第二个问题,不,它们不相同。双引号 " 表示一串字符,即一个以 null 结尾的字符数组,而单引号 ' 表示一个单独的字符,即该字符所代表的字节。


单引号表达式不是单字节字符。 - Cascabel

1

\x 允许您通过十六进制代码指定字符。

这使您可以指定通常不可打印的字符(其中一些具有预定义的特殊转义序列,例如'\n'=换行符和'\t'=制表符'\b'=响铃符)


0
一个有用的网站在这里
引用:
x 无符号十六进制整数
这样,你的\xeb就像十进制中的235。

1
该链接是关于printf()等函数所使用的格式字符串的描述,而不是C语言字面量理解的转义序列。此外,它也是特定于C++的,但由于提问者询问的是神秘的C/C++语言,我会让它通过。 - RBerteig

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接