c中常会见到指针,但是指针的理解还需要要从变量中说起,先看内存空间:
如图:内存是一个存放数据的空间,就像电影院一样,都有自己的编号,这种有序的编号成为内存编址。内存是按照字节一个一个的编址。每个字节都有编号,我们称之为内存地址。
如:
int i;
char b;
在使用变量的时候先申明两个变量,系统会自动的在内存中给你申明的两个变量分配空间:如下所示
以6开始,给i分配了2个字节,给a分配了一个字节。
i=30;
b= 'a';
存储完了之后如下所示:
这时候时候 &i, &b就可以看到当前的存储地址;
在计算机中,运算的部分主要是cpu, 但cpu不会直接和硬盘发生数据的交换,因为cup的处理速度远远的大于硬盘的速度。因此,他们两个之间出现了内存这个东西,内存起到一个缓冲的作用。当程序运行的时候,首先是把程序加载到内存,然后cup从内存中取出指令以及传输的数据。[但是内存是掉电之后里面的数据就会丢失,而磁盘里面的数据会一直存在的,因此,当你关机之后,内存就会被清空,下次开机的时候重将系统程序从磁盘加载到内存,然后再执行。这种每次断电之后开机都会重新从磁盘加载系统程序到内存的方法明显影响了开机的速度,因此现在人们想出了一种办法在断电之后仍能保证内存的数据不会丢失的办法,那就是断电之后仍然给内存供极少的电量来保证内存的数据不会丢失,着就是所谓的低功耗。当下次打开电脑的时候,系统加载会很快。]
所以说,内存是程序运行的过程中不可缺少的东西,现在看下编译器是怎么把整个内存进行分配的。我们写的C语言的源码必须的转化为机器能识别的二进制文件,计算机才能够运行。因此:
源码经过汇编-->编译成为二进制文件,然后编译器将所有的二进制文形成一个整体的二进制文件。
在上述的过程中编译器会在内存中分出以下的几个阶段:
代码段:代码段用来存储加载到内存的二进制代码。cpu从里面取指令。
数据段:数据段细分为三段:
1、已初始化读写数据段:主要存放声明并有初值的全局变量和加了static关键字的局部变量,它们的值都是可以改变的。
2、未初始化数据段BSS:主要存放的是未初始化的全局变量和加了static关键字的未初始化局部变量。
3、只读数据段:该数据段主要是存储程序中的常量数据(内容是不能改变的),一般所称的常量区就是指该数据段
变量或者常量在上诉几个内存段中分配好之后,在整个程序运行过程中都有效,生命周期从建立到整个程序运行结束才释放,我们称之为静态存储区。
三、初始化完成之后程序应该要执行了,在执行的过程中会在分出两个段:
堆:主要是提供给程序猿用malloc()函数动态分配需要的内存大小的。
栈:主要是分配函数里面的未加static关键字的局部变量和函数的行参的
这两个段是在程序运行的过程中动态分配的,当调用函数的时候为其行参和未加static的局部变量分配内存,当函数调用结束内存释放,我们称为动态存储区。
注明:全局变量加关键字static只是影响该变量的作用域,加上了就只能在该文本文件里面用,而不能在其他文件里面使用该变量。不会影响其存储位置,有无关键字都是存储在静态存储区里面的。但是局部变量若加了static则会将该变量存储在静态存储区里面,不加应该是在动态存储区栈里面的,只是影响了存储位置,不会影响其作用域。
补充:全局变量是在编译的过程中就在静态存储区里面分配内存的,而局部变量则是在程序运行过程中动态分配内存的。
盗一张图看下:
可以对应当前的图进行对号查看。