C语言深度剖析--读书笔记4_signed/unsigned关键字

来源:互联网 发布:淘宝阶层有什么区别 编辑:程序博客网 时间:2024/06/08 05:53

signed/unsigned关键字

 

1:char类型默认是signed

如下代码:

char a[1000];

int i;

for(i=0;i<1000;i++)

{

    a[i]=-1-i;

}

printf("%d\n",strlen(a));//在用strlen运算时,从数据起始,直至遇到第一个\0

 打印结果:255

 

分析过程如下:

a[0]= -1,对应的补码为 0xff 1 1111111

a[1]= -2,对应的补码为 0xfe 1 1111110

a[127]= -1 – 127= -128,对应的补码为 0x80 1 0000000

a[128]= -1 – 128= -129 //-129需要9位才能存储,而char只有8位,故发生溢出,高位舍弃:

//首先,计算机计算-1 – 128得到 -129。这个过程是不存在舍弃问题的。

//第二步,- 129 赋值给a[128]就出现了问题。因为a[128]一个char类型,只有位,无法完全容纳- 129.只能把高位丢弃

//-129对应的补码为:1 0 1 1 1 1 1 1 1现在丢掉高位,即截取后8得到:

0 1 1 1 1 1 1 10x7f。注意,这是一个正数127.

 

接着计算a[129]

a[129]= -1 – 129 = -130//同样-130无法用8位来表示

// -130的补码为 1 0 1 1 1 1 1 1 0,截取后8位得到:0 1 1 1 1 1 1 00x7e即正数126

a[255]=-1-255=-256

//对应补码:1 1 0000 0000,截后8位(即存到char中的)为:000000000x000

 

a[256]= -1–256= -257。对应补码:1 0 1111 1111,截后8位为:1111 1111 0xff-1

a[257]= -1–257= -258。对应补码:1 0 1111 1110,截后8位为:1111 1110 0xfe-2

注意,这里发现从a[256]开始,又回到了a[0]的状态。相当于一个循环。(a[0]=a[256],a[1]=a[257]… 

 

结果分析:

注意到,存到a[255]的值为0,0对应的ascii码为 null,即结束符。所以在执行strlen(a)的时候,到a[255]就认为结束了。故打印出结果为255

 

补充1:把int值赋给char类型

系统会把 int值对应的2进制,存到char变量的那8位内存上。

例如:char a=65

内存中a为:0100 0001,如果要用%c的格式打印a时,会把65对应的ascii字符打印出来,即’A’。如果要用%d的格式打印a,那么打印出:65

 

补充2char类型的赋值区别

char c1 = 0; //把数值0存到字符变量c1

char c2 = ‘\0’;//把字符 ‘\0’即结束符,在ascii表中对应的十进制数即0,存到变量c2

char c3 = ‘A’;//字符’A’ascii表中对应的十进制数,即65存到变量3

 

注意1ascii码表中,存在一个十进制数到字符的映射。

注意2’\0’ascii表中对应的十进制数为0,所以char c =0 等价于 char c=’\0’

 

 

补充3把一个负数,转成补码的方式。

先计算该绝对值的补码(正数的补码=原码),再将绝对值的补码,最高位改为1,剩余位取反加1

 

 

2:signedunsigned之间的隐式类型转换

如下代码:

int i=-20;

unsigned int j=10;

 if(i+j>0)//编译器会自动的把i+j的结果转为unsigned类型,而unsigned一定是大于等于0

    printf("conversed~!\n");

else

    printf("unconversed~!\n");

打印结果:conversed~

 

结果分析:

在运算的时候,会把int值,隐式的转换为unsigned类型。

i= -20-20的补码为:1…1110 1100 0Xffffffed。当将之转成unsigned类型的时候,这样i就会变成一个很大的正数