大家好 今天分享的知识是C语言数据在内存中如何存储的知识
目录
4、signed char、 unsigned char、signed short、unsigned short的取值范围
1、整型的存储
整型主要包括char 、 short、 int 、 long
C语言没有明确规定是char 是signed char还是unsigned char
其余默认都是有符号的signed
构造类型
主要分为:数组类型、结构体类型 (struct)枚举类型(enum)联合类型(union)
其中整型都是以补码的方式存储在内存中 打印的时候打印的原码
正数的原码、反码、补码相同
其中一个数先转化为二进制的原码
其反码是符号位不变 其余位数取反 补码是反码+1
补码到原码 就是1、将补码-1在取反 2、补码先取反在-1
2、大小端存储模式
大端存储(C51等常见):数据的低位保存在内存的高地址中,数据的高位保存在内存的低地址中
小端存储(X86等常见):数据的低位保存在内存的低地址中,数据的高位保存在内存的高地址中
3、char、 short等的整型提升
char占一个字节(8个bit)在打印成int(占四个字节 32个bit)时 需要整型提升将8位补成32位
short占二个字节(16个bit)在打印成int(占四个字节 32个bit)时 需要整型提升将16位补成32位
有符号signed的整型提升补符号位
无符号unsigned的整型提升高位补0
同样的如果int需要用char打印的话只能取低的8位bit
4、signed char、 unsigned char、signed short、unsigned short的取值范围
char(默认signed char)在内存中根据存储原则范围是-128~127
unsigned char在内存中根据存储原则范围是0~255
short(默认signed short)在内存中根据存储原则范围是-32768~32767
unsigned shortr在内存中根据存储原则范围是0~65535
5、课堂中的几个例子
int main()
{
char a = -1;
//-1的原码 10000000000000000000000000000001 反码11111111111111111111111111111110 补码11111111111111111111111111111111
//因为char中只能放一个字节 8bit所以需要截断 补码11111111
signed char b = -1;
//-1的原码 10000000000000000000000000000001 反码11111111111111111111111111111110 补码11111111111111111111111111111111
//因为char中只能放一个字节 8bit所以需要截断 补码11111111
unsigned char c = -1;
//-1的原码 10000000000000000000000000000001 反码11111111111111111111111111111110 补码11111111111111111111111111111111
//补码 11111111
printf("a=%d,b=%d,c=%d", a, b, c);
//打印时要进行整型提升
//a b 有符号所以高位补符号位 11111111111111111111111111111111 反码11111111111111111111111111111110 原码10000000000000000000000000000001
//c 无符号位 高位补0 00000000000000000000000011111111 补完以后符号位是0为正数 补码 反码 原码相同 所以原码为00000000000000000000000011111111
}
int main()
{
char a = -128;
//-128 原码 10000000000000000000000010000000
// 反码 11111111111111111111111101111111
// 补码 11111111111111111111111110000000 因为char只能存一个字节 8比特 所以需要截断 补码为10000000
printf("%u\n", a); //%u只是体现打印的是无符号整型 a在整型提升时是char类型 是有符号的高位补符号位
//11111111111111111111111110000000 补完以后的补码 这时候因为打印的是无符号整型 所以原反补相同
//11111111111111111111111110000000 转化为10进制4,294,967,168
}
int main()
{
char a = 128;
//128 原码00000000000000000000000010000000 正数原反补相同 char需要截断 10000000
//对a进行整型提升 a的类型char有符号位 高位补1 11111111111111111111111110000000
//%u 无符号打印整型 所以没有符号位 原反补相同 打印11111111111111111111111110000000 转化十进制打印4,294,967,168
printf("%u\n", a);
return 0;
}
int i = -20;
// -20原码 10000000000000000000000000010100
//反码 11111111111111111111111111101011
//补码 11111111111111111111111111101100
// 10原码 00000000000000000000000000001010 正数原反补相同
//i+j 补码 11111111111111111111111111110110
//-1 11111111111111111111111111110101
//取反 10000000000000000000000000001010 转化成十进制 -10
unsigned int j = 10;
printf("%d\n", i + j);
unsigned int i;
for (i = 9; i >= 0; i--)
{
printf("%u\n", i);
}
//无符号位没有负数 会一直循环 减到0后变成很大的数 继续减0 又变成很大的数
int main()
{
char a[1000];
int i;
for (i = 0; i < 1000; i++)
{
a[i] = -1 - i;
}
printf("%d", strlen(a)); //char数组由于只能存放一个字节 8bit 所以范围-128~127 范围是-1 -2 -3···-128、127、126 ····0
//总共127+128 255个
return 0;
}
unsigned char i = 0; //取值范围0~255 所以会死循环一直打印hello world
int main()
{
for (i = 0; i <= 255; i++)
{
printf("hello world\n");
}
return 0;
}
6、浮点型的存储
首先 浮点型在内存中的存储是与整型不一样的
浮点型有float、double类型的
例如5.5 可以写成二进制的101.1 小数点后面都是2的-1 -2 ····次方 因此精度上依然不够准确
小数点前面的5可以写成为二进制的101
此时注意 一般在写前面的时候会保证在1~2之间 所以101.1小数点往左移两位 可以写成1.011*2^2
整体的公式为(-1)^0*1.011*2^2*2^(-1)
其中S是0 是0代表正式 是1则代表负数 因为前面有-1
M为1.01 其中1<=M<2
E为-1 小数点后面
浮点数的存
在举个例子 9.5
可以写成1001.1
(-1)^0*1.0011*2^3
S=0 M=1.0011 E=3
是将S、M、E存起来
单精度是占4字节 32bit
单精度 S(1bit) E(8bit)(存的时候E需要加上127) M(23bit) (只存小数点后面的 将小数点前面的1省去)
单精度是占8字节 64bit
双精度 S(1bit) E(11bit) 存(的时候E需要加上1023) M(52bit)
浮点数的取
分三种情况 :
1、当E不为全0或全1 (怎么存的怎么逆着取出来)
2、当E为全0 E取-126 或者-1022 结果几乎等于0
3 当E为全1 趋近于正负无穷大了