char类型内存存储和加减问题

本文通过具体的C语言代码示例,详细解析了不同字符类型在进行运算时的内部处理过程,包括整数提升、符号扩展和左截断等概念,并解释了在特定平台下出现的运算结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天处理一些char类型存储的一些问题,附上所分析的源代码

 1 #include<stdio.h>
 2 
 3 int main(int argc,char *argv[])
 4 {
 5 
 6     char cA;
 7     unsigned char ucB;
 8     unsigned short usC;
 9     cA = 128;
10     ucB = 128;
11 
12     usC = cA+ucB;
13     printf("0x%x\n",usC);
14 
15     usC=cA+(short)ucB;
16     printf("0x%x\n",usC);
17 
18     usC = (unsigned char)cA+ucB;
19     printf("0x%x\n",usC);
20 
21     usC=cA+(char)ucB;
22     printf("0x%x\n",usC);
23 
24 
25     return 0;
26 
27 }

(unsigned short)(cA+(char)ucB) = 65280  0xFF00,求解答!!

 

下面是unix论坛高手给的解答,很专业,谢谢Alister!!

Short version:

Integral promotion with sign extension followed by left truncation.


Long version:

Whether char is signed or unsigned depends on the implementation. Working backwards, 0xFF00 suggests that on your platform char is signed. I will also assume that on your platform char is 1 byte, short is 2 bytes, and int is 4 bytes.

Initial values:
signed char cA = 1000 0000 (0x80) (-128)
unsigned char ucB = 1000 0000 (0x80) (128)

Expression as written:
cA + (char)ucB

Arithmetic in C doesn't use anything smaller than an int. In an expression whose operands are all char or short, on a platform where char is signed, every operand is always promoted to int.

Expression as evaluated:
(int)cA + (int)(char)ucB

Before moving on to each operand's promotion to int, let's take a close look at (char) ucB .

The result of casting ucB to char is unpredictable for a couple of reasons. First, is char signed or unsigned? As mentioned earlier, that depends on the implementation. If char is unsigned, then your cast of ucB has no effect, because the original type and the new type are identical. If, however, char is signed (as appears to be the case here), you will be casting from an unsigned type to a signed type of identical width. Even though both types use the same number of bits, since a bit is lost to the sign, the new, signed type cannot represent the full range of values of the original type. Obviously, this is also true when the new type is narrower. In both cases, ANSI says that the result of converting from an unsigned type to a signed type of equal or lesser width is implementation-defined.

Your implementation seems to have left the original bit-field as is. So before and after the cast, unsigned char to signed char, ucB still holds 1000 0000 (0x80).

Before adding, each value is promoted to int. Promoting a signed type to a wider signed type is done through sign-extension. cA and ucB, now both of identical type and value, are promoted from signed char to signed int:
1000 0000 (0x80) (-128) --> 1111 1111 1111 1111 1111 1111 1000 0000 (0xffffff80) (-128)

Finally, we can perform some arithmetic:

Code:
  1111 1111 1111 1111 1111 1111 1000 0000    (0xffffff80) (-128)
+ 1111 1111 1111 1111 1111 1111 1000 0000    (0xffffff80) (-128)
=========================================
1 1111 1111 1111 1111 1111 1111 0000 0000    (0xffffff00) (-256)


The carry bit (in red) is ignored.

The assignment to usC requires converting a signed type to a narrower unsigned type, int to unsigned short. This is done through left truncation:
1111 1111 1111 1111 1111 1111 0000 0000 (0xffffff00) (-256) --> 1111 1111 0000 0000 (0xff00) (65280)

Keep in mind that due to the implementation-defined situations mentioned above, a different platform can yield different results.

转载于:https://www.cnblogs.com/micky-zhou/archive/2012/08/17/2643380.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值