c: 将 char 值类型转换为 unsigned short
c: type casting char values into unsigned short
从一段伪代码开始:
char a = 0x80;
unsigned short b;
b = (unsigned short)a;
printf ("0x%04x\r\n", b); // => 0xff80
根据我目前的理解,"char" 根据定义既不是 signed char 也不是 unsigned char,而是第三种类型的符号。
为什么 'a' 首先从(可能取决于平台)8 位存储符号扩展到(可能又是特定于平台的)16 位有符号短整数,然后转换为一个未签名的短?
有没有一个c标准决定展开的顺序?
本标准指南是否以任何方式处理 "pure" 字符的第三种类型的符号(我曾称它为 X-char,x 表示未确定的符号),以便结果位于确定性最低?
PS:如果在赋值行的'a'前插入一个“(unsigned char)”语句,那么打印行的结果确实变成了0x0080。因此,只有连续两次类型转换才能提供某些意图的预期结果。
类型 char
不是 "third" 符号。它是 signed char
或 unsigned char
,具体是哪一个由实现定义。
这是由 C standard 的第 6.2.5p15 节规定的:
The three types char
, signed char
, and unsigned char
are
collectively called the character types. The implementation
shall define char
to have the same range, representation, and
behavior as either signed char
or unsigned char
.
看来在您的实现中,char
与 signed char
相同,因此因为该值为负数并且因为目标类型是无符号的,所以必须对其进行转换。
第 6.3.1.3 节规定了整数类型之间的转换是如何发生的:
1 When a value with integer type is converted to another integer type
other than
_Bool ,if the value can be represented by the new type, it is unchanged.
2 Otherwise, if the new type is unsigned, the value is
converted by repeatedly adding or subtracting one more than
the maximum value that can be represented in the new type
until the value is in the range of the new type.
3 Otherwise, the new type is signed and the value cannot be
represented in it; either the result is implementation-defined or
an implementation-defined signal is raised.
由于值 0x80 == -128 无法在 unsigned short
中表示,因此发生第 2 段中的转换。
char
具有实现定义的签名。它要么是有符号的,要么是无符号的,具体取决于编译器。在某种程度上,char
确实是第三种字符类型,请参阅 。 char
具有不确定的(不可移植的)符号,因此绝不能用于存储原始数字。
但在这种情况下这并不重要。
- 在您的编译器上,
char
已签名。
char a = 0x80;
以特定于编译器的方式强制从 0x80
类型(即 int
)转换为 char
。通常在 2 的补码系统上,这意味着 char
获得值 -128
,这里似乎就是这种情况。
b = (unsigned short)a;
强制从 char
转换为 unsigned short
1)。 C17 6.3.1.3 有符号和无符号整数然后说:
Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or
subtracting one more than the maximum value that can be represented in the new type
until the value is in the range of the new type.
比最大值多一个 65536
。所以你可以把它想象成 -128 + 65536 = 65408
.
65408
的无符号十六进制表示是0xFF80
。任何地方都没有符号扩展!
1) 不需要强制转换。当 =
的两个操作数都是算术类型时,如本例所示,右操作数将隐式转换为右操作数的类型 (C17 6.5.16.1 §2)。
从一段伪代码开始:
char a = 0x80;
unsigned short b;
b = (unsigned short)a;
printf ("0x%04x\r\n", b); // => 0xff80
根据我目前的理解,"char" 根据定义既不是 signed char 也不是 unsigned char,而是第三种类型的符号。
为什么 'a' 首先从(可能取决于平台)8 位存储符号扩展到(可能又是特定于平台的)16 位有符号短整数,然后转换为一个未签名的短?
有没有一个c标准决定展开的顺序?
本标准指南是否以任何方式处理 "pure" 字符的第三种类型的符号(我曾称它为 X-char,x 表示未确定的符号),以便结果位于确定性最低?
PS:如果在赋值行的'a'前插入一个“(unsigned char)”语句,那么打印行的结果确实变成了0x0080。因此,只有连续两次类型转换才能提供某些意图的预期结果。
类型 char
不是 "third" 符号。它是 signed char
或 unsigned char
,具体是哪一个由实现定义。
这是由 C standard 的第 6.2.5p15 节规定的:
The three types
char
,signed char
, andunsigned char
are collectively called the character types. The implementation shall definechar
to have the same range, representation, and behavior as eithersigned char
orunsigned char
.
看来在您的实现中,char
与 signed char
相同,因此因为该值为负数并且因为目标类型是无符号的,所以必须对其进行转换。
第 6.3.1.3 节规定了整数类型之间的转换是如何发生的:
1 When a value with integer type is converted to another integer type other than _Bool ,if the value can be represented by the new type, it is unchanged.
2 Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.
3 Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.
由于值 0x80 == -128 无法在 unsigned short
中表示,因此发生第 2 段中的转换。
char
具有实现定义的签名。它要么是有符号的,要么是无符号的,具体取决于编译器。在某种程度上,char
确实是第三种字符类型,请参阅 char
具有不确定的(不可移植的)符号,因此绝不能用于存储原始数字。
但在这种情况下这并不重要。
- 在您的编译器上,
char
已签名。 char a = 0x80;
以特定于编译器的方式强制从0x80
类型(即int
)转换为char
。通常在 2 的补码系统上,这意味着char
获得值-128
,这里似乎就是这种情况。b = (unsigned short)a;
强制从char
转换为unsigned short
1)。 C17 6.3.1.3 有符号和无符号整数然后说:Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.
比最大值多一个
65536
。所以你可以把它想象成-128 + 65536 = 65408
.65408
的无符号十六进制表示是0xFF80
。任何地方都没有符号扩展!
1) 不需要强制转换。当 =
的两个操作数都是算术类型时,如本例所示,右操作数将隐式转换为右操作数的类型 (C17 6.5.16.1 §2)。