【问题标题】:Range of unsigned char in C languageC语言中无符号字符的范围
【发布时间】:2015-06-30 21:53:36
【问题描述】:

据我所知,C 中无符号字符的范围是 0-255。但是当我执行下面的代码时,它会打印 256 作为输出。这怎么可能?我从“测试你的 C 技能”一书中得到了这段代码,其中说 char 大小是一个字节。

main()
{
 unsigned char i = 0x80;
 printf("\n %d",i << 1);
} 

【问题讨论】:

  • 发布的代码将导致编译器发出一些警告。例如,编写 main() 函数只有 2 种有效方式(另加一种可选方式)。 1) int main( void ) 2) int main( int argc, char * argv[]) 和可选:int main()。请注意,它们都有一个“int”返回类型。大多数情况下,当从 main() 返回时,需要“有效”状态指示。所以最后一个可执行语句应该是'return(status);'其中状态通常为 0,除非发生错误
  • 0x80 不是 255,而是 128。无符号字符被“提升”为无符号整数。所以将 0x00000080 左移一位是 0x00000100。打印结果为 256。建议阅读 C 中的参数提升
  • 请注意,unsigned char 不限于 0-255 范围内。
  • @user3629249 如果您声明一个函数而不指定返回类型,则隐式返回int。此外,int main(void) 不是main 函数的可移植声明。

标签: c


【解决方案1】:

因为&lt;&lt;* 的操作数经过整数提升。它实际上等同于(int)i &lt;&lt; 1


* 这对于 C 中的大多数运算符都是正确的。

【讨论】:

  • @GrzegorzSzpetkowski:是的,你是对的。谢谢。
【解决方案2】:

有几件事正在发生。

首先,表达式i &lt;&lt; 1 的类型为int,而不是char;文字1 的类型为int,因此i 的类型被“提升”为int,并且0x100 完全在有符号整数的范围内。

其次,%d 转换说明符期望其对应的参数具有 int 类型。所以这个参数被解释为一个整数。

如果要打印带符号的char 的数值,请使用转换说明符%hhd。如果要打印无符号char 的数值,请使用%hhu

【讨论】:

  • 我猜 %d 将 unsigned char 提升为 int。我试过 printf("\n %hhu",i
  • @Amandeepsinghsaini.gmail.com:否:格式字符串不会影响参数转换(即使 8 位 unsigned char 的移位结果将是 0)。对于hhu:阅读here:它需要一个'int'并解释为char
  • 与大多数二元运算符不同,按位移位运算符不会对其操作数执行“通常的算术转换”。操作数经过整数提升,但不强制具有相同的宽度或符号。移位表达式的类型是其左侧操作数的提升类型,在这种情况下将是 int,而不管其右侧操作数的类型。第 6.5.7 和 6.3.1.1/2 节
  • 对于移位运算符,结果类型仅是左操作数的类型。如果小于(低于等级)int,则仅提升右侧。
  • 请注意,如果实际值大于最大值,则将 unsigned 类型解释为 signed 是实现定义的。 signed 类型的可表示值。
【解决方案3】:

对于算术运算,在执行运算之前,char 被提升为 int。有关详细信息,请参阅the standard。简化:在执行操作之前,首先将“较小”类型带到“较大”类型。对于移位运算符,结果类型是左侧操作数的类型,而对于例如+ 和其他“组合”运算符是两者中较大的一个,但至少是 int。后者意味着charshort(以及它们的unsigned对应物总是被提升为int,结果也是int。(简化,详情请阅读标准)

另请注意,%d 采用 int 参数,而不是 char

补充说明:

  • unsigned char 不一定具有0..255 范围。检查limits.h,你会在那里找到UCHAR_MAX
  • char 和“byte”在标准中是同义词,但都不一定是 8 位宽(很可能适用于现代通用 CPU)。

【讨论】:

    【解决方案4】:

    正如其他人已经解释的那样,语句“printf("\n %d",i

     int main()
     {
         unsigned char ch = ~0;
         printf("ch = %d\n", ch);
         return 0;
     }
    
    Output:-
    M-40UT:Desktop$ ./a.out 
    ch = 255
    

    【讨论】:

      猜你喜欢
      • 2018-12-16
      • 1970-01-01
      • 2016-02-06
      • 2011-04-23
      • 2015-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多