c - C 中 "big"字符十六进制常量的值是多少?

标签 c char integer c99 c11

假设我们在C中写了如下字符常量:

  '\xFFFFAA'  

它的数值是多少?

标准 C99 说:

  • 字符常量的类型为int
  • 十六进制字符常量可以表示为unsigned char
  • 基本字符常量的值是非负的。
  • 任何字符常量的值都在char 范围内。

此外:

  • signed char 的取值范围包含在int 的取值范围内。
  • charunsigned charsigned char 的大小(以位为单位)相同:1 个字节。
  • 一个字节的大小由CHAR_BIT给出,其值至少为8。

假设我们有 CHAR_BIT == 8 的典型情况。
另外,我们假设 char 对我们来说是 signed char

遵循以下规则:常量 '\xFFFFAA' 的类型为 int,但其值可以用 unsigned char 表示,虽然它的真实值适合char
根据这些规则,'\xFF' 的例子会给我们:

  (int)(char)(unsigned char)'\xFF' == -1

第一次转换 unsigned char 来自“可以表示为 unsigned char” 要求。
第二次转换 char 来自“该值适合一个 char” 要求。
第三个转换 int 来自 "has type int" 要求。

但是,常量'\xFFFFAA' 太大了,不能“表示”为unsigned int
它的值(value)是多少?

我认为该值是 (char)(0xFFFFAA % 256) 的结果,因为标准或多或少地说如下:

  • 对于无符号整数类型,如果一个值大于该类型所能表示的最大值M,则取余数对M取模得到的值.

我的结论对吗?

编辑 @KeithThompson 我已经说服了他:他说,根据标准,一个大的十六进制字符常量是违反约束的。
所以,我会接受这个答案。

但是:例如,对于 GCC 4.8、MinGW,编译器会触发一条警告消息,程序会按照我描述的行为进行编译。因此,它被认为是有效的常量,如 '\x100020',其值为 0x20。

最佳答案

C 标准在第 6.4.4.4 节中定义了语法和语义。我会引用 N1570 C11标准草案。

第 6 段:

The hexadecimal digits that follow the backslash and the letter x in a hexadecimal escape sequence are taken to be part of the construction of a single character for an integer character constant or of a single wide character for a wide character constant. The numerical value of the hexadecimal integer so formed specifies the value of the desired character or wide character.

第 9 段:

Constraints

The value of an octal or hexadecimal escape sequence shall be in the range of representable values for the corresponding type:

后跟一个表说没有前缀,“对应类型”是unsigned char

因此,假设 0xFFFFAA 超出类型 unsigned char 的可表示范围,则字符常量 '\xFFFFAA' 违反约束,需要编译时诊断。编译器可以完全拒绝您的源文件。

如果您的编译器至少没有就此警告您,则它不符合 C 标准。

是的,标准确实说无符号类型具有模块化(环绕)语义,但这只适用于算术表达式和一些转换,不适用于常量的含义。

(如果 CHAR_BIT >= 24 在您的系统上,它是完全有效的,但这种情况很少见;通常是 CHAR_BIT == 8。)

如果编译器选择仅发出警告然后继续编译您的源代码,则行为是未定义的(仅仅是因为标准没有定义行为)。

另一方面,如果您实际上是指 'xFFFFAA',则不会将其解释为十六进制。 (我知道这只是一个打字错误,问题已被编辑以更正它,但我还是要把它留在这里。)它的值是实现定义的,如第 10 段所述:

The value of an integer character constant containing more than one character (e.g., 'ab'), ..., is implementation-defined.

包含多个字符的字符常量是一种几乎无用的语言特性,偶然使用的次数多于有意使用的次数。

关于c - C 中 "big"字符十六进制常量的值是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18679206/

相关文章:

c++ - 如何在 C++ 中将值 char 数组的类型更改为 int?

c++ - 使用流运算符将具有整数值的类保存到二进制文件中 >>/<<

java - 将整数转换为字符串的问题

c - 迭代字符串输入

c - 在 C 中初始化一个 "eye"(identity) 矩阵数组

c - C中的指针问题

c - 在字符串中不使用空终止会产生什么影响?

c - 区分读取的字符和读取的整数

c - Round Robin C 调度模拟器

c - 如何匹配PCRE中的所有组和子组