c# 字符和整数相乘时会发生什么?

68bkxrlz  于 2023-04-18  发布在  C#
关注(0)|答案(2)|浏览(194)

我不明白当我将char变量和int变量相乘并将结果放入char中时发生了什么。
例如:

char p= (98*'b') ;
printf("%d",p);

为什么是-124?
我以为会满溢的。

ktecyv1j

ktecyv1j1#

“字里行间”发生了什么:

  • (98*'b')括号没有添加任何内容。
  • C语言中的所有东西都有一个类型,包括整型常量和字符常量。碰巧98'b'都是int类型。
  • 因此,乘法是在int上执行的,结果的类型是int.9604十进制或0x 2584十六进制。
  • 然后尝试将其存储在不能容纳如此大的值的char中。进一步的问题是char类型具有实现定义的有符号性,并且可以是有符号的或无符号的,当涉及到存储值时,它是不可移植的类型。Is char signed or unsigned by default?
  • 如果char是无符号的,则转换是定义良好的,您将获得值0x 84 hex / 132 dec。
  • 如果char是有符号的,则转换是实现定义的。然而,大多数具有2的补码的主流系统将仅将0x 84转换为1字节的2的补码数。即-124。
  • 严格来说,将char传递给printf("%d",...并没有很好的定义,因为%d意味着它需要一个整数。(“default argument promotions”),如果是char,它将被提升为int。要可靠地打印有符号的char整数值,请使用%hhd

最佳做法:

  • char除了用于存储字符外,永远不要用于其他用途。避免将其用于算术,尤其是位操作。
  • 在stdint. h中使用可移植字节类型uint8_t
  • printf使用正确的格式说明符。
ar5n3qh5

ar5n3qh52#

这是因为char是有符号的。有符号的char的值为-128至127。
因此,当你得到值0x 2584时,MSB被忽略,你实际上得到值0x 84。
现在,0x 84在二进制中是:

1000 | 0100 = 0x84

设置最高有效位,因此将其视为负数。
因此,如果设置了最高有效位,则我们有:

1000 | 0000 = 0x80 = -128
1000 | 0001 = 0x81 = -127
1000 | 0010 = 0x82 = -126
1000 | 0011 = 0x83 = -125
1000 | 0100 = 0x84 = -124

这就是你得到的。
如果你正在寻找一个值0x 2584,那么你需要使用一个16位的数据类型作为最小值,在你的平台上可能是一个普通的int。
如果你正在寻找0x 84的实际值,那么你需要使用unsigned char数据类型。类似于:

unsigned char p= (98*'b') ;
printf("%d",p);

相关问题