补码,有符号数,无符号数,C语言

比较有意思的两点:一,计算机补码表示;二,计算机如何区分无符号数和有符号数;

一:补码

1.补码的定义:

1.1.正数的补码是其本身;

1.2.负数的补码是符号位不变,其余位按位取反 ,再加1;

1.3.补码的补码还是自身;即对补码再做一次补码运算,得到原码。

2.计算机中存储数据是以补码的形式;

   1 #include <stdio.h>
   2 
   3 int main(int argc, char *argv[])
   4 {
   5         int i = -1;
   6         char tmp1 = 0b01010101;//border to distinguish;
   7         char j = -1;
   8         char tmp2 = 0b10101010;//border to distinguish;
   9 
  10         return 0;
  11 }

利用gdb:x /8tb 0x************;//tmp2对应的地址;查看存在内存里的值;

(gdb) p &tmp2
$6 = 0x7fffffffe329 "\252\377U\377\377\377\377\001"
(gdb) x /8tb 0x7fffffffe329
0x7fffffffe329:	10101010	11111111	01010101	11111111	11111111	11111111	11111111	00000001
(gdb) 

可以看到i在内存里是:0b11111111 11111111 11111111 11111111,占4个字节;(-1的补码);

               j在内存里是:0b11111111                                              ,占1个字节;(-1的补码);

3.补码溢出

char a[i];
a[i] = -128;
a[i] -1 = 127;

-128是char型变量能表示的最小负数,再减去1,就会溢出,高位被丢弃;剩下的低八位,是7f;即127;这是补码提供一个巧合之处,这种循环的含义,很是神奇!!!

3.1补码这种被截断保持原有值的性质,也很神奇!!!

int i = -1;
char j = i;

变量j由于补码的性质截取了i的低八位,j的值依然为-1;

若是计算机采用原码存储:i在内存里是:0b10000000 00000000 00000000 00000001,占4字节;

                                            j截断i的低八位,就变成了                                0b00000001,占1字节;

j的值就变成了1;

那么考虑下面这个例子:

int m = -129;
char j = m;

这个截断之后,j变成了127;从循环意义上保持了原有的值;

二,无符号数和有符号数的区分:

清华大学,张悠慧老师,《汇编语言程序设计》

在硬件层面,不区分无符号数和有符号数;

编译器来区分无符号数和有符号数,通过条件码的cf, zf位;

图中w为数据位宽,例如图中w=4;

计算机如何区分无符号数和有符号数?

反汇编看一下区别:
 

#include <stdio.h> 
#include <string.h> 
 
int main()
{
    int x = 2; 
    char * str = "abcd"; 
    int y = (x - strlen(str) ) / 2;
    
    printf("%d\n",y);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值