前言:指针!菜鸟的终点,高手的起点。漫谈一些进阶之路上的趣事;记录一些语言本身的特性以及思想,没有STL,也没有API!
0x01: 程序内存中的存储划分对于程序在内存中是如何分布的,网上有多个解释的版本(解释为3、4、5、6个区的都有),这里我也不赘述了,反正该有的都有,只是看个人怎么理解
建议自己搜来看看温习一下(主要是栈区、常量区、代码段),看懵了就不要说我描述有问题了......
0x22: 变量与常量程序的运行过程(屏蔽一些较为底层的东西):
① 将物理内存(磁盘等存储介质)中的程序文件装入运行内存中,程序中的内存指的是运行内存
② CPU从内存中的指定位置读取到指令加以运行,这里的指令最终都是对于内存的操作
程序中定义的操作存储于内存 - 代码段,操作指C代码指令编译的结果,例如赋值操作、比较运算等;CPU读取指令的位置
程序中定义的局部变量存储于内存 - 栈区,这是我们最常使用的存储区域;这些变量在同一作用范围内时我们可以随意改变其值
程序中定义的常量存储于内存 - 数据区,数据区中全局变量、静态变量、常量的存储区不同,我们通常使用 'const' 定义的常量是存储在常量区的,常量区的数据根据规定是不可改变的
思考:程序加载到内存中的绝对位置是由操作系统决定的,程序可以加载到的内存(除系统保留区)也是平等的,为什么存储在栈区的变量可以改变而存储在代码区和常量区的数据不可改变;理论上来说该程序可以操作的内存(也就是系统加载该程序时分配的内存地址范围)都是可以被改变的,所以这里可以推测为程序做了权限的限制
0x32: 指针操作的本质指针操作是可以直接作用于内存的,使用指针操作时只有两个限制,一个是定义指针时规定的对于变量本身的限制,一个是该程序的寻址空间限制;在某些情况下这两个限制都可以突破,这里不作论述
指针的强大之处在于它能修改所有能寻址到的内存中的值;对应程序在内存中的分配,理论上可以使用指针操作栈区堆区(常用),那么同样可以操作数据区和代码区;语言限制中不允许修改操作的区域为代码区和数据区中的常量区,这里我们可以将指针指向这两个区域,这样就能达到修改代码和常量的目的
0x42: 通过指针操作常量区代码示例:
const int a=10; int *pa=(int*)&a; *pa=99; printf("*pa=%d,a=%d",*pa,a); /*输出: *pa=99,a=10 */