目录
整型家族分类:
C语言中的整型家族一般包含char,short,int,long,其中根据数据性质的不同,如温度等有正值,也有负值,而年龄、长度等只有正值一说,又可分为有符号和无符号,具体如下:
char:unsigned char / signed char (char的符号性质由编译器决定)
short:unsigned short [int] / signed short [int] (short = signed short)
int:unsigned int / signed int (int = signed int)
long:unsigned long [int] / signed long [int] (long = signed long)
有符号的数据,最高位代表符号位,0-正;1-负 ,如char类型为一个字节大小,八个比特位,一个有符号的char类型最高位是符号位,数值位有7位,所表示的范围是-128~127,而一个无符号的char类型八个比特位均是数值位,所表示的范围是0~255;short类型为2个字节大小,16个比特位,一个有符号的short类型最高位是符号位,数值位有15位,所表示的范围是-32768~32767,而一个无符号的short类型16个比特位均是数值位,所表示的范围是0~65535
整型在内存中的存储:
1、原码、反码、补码
计算机整数有三种表示形式:原码、反码和补码。对于正数,原、反、补码均相同,负数的原码、反码、补码是需要计算的,计算规则如下:
原码:直接将数值按照正负数的形式翻译成二进制。
反码:在原码的基础上,符号位不变,其他位按位取反。
补码:反码加一。
2、数值的存储和计算
在计算机中,数值一律用补码表示和存储,原因在于,使用补码可以将符号位和数值位统一处理,补码与原码相互转换,其运算过程也是相同的,不需要额外的硬件电路。
#include<stdio.h>
int main()
{
int a=10;//整型值
/*
原码:00000000000000000000000000001010
反码:00000000000000000000000000001010
补码:00000000000000000000000000001010
*/
int b=-10;//整型值
/*
原码:10000000000000000000000000001010
反码:11111111111111111111111111110101
补码:11111111111111111111111111110110
*/
return 0;
}
同一个数据,打印方式不同,打印的值也不一样,如下面这个例子中:u%是打印无符号数,打印的一定是无符号数,即使不是无符号数,也认为是无符号数打印;d%是打印有符号数,打印的一定是有符号数,不是有符号数,也认为是有符号数打印。
#include<stdio.h>
int main()
{
unsigned int ch=-10;
//补码:11111111111111111111111111110110
printf("%u\n",ch);//4294967286
//u%是打印无符号数
printf("%d\n",ch);//-10
//d%是打印有符号数
return 0;
}
3、大小端字节序存储
计算机以字节为单位,每个地址单元都对应着一个字节。C语言中,除了 8 bit 的 char 之外,还有16 bit 的 short 、 32 bit 的 long,对于位数大于 8 位的处理器,如 16 或者 32 位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题,因此就导致了大小端存储模式。
大端存储:
把一个数据的低位字节处的数据放在高地址处,把高位字节处的数据放在低地址处。
小端存储:
把一个数据的低位字节处的数据放在低地址处,把高位字节处的数据放在高地址处。
如 int a=0x11223344;
对 0x11223344 来说,44 是最低位字节数,而 11 是最高位字节数
低地址--------------------------------高地址
11 22 33 44 --- 大端字节序存储低地址---------------------------------高地址
44 33 22 11 --- 小端字节序存储
如下面是一个验证当前编译器是大端存储还是小端存储的代码:
#include<stdio.h>
int main()
{
int a=1;
//00000000000000000000000000000001
//0x 00 00 00 01
char*p=(char*)&a;
//强制类型转换,char*只能访问一个字节,看第一个字节是01还是00
if(*p==1)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
}