c:将类型转换为无符号short类型的char值

时间:2018-11-13 13:39:18

标签: c casting char short

以伪代码段开头:

numpy

根据我目前的理解,“ char”从定义上来说既不是带符号的字符也不是未签名的字符,而是某种第三种签名。

怎么会发生这样的情况:首先将“ a”符号从一个8位存储(可能与平台有关)扩展到一个16位带符号的short,然后转换为一个无符号的short?

是否有确定扩展顺序的c标准?

该标准指南是否以任何方式处理“纯”字符(我称其为X字符,x表示不确定的字符)的第三种类型的签名,以使结果至少具有确定性? / p>

PS:如果在赋值行的'a'前面插入“(unsigned char)”语句,则打印行的结果确实变为0x0080。因此,连续只有两种类型的强制转换将提供某些意图的预期结果。

2 个答案:

答案 0 :(得分:4)

类型char不是“第三”签名。它是signed charunsigned char,它是实现定义的那个。

这由C standard的6.2.5p15节规定:

  

三种类型charsigned charunsigned char是   统称为字符类型。实施   应将char定义为具有相同的范围,表示形式和   行为为signed charunsigned char

在您的实现中,char似乎与signed char相同,因此,由于该值为负,并且由于目标类型是未签名的,因此必须对其进行转换。

第6.3.1.3节规定了整数类型之间如何进行转换:

  

1 将整数类型的值转换为另一种整数类型时   以外   _Bool,如果该值可以用新类型表示,则它保持不变。

     

2 否则,如果新类型是未签名的,则值为   通过重复加减乘除   新类型可以表示的最大值   直到该值在新类型的范围内。

     

3 否则,将对新类型进行签名,并且值不能为   代表其中;结果要么是实现定义的,要么是   会产生一个实现定义的信号。

由于无法在unsigned short中表示值0x80 == -128,因此发生了第2段中的转换。

答案 1 :(得分:2)

char具有实现定义的签名。它是签名的还是未签名的,取决于编译器。从某种意义上说,char是第三种字符类型,请参见thischar具有不确定的(不可移植的)签名,因此决不能用于存储原始数字。

但是在这种情况下没关系。

  • 在您的编译器上,char已签名。
  • char a = 0x80;以特定于编译器的方式强制从0x80的类型int转换为char。通常在2的补码系统上,这将意味着char的值是-128,就像这里的情况一样。
  • b = (unsigned short)a;强制从charunsigned short 1)的转换。 C17 6.3.1.3有符号和无符号整数然后说:

      

    否则,如果新类型是无符号的,则通过重复加或   比新类型可以表示的最大值多减去一个   直到该值在新类型的范围内。

    比最大值多一个65536。因此,您可以将其视为-128 + 65536 = 65408

  • 65408的无符号十六进制表示形式为0xFF80。任何地方都没有扩展标志!


1)不需要强制转换。当=的两个操作数都是算术类型时,在这种情况下,右操作数将隐式转换为右操作数的类型(C17 6.5.16.1§2)。