C语言中关于char类型存储的分析 以及signed与unsigned的区别

char类型存储的分析



char和signed char


大家对char类型相信一定不会陌生的ANSI C 提供了3种字符类型,分别是char、signed char、unsigned char char相当于signed char或者

unsigned  char,但是这取决于编译器! 这三种字符类型都是按照1个字节存储的,可以保存 256个不同的值。 signed char取值范围是 -128 到 127


那么问题来的为什么signed char的取值范围是从 -128到127呢 先大家应该知道原码反码补码的概念以及他们之间的关系。

------------------------------------------------------------
正数的原码、反码和补码相同


负数将原码先进行除符号位取反然后再加一就可以得到他的补码
------------------------------------------------------------

现在继续,首先上面提到char可以保存256个不同的值,也就是说明他的二进制编码只能拥有8位有符号 的char占一个字 节, 最高位表示正负,其余的七位表示数值,七位二进制可以表示128个数(2^7 = 128) ,即0~127;加上符号位后,就 变成 了-127~-0,0~127,但是我们实际上char的取值范围为 -128~127,这时就会发现这个-0是什么东西,聪明人一眼就 来-0  和 -128有关系。。(当然不能瞎猜,我们要用事实 来证明)

首先呢计算机是以补码形式存储的   我列出-0和-128的原码反码补码

-0     原码    1000 0000
       反码    0111 1111
       补码    1000 0000

-128   原码   11000 0000
       反码   10111 1111
       补码   11000 0000


可以看出来这个其实根本不是-0,只是因为char类型只能存储8位二进制编码,而-128有9位,所以只能将他前 面的1截掉 ,所以给了 你一个错觉-0,这东西完全就是不存在的,你要记住他只是-128没有被截掉的那部分,但 是它还是属于-128。

unsigned char 取值范围是 0 到 255   但是char究竟相当于signed char呢还是相当于unsigned char呢??

这就是char和int的不同之处!

int==signed int,但是char不能简单以为==signed char

以我的编译器为例子




他们的值完全不同,但是为什么呢。

首先列出-1的原码反码补码

-1   原码   1000 0001
     反码   1111 1110
     补码   1111 1111

当为signed时可以看出来值为-1,但是当它为unsigneds时计算机只识别补码序列然后值就为255.

下面做两个小练习

1==》


#include<stdio.h>
 int main()
 {
    char a = -128;
    printf("%u\n",a);
    return 0;
}



现在看结果





其实第一次我看到这个心情也是日了狗了。。。。

完全解释不通。。。。。

我简单说一下我的理解,如果错了指出来,我们已经知道了-128的补码序列,现在把它提出来(1000 0000 ),但是你是

希望计算 机以%u的形式打印出来,所以你要对-128的补码形式进行扩展(整形提升),把它扩展成32位,由于扩展是根据你

自身的符号位扩 展,所以你往 它的前面加上24个1。然后%u他只是拿到你的序列将它打印出来,所以 他就打印出来我们

扩展出来的2进制序列, 也就是上面的 值。   

-128 整形提升后补码形式:

1111 1111 1111 1111 1111 1111 1000 0000


还有这里的%u,我们都应该知道数据在内存中是以补码形式存储的,现在%u输出也就是认为你就是无符号数,所以在%u的

角度来 讲,它直接从你的内存中拿出来的就是原码,直接输出内存中拿出来的数据.



2==》

我们再来看一个题

  #include<stdio.h>
  intmain()
  {
    char a = 128;
    printf("%d\n",a);
    return 0;
  }


看看结果:





这里我明明要%d要打印的是128,为什么打印出来-128.编译器坏掉了? 其实这里当你使用了%d还是发生了整形提升了,128的补码序列(1000 0000)

对它进行整形提升后是这样的


补码:  1111 1111 1111 1111 1111 1111 1000 0000
反码:  1111 1111 1111 1111 1111 1111 0111 1111
原码:  0000 0000 0000 0000 0000 0000 1000 0000


那么这个序列认识么?  前面不用看它的类型时char类型,所以在char中128是不存在的,然后char的取值范围是 127 ~ -128,所以 这里直接跳到

char取值范围最小的-128去。  





评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值