文章目录提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
- 前言
- 一、数据类型基本归类
- 1.C语言中给的基本内置类型与归类
- (1)整型家族
- (2)浮点型家族
- (3)构造类型
- (4)指针类型
- (5)空类型
- 二、整型在内存中的存储
- 2.1原码,反码,补码
- 2.2大端存储和小端存储
- 2.3练习
- (1)
- (2)
- (3)
- (4)
- (5)
- 三:浮点数在内存中的存储
- 3.1浮点数在内存中的存储规则
- 3.2练习
- 总结
前言
提示:这里可以添加本文要记录的大概内容:
了解了数据在内存中如何存储,如何取用,对我们修改bug很有帮助
提示:以下是本篇文章正文内容,下面案例可供参考
一、数据类型基本归类 1.C语言中给的基本内置类型与归类 (1)整型家族int----------------------------4个字节
char-------------------------1个字节(内存中以ASCII值存放,所以算是整型家族的1一员)
short------------------------2个字节
long-------------------------4 / 8个字节
long long------------------8个字节
== 注:这些数据类型又分为signed和unsigned两种类型。==
(2)浮点型家族float
double
== 两种类型的精确度不同,后面会谈到 ==
(3)构造类型(4)指针类型数组类型
结构体类型(struct)
枚举类型(enum)
联合类型(union)
(5)空类型int*
char*
float*
void*
二、整型在内存中的存储void
int x=10; int y=20;
类似x,y这样的变量在内存中会开辟四个字节的空间,那么会如何存储呢?
2.1原码,反码,补码计算机中的整数通过原码,反码,补码存放在内存中。
对于signed类型的数据来说,这三种表示方法通常都有符号位和数值位两部分。
符号位是二进制的第一个数字,用1表示正,用0来表示负。
正数的原,反,补都是一样的
负数的原码可以直接通过数值翻译
反码将符号位不变,其他位取反得到
补码课通过将反码加一得到
计算机中整型在内存中存储的都是补码
运用补码可以将符号位和数值位进行统一处理,而不需要拆开分别计算
2.2大端存储和小端存储大端存储就是将数据的低位存放到内存高地址处,数据的高位放在内存的低地址处
小端存储就是将数据的高位存放到内存高地址处,数据的低位放在内存的低地址处
#includeint main() { int a = 10; int b = -10; return 0; }
a的值是10,转化为十六进制为0x0000000a,如图就是小端的存储模式
那么如何用代码进行大端小端的判断呢
以int a = 1来计算
以十六进制存放为0x00000001
大端中00 00 00 01
小端中01 00 00 00
可以通过内存中数据的第一个字节可以判断出是大端还是小端
所以可以通过以下代码来求出
#includeint main() { int a = 1; char b = *((char*)&a); printf("%dn", b); return 0; }
2.3练习 (1)取出a的地址,进行强制类型转化,取出第一个字节内的数值,赋给b,进行打印
//输出什么? #includeint main() { char a= -1; signed char b=-1; unsigned char c=-1; printf("a=%d,b=%d,c=%d",a,b,c); return 0; }
(2)打印时要进行整型提升
-1作为整型,补码为11111111111111111111111111111111,截断后,变成11111111
通过a,b,c的不同类型来进行判断值的大小
#includeint main() { char a = -128; printf("%un",a); return 0; }
(3)-128的补码为:11111111111111111111111110000000,截断后10000000
因为a是一个char类型的数据,所以整型提升后为11111111111111111111111110000000
以无符号形式打印出来
#includeint main() { char a = 128; printf("%un",a); return 0; }
(4)解释过程同(2)
int main()
{
char a[1000];
int i;
for(i=0; i<1000; i++)
{
a[i] = -1-i;
}
printf("%d",strlen(a));
return 0;
}
(5)strlen这个函数会从给出的地址往后读,直到遇到‘ ’,那么当a[i]==' ’时,就停止
如图所示,a[i]的数值会随着圈的逆时针变化
#includeunsigned char i = 0; int main() { for(i = 0;i<=255;i++) { printf("hello worldn"); } return 0; }
三:浮点数在内存中的存储 3.1浮点数在内存中的存储规则unsiged char类型最大值就是128,所以会打印死循环
任一个二进制浮点数在内存中存储的形式为
V=(-1)^S* M *2 ^E
(-1)^S表示符号位,当S=0,V为正数;当S=1,V为负数。
M表示有效数字,大于等于1,小于2。
2^E表示指数位。
就比如5.0,二进制为101.0==>(-1)^0 * 1.010* 2^2
对于一个32位的平台来说:
对于一个64位平台来说:
== 注:对于有效数字M,由于它的大小为1~2,所以系统默认将第一位的1舍去不存,在使用时加上(如1.001在存储时只放001)。
对于无符号E来说,可能存在负数的情况,所以我们就在存储时给它加上一个中间数。32位平台加127,64位平台加1023
下面给一道例题解释
int main()
{
int n = 9;
float *pFloat = (float *)&n;
printf("n的值为:%dn",n);
printf("*pFloat的值为:%fn",*pFloat);
*pFloat = 9.0;
printf("num的值为:%dn",n);
printf("*pFloat的值为:%fn",*pFloat);
return 0;
}
总结n的十六进制表示为0x00 00 00 09
转化为二进制为0 00000000 00000000000000000001001
这里的指数位置全为0,我们上面有介绍到,指数位置需要加一个中间数127,所以原本的指数是很小的,所以以浮点数打印出来是很小的,直接为0
再以浮点数9.0,来存放进去,二进制形式为1001.0==>(-1) ^ 01.00102^3
所以放进去为01000001000100000000000000000000
再把这个二进制换成整数,就是结果
数据在内存中如何存储,有助于我们深度了解bug的成因,这也是我的第一次写博客,有什么不对的地方欢迎指出。



