关于char,signed char 以及unsigned char 和整形提升的几道例题分析及总结

下面我会根据几道例题详细分析其内部逻辑:

#负数在内存中以补码形式存储,打印出负数应先转换成原码;正数在内存中也以补码形式存储,但由于正数的原码,反码,补码相等,因此打印出正数原码即补码;

#%u为打印十进制的无符号数字;%d为打印十进制的有符号数字;

#有符号的char范围是-128->127;无符号char范围是0->255;

一.

1.首先,由于负数在内存中存储的是其补码。对于-1,其原码为1000000.....00001(共32位),则反码为11111......11110(符号位为1不变);故补码为原码加1,即11111.....11111;由小端存储知在char类型下其在内存中会存储位于低地址的第一个字节,即补码低位(右边)算起的8为->11111111;

2.对于char 以及signed char而言,由于要打印出整形类型(%d),因此要先进行整形提升,符号位位最高位1决定,因此其提升完成的补码为->11111....11111(32位);对应打印出的原码为1000.....0001;即-1;

3.对于unsigned char而言,由于11111111中第一个1不再是符号位,因此打印出整形进行整形提升后,在前面24位全部补充上0,即变成00000.....0011111111;由于提升后的整形最高位为0,因此为正数,由因为正数的原码,反码,补码相等,则打印值为255;

4.综上,答案为-1;-1;255;

二.

 1.对于本例题,先求出a的原码,即为->10000...10000000,补码为1111....110000000,由于打印的a为char类型,由小端存储模式,其会取得地址的第一个字节(从右边数8个二进制位),即10000000;

2.由于a为char类型,因此最高位为符号位,故整形提升过程前面24个二进制位全部补上最高位1,变为->>1111....11110000000,此时打印出的是补码,应当再转换为原码再打印输出。

3.由于打印的是无符号数-->原码,补码,反码相同,则最后打印的二进制序列为1111....11110000000,因此最后的值为:4294967168。

三.下面给出有符号char范围在-128-<127的一个内在逻辑图:

 根据上图,在下面的例题中:

1.由于有符号char的范围是-128到127,由上图可知:a=128=127+1=-128!

2.因此char a的补码为->   10000000,进行整形提升->111....110000000;由于打印十进制的无符号数->原码等于补码->打印值与T2相同:4294967168。

四.

#对于有无符号数的相加,应当先转换成为补码(内存中为补码),再进行相加!

#本题大致思路:按照补码形式进行运算,最后格式化成为有符号整数!

1.先算出 i 和 j的补码,再相加,具体如下图所示:

 2.由-"结果"处的补码算出最终的原码值;

3.最终打印出的结果是-10;

#无符号数容易使代码死循环;

五.

 1.在本题中,由于i是以无符号数的格式进行输出,因此无论输入的是正数还是负数,都会以无符号的格式输出,

2.因此该程序会死循环;

六.

1.在本题中,由于无论输入怎样的整数,以unsigned char格式进行输出之后范围均在0-255之间;

2.因此同样会死循环;

七.

 1.根据T3中关于有符号char范围在-128-<127的内在逻辑图可知: a[1000]中存储的是-128到127的数字;

2.由于strlen()函数会在找到'\0'时停下来,而'\0'的值为1;在a[1000]数组中;分别存储的数字为->

{-1,-2,-3,.....-128,127,126,125......3,2,1,0......};直到取到的值为0的时候停止,此时前面共出现了

255个数字;

3.因此答案为255;

猜你喜欢

转载自blog.csdn.net/2201_75303014/article/details/128169485
今日推荐