文章目录
前言
🎉欢迎关注🔎点赞👍收藏⭐️留言📝
🎉推荐up主专题文章【C语言编程一百题】
📌QQ:3052645092 有问题可以一起讨论哦
🔎超级好用的刷题网站【牛客网】
🍭作者水平很有限,如果发现错误,请及时告知作者哦!感谢感谢!
💗什么是指针
💗左值与右值
🍃 先明确什么叫做左值和右值做一下铺垫
🍃 我们反汇编一下,深刻认识一下!!!
#include<stdio.h>
int main(){
int a = 10;
int b = a;//使用的是a的内容 a==10
return 0;
}
🍃 知道了什么是左值和右值,再来看一下什么是指针
1.什么是指针?
指针就是地址!那么地址本质是什么呢?地址是数据,那么数据可不可以被保存在变量空间里面呢?当然可以
2.有没有指针变量这个概念呢?
当然有了,保存指针(地址)相关数据的变量就是指针变量
3. 指针 和 指针变量又有何不同?我们口语中的"定义一个指针"究竟是什么意思?我们该如何理解这种说法
严格意义上,指针和指针变量是不同的,指针就是地址值,而指针变量是C中的变量,要在特定区域开辟空间,要用来保存地址数据,还可以被取地址。(先分开)
但是,我们经常在口语化表达的时候,又经常将这两个概念混合,具体原因无从考证,可能是与最早的C资料的翻译有关。然后,书与书之间互相借鉴,形成了这样的说法。同时,简化说法,也更符合人的表达习惯,估计老外也是这么想的。(在关联)
那么我们以后怎么认为呢?我们分开理解,但是依旧关联使用。自己使用的时候,混合使用可以。
🍃 看一下指针变量的左右值
🍃 所以得出结论:指针变量也是区分左值右值的
经过上面的叙述我们也把指针和指针变量分开了,解释:其实指针就是地址,地址就是数据呀,是数据就可以被存放呀,那么指针变量就来了,指针变量就是存放地址(指针)数据的,好,我们现在已经把这两个概念分开了,接下来我们就合并它
🍃 看这组代码:
#include<stdio.h>
int main(){
int a = 10;
int *p = &a;
p = (int*)0x1234;
int *R = p;
return 0;
}
🍃 解释:
🍃 这幅图一定要好好理解很重要!!!!!!!!
💗为什么有指针
🍃 我们以生活中的例子宿舍楼为例
像这样的宿舍楼,那么多层,如果要找一个房间如果没有门牌号是不是会很不方便,所以建筑师很聪明,为每个房间都搞了个门牌号,我们的内存也是,一个地址代表一个空间,这样我们在找数据的时候直接按照地址就可以找到。效率很高不用再遍历整个内存再找数据。
🍃 这时有人就想问了,你刚才说地址也是数据,那这个数据是多大的呢,占几个字节空间呢?
答案是:在32位平台指针占4字节,在64位平台占8字节。
那又有人想问了,我们还要保存这些地址数据吗,一个字节空间有一个地址,一个地址就4个字节,光保存地址,内存也放不下呀
其实是不用的,cpu用硬件电路对内存按照字节编址
🍃 简单理解一下编址:
大家能理解到地址是通过硬件编址得到的就行了
💗指针的内存布局
🍃 一个整形,有4个字节,那么应该有4个地址!那么&a取了哪一个地址?那么如何全部访问这4个字节呢
🍃 如何访问4个字节,这要看你定义的类型了,如果是int就是4个字节,如果要是short就是2个字节
💗解引用
🌼总结一个口诀:在类型相同的情况下,对指针进行解引用,表示指针所指向的目标【一定要熟记于心】
🌼解释:
🌼*p完整理解是,取出p中的地址,访问该地址指向的内存单元(空间或者内容)(其实通过指针变量访问,本质是一种间接寻址的方式)
💗如何将数值存储到指定的内存地址(栈随机化)
知道了指针的本质就是地址,地址就是数据,那么我们可以直接通过地址数据对变量进行访问吗???
我们来试一下!!!
答案是不行的,我们也也没看见过这样直接访问的吧,我们都是间接访问!!!
🌼但是为啥不能呢?
目前主流的编译器和操作系统,为了安全,已经有了很多内存保护的机制。我们目前的win和Linux都有栈随机化这样的机制来方式黑客对用户数据地址进行预测。当然,还有其他的栈保护机制,比如“金丝雀”技术之类的
🌼接下来我测试一下这个“栈随机”
第一次
第二次
我们看每次变量的地址都是不一样的吧,意思就是你存进去的内容不变,但是地址是动态变化的,这样就避免了,黑客推算出某些地址存在重要内容,而盗之。
这下能明白为啥不能直接访问了吧,你在变量存的内容的地址是动态变化的,每次运行时,地址就变,没准就变化到0x1234这个地址,这不就访问冲突了吗,所以编译器会提示错误。
💗全局变量呢,有保护机制吗?
🍁第一次
🍁第二次
一样哦
🍁换一下位置就变了
对全局变量也有相关的保护!!!!
💗一道有趣的指针题目:
#include<stdio.h>
int main()
{
int *p = NULL;
p = (int*)&p;
*p = 10;
p = 20;
return 0;
}
🌼自己先看一下该如何理解
解释:
🚀 恭喜看到最后,老夫看你骨骼精奇,送你三句话:
对指针进行解引用,代表指针所指向的目标!!!
对指针进行解引用,代表指针所指向的目标!!!
对指针进行解引用,代表指针所指向的目标!!!