计算机中的有符号数有三种表示方法,即原码、反码和补码。 三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,而数值位三种表示方法各不相同。
原码:直接将二进制按照正负数的形式翻译成二进制
反码:对于负数来说,原码的符号位不变,其他位依次按位取反即得到其反码;正数的反码与原码相同
补码:对于负数来说,将其反码加1,可得到其补码;正数的补码与原码相同
在计算机系统中,使用补码,可以将符号位和数值域统一处理; 同时,加法和减法也可以统一处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。所以在计算机中,数值一律用补码来表示和存储。
int型数值在内存中的存储在计算机系统中,数值的存储方式分为大端和小端两种存储方式。
大端存储方式: 将一个数的低位字节序内容放在高地址位处,高字节序内容放在低地址处。
小端存储方式: 将一个数的高位字节序内容放在高地址位处,低字节序内容放在低地址处。
举个栗子:
int a=0x11 22 33 44;
大端存储:
低地址 高地址
11223344小端存储:
低地址 高地址
44332211举个栗子:a在计算机中是采用大端还是小端存储
分析:若为小端:01 00 00 00
若为大端:00 00 00 01
此时我们可以通过char类型指针指向&a的第一个字节的数据,即 char* p =(char*) &a;如果*p==1,则证明它是小端存储方式;否则为大端存储方式。代码如下:
#include<stdio.h> int main() { int a = 1; char* p =(char*) &a; if (*p == 1) { printf("小端\n"); } else { printf("大端\n"); } return 0; }运行结果:
我们再来看一下它的内存分配情况: 与结果一致,所以是小端存储。
习题:
#include <stdio.h> int main() { char a= -1; signed char b=-1; unsigned char c=-1; printf("a=%d,b=%d,c=%d",a,b,c); return 0; }分析:%d是整型,所以啊,a,b,c会进行整形提升
整型提升概念:
如果是有符号数据类型:正数填充0,负数填充1如果是无符号数据类型:填充0char a=-1
char a的补码:11111111
整形提升后的补码:11111111 11111111 11111111 11111111
反码:11111111 11111111 11111111 11111110
原码:10000000 00000000 00000000 00000001
所以:a=-1
signed char b=-1
signed char b的补码:11111111
整形提升后的补码:11111111 11111111 11111111 11111111
反码:11111111 11111111 11111111 11111110
原码:10000000 00000000 00000000 00000001
所以:b=-1
unsigned char c=-1
unsigned char c的补码:11111111
整形提升后的补码:00000000 00000000 00000000 11111111
反码:00000000 00000000 00000000 11111111
原码:00000000 00000000 00000000 11111111
所以:c=255