摘要:有关内存文章目录有关内存前言一指针初阶指针大小指针类型解引用野指针成因未初始化越界指针指向的空间释放规避局部地址检查有效性指针运算整数指针指针关系运算时允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置
大体把握C语言后,要清楚C语言是一门偏底层的语言,因此就非常有必要来探究一下内存深处的样子,修炼我们的内功,对此有更深层次的理解.
指针就是变量,用来存放地址的变量。(存放在指针中的值被当做地址处理)
#include int main(){ int a = 10;//在内存中开辟一块空间 int *p = &a;//这里我们对变量a,取出它的地址,可以使用&操作符。 //将a的地址存放在p变量中,p就是一个之指针变量。 return 0;}
对于32位机器,有32根地址线,即有2^32个地址,可以操作4g的空间,笔者在下文对此有详细的介绍
C语言整体把握
既然不管何种类型指针大小都由32位与64位决定,那不同的指针类型有什么作用呢?
char *pc = NULL;int *pi = NULL;short *ps = NULL;long *pl = NULL;float *pf = NULL;double *pd = NULL;
*(解引用操作符)可以对地址(指针)变量 解引用通过地址对其内容做出修改
*pc = 10
#include int main(){ int n = 10; char *pc = (char*)&n; int *pi = &n; printf("%p/n", &n); printf("%p/n", pc); printf("%p/n", pc+1); printf("%p/n", pi); printf("%p/n", pi+1); return 0;}
经过调试可以发现int类型一次跳过四个字节,char类型一次跳过一个字节,即地址变量类型决定了指针移动的距离
位置不可只的指针,使用起来极其危险也没有意义
随意定义指针
#include int main(){ int *p;//局部变量指针未初始化,默认为随机值 *p = 20; return 0;}
#include int main(){ int arr[10] = {0}; int *p = arr; int i = 0; for(i=0; i<=11; i++) { //当指针指向的范围超出数组arr的范围时,p就是野指针 *(p++) = i; } return 0;}
初始化,不越界,释放置为空( NULL),局部变量地址慎用,检查有效性
尽量不要在子函数中直接返回指针,由于作用域与生命周期的限定,出函数时指针所指向的空间已经被销毁.
if(*p != NULL)//断言,需引头文件 //条件不为真时报错,对程序员十分友好assert(*p)
结合上文,常用于指针与数组——函数等的结合
可以得到两地址之间的元素个数
可以与数组越界后一位判定目的是否成立
存放地址的指针
int c= 0;int *p = &c;int **p = *p;
存放指针的数组
arr数组里存放五个元素,每个元素都是int*类型int* arr[5]
引图可以当做引言,但不可视为栈帧,下期详讲
char //字符数据类型short //短整型int //整形long //长整型long long //更长的整形float //单精度浮点数double //双精度浮点数
int* p;char* p;float* p;void* p;
整形分配四个字节
00000000 00000000 00000000 00000000
内存中,对整形,存储并使用的是他的二级制位的补码
原码,反码,补码相同,都是它所对应的二进制
原码是其所对应二进制且最高位为1
10000000 00000000 00000000 00000000
大(小)端字节序
3.1415926
1e10
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;}
与思考有所不同,不得不介绍浮点数在内存中的存储规则
///
根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成下面的形式:
科学计数法中,e可以为负数,也就有了e存入内存时其真实值必须加一个中间数,8位为127,11位为1023
例:2^10 E为10,存储时 10+127=137
10001001
正常情况,只需减去中间值127(1023)得到真实值,存储时m正常补齐即可
E等于1-127(或1023)即为真实值
表示一个无穷小的数
将M直接还原为0.xxxxxxx的小数
2的高次幂,是一个非常大的数,表示±无穷
无符号的char所对应图示可以用于E的二进制展示
探究底层时离不开调试,调试是一个优质程序员必须掌握的技巧。文中多处引入调试图例
调试常用
最常使用的几个快捷键:
long doubledoublefloatunsigned long intlong intunsigned intint
不同算数类型进行算数操作时,数据由低到高进行算数转换
注意:转换为char类型时要在二进制位低八位处进行截断,转回时要将高位补为符号位.
重点在于数据存储,浮点数的存储,算数转换.
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/125658.html
摘要:一引用操纵对象在的世界里,一切都被视为对象。特点创建程序时,需要知道存储在栈内所有数据的确切生命周期,以便上下移动堆栈指针。因为,指向同一块内存空间除了通过对象引用静态变量,我们还可以通过类直接引用静态变量 一、引用操纵对象 在Java的世界里,一切都被视为对象。操纵的标识符实际上是对象的引用, 例如:遥控器与电视的关系。 可以在没有对象关联的情况下,拥有一个引用。没有电视机,也可以拥...
摘要:调用函数时,它将用户释放的内存块连接到空闲链上。这个联合体共占用字节。是数字,且顺序递增位置固定,如访问是的元素,即,就直接访问数组的第个位置即可即,这样就不需要前面的索引数组。 baiyan 全部视频:https://segmentfault.com/a/11... 原视频地址:http://replay.xesv5.com/ll/24... 本笔记中部分图片截自视频中的片段,图片版...
摘要:博主接下来将会整理一些语言中常见的问题和坑,再看博主解释的时候可以自己思考一下变量的声明和定义有什么区别答变量的定义为变量分配地址和存储空间,变量的声明不分配地址。指针操作超过了变量的作用域范围如返回局部变量的地址。 博主接下来将会整理一些语言中常见的问题和坑,再看博主解释的时候可以自己...
阅读 3664·2023-01-11 11:02
阅读 4206·2023-01-11 11:02
阅读 3004·2023-01-11 11:02
阅读 5145·2023-01-11 11:02
阅读 4699·2023-01-11 11:02
阅读 5483·2023-01-11 11:02
阅读 5234·2023-01-11 11:02
阅读 3857·2023-01-11 11:02