目录:
- 数据类型介绍
- 整形在内存中的存储:原码、反码、补码
- 大小端字节序介绍及判断
- 浮点型在内存中的存储解析
1.数据类型介绍
char //字符数据类型
short //短整型
int //整形
long //长整型
long long //更长的整形
float //单精度浮点数
double //双精度浮点数
1.1基本类型归类
1整形
char
unsigned char
signed char
short
unsigned short[int]
signed short[int]
int
unsigned int
signed int
long
unsigned long[int]
signed long[int]
2浮点数家族
float
double
3构造类型
数组类型
结构体类型 struct
枚举类型 enum
联合类型 union
4指针类型
int pi;
char pc;
float pf;
void pv;
5空类型
void 表示空类型(无类型)
通常应用于函数的返回类型、函数的参数、指针类型
2.1整形在内存中的存储:原码、反码、补码
1对于负数而言:
原码:直接将二进制按照正负数的形式翻译成二进制就可以。
反码:将原码的符号位不变,其他位依次按位取反就可以得到了。
补码:反码 + 1就得到补码。
2对于正数
正数的原、反、补码都相同。
对于整形来说:数据存放内存中其实存放的是补码。————重点
内存中存储的都是补码 且顺序是相反的
#include<stdio.h>
int main()
{
int a = 0x12345678;
return 0;
}
例:
a在内存中的存储为 78 56 34 12
3. 大小端字节序介绍及判断
大端(存储)模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中;
小端(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位, ,保存在内存的高地址中。
判断其在内存中存在为大小端? 小端
#include <stdio.h>
int check_sys()
{
int i = 1;
return (*(char *)&i);
}
int main()
{
int ret = check_sys();
if (ret == 1)
{
printf(“小端\n”);
}
else
{
printf(“大端\n”);
}
return 0;
}
相关练习题
#include <stdio.h>
int main()
{
char a = -1; 正常模式下的char
signed char b = -1; 整形模式下的char
unsigned char c = -1; 正形模式下的char unsigned表示这个定义下的数字全部为正数
printf(“a=%d,b=%d,c=%d”, a, b, c);
return 0;
}
a = -1; b = -1; c = 255;
#include <stdio.h>
int main()
{
char a = -128;
printf(“%u\n”, a);
return 0;
}
10000000 00000000 00000000 10000000 原码
11111111 11111111 11111111 01111111 反码
11111111 11111111 11111111 10000000 补码
因为 %U 是打印无符号数 所以打印
01111111 11111111 11111111 10000000
即为 429 496 7168
#include <stdio.h>
int main()
{
char a = 128;
printf(“%u\n”, a);
return 0;
}
char类型在内存中的大小存贮为
0 1 2 3 4 5 6 7 ,,,,125 126 127 -128 -127 -126 ,,,,,,-3 -2 -1 然后继续0 2 3 4 周而复始
所以128 = -128
#include <stdio.h>
int main()
{
int i = -20;
unsigned int j = 10;
printf("%d ", i + j);
return 0;
}
-20 1,00010100 原码
1,11101011 反码
1,11101100 补码
10 0,00001010 原码=反码= 补码
1,11110110 结果 补码
1,11110101 反码
1,00001010 原码 即为-10
结果为10
#include<stdio.h>
int main()
{
unsigned i;
for (i = 9; i >= 0; i++)
printf(“%u\n”, i);
return 0;
}
当i从9到0时,正常, 当i=0时,i-1=(-1) 因为是unsigned 所以i-1 = 1 然后就死循环
#include<stdio.h>
int main()
{
char a[1000];
int i;
for (i = 0; i<1000; i++)
{
a[i] = -1 - i;
}
printf(“%d”, strlen(a));
return 0;
}
结过为 255
char 的大小为 012345 127 -128 -127 -126 -3-2-1 012345
#include <stdio.h>
unsigned char i = 0;
int main()
{
for (i = 0; i <= 255; i++)
{
printf(“hello world\n”);
}
return 0;
}
255+1=0;所以死循环打印 hello wolrd
类比一下 其余类型也一样都有最大值与最小值,周而复始的运行 从0 到最大然后到最小
3.1浮点型在内存中的存储
常见的浮点数:3.14159 1E10
浮点数家族包括: float、double、long double 类型。
浮点数表示的范围:float.h中定义
int main()
{
int n = 9;
float *pFloat = (float *)&n;
printf("n的值为:%d\n",n);
printf("*pFloat的值为:%f\n",*pFloat);
*pFloat = 9.0;
printf("num的值为:%d\n",n);
printf("*pFloat的值为:%f\n",*pFloat);
return 0;
}
原因:
为方便观察,我会选择在数据合适位置进行断开,内存中数据不会断开都是连续的
1.n在内存中存储为:0000 0000 0000 0000 0000 0000 0000 1001
第一个数据正常读取
2.float pFloat = (float )&n;
这句代码含义是: 将数据类型为int的n的地址转换称为float类型,放在pFloat
我们知道 数据在内存中存储是固定的格式的,数据类型取决于如何把数据拿出来
也就是说上面代码中第二个让我们把0000 0000 0000 0000 0000 0000 0000 1001按照float类型输出:
0 01111110 00000000000000000001001
按照float*类型格式上述二进制可以写为:
(-1)^S * M * 2^E = (-1)0*0.00000000000000000001001*2(-126)
也即是一个非常接近零的数字
3.*pFloat = 9.0;的含义:将9.0这个浮点数存储在二进制中,即:
0 00001001 0000000000000000000000
第三个输出即将上述二进制数字用 整形的形式表达出来
4.第四个输出即为:将3中的二进制用float类型表达出来
num 和 *pFloat 在内存中明明是同一个数,为什么浮点数和整数的解读结果会差别这么大? 要理解这个结果,一定要搞懂浮点数在计算机内部的表示方法。
详细解读:
根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成下面的形式:
(-1) ^ S * M * 2 ^ E
(-1) ^ s表示符号位,当s = 0,V为正数;当s = 1,V为负数。
M表示有效数字,大于等于1,小于2。
2 ^ E表示指数位。
举例来说: 十进制的5.0,写成二进制是 101.0 ,相当于 1.01×2 ^ 2 。 那么,按照上面V的格式,可以得出s = 0,M = 1.01,E = 2。
十进制的 - 5.0,写成二进制是 - 101.0 ,相当于 - 1.01×2 ^ 2 。那么,s = 1,M = 1.01,E = 2。
IEEE 754规定: 对于32位的浮点数,最高的1位是符号位s,接着的8位是指数E,剩下的23位为有效数字M。
对于64位的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M。
特别提醒:M是一个1<M<2的数字,它的第一位绝对是一,所以我们可以省略这个一,以能够表示更准确的数字
E这个数字在8位和11位时,会出现负数,那么我们就需要给其加上一个127或者1023,使其变成一个整数
E不全为0或不全为1
这时,浮点数就采用下面的规则表示,即指数E的计算值减去127(或1023),得到真实值,再将有效数字M前
加上第一位的1。 比如: 0.5(1 / 2)的二进制形式为0.1,由于规定正数部分必须为1,即将小数点右移1位,
则为1.0 * 2 ^ (-1),其阶码为 - 1 + 127 = 126,表示为01111110,而尾数1.0去掉整数部分为0,补齐0到23位
00000000000000000000000,则其二进制表示形式为:
0 01111110 00000000000000000000000
E全为0
这时,浮点数的指数E等于1 - 127(或者1 - 1023)即为真实值, 有效数字M不再加上第一位的1,而是还原为
0.xxxxxx的小数。这样做是为了表示±0,以及接近于0的很小的数字。
E全为1
这时,如果有效数字M全为0,表示±无穷大(正负取决于符号位s);