指针可以说是C语言的一大难点,很多人都比较讨厌指针。我个人学习C语言也有一段时间了,今天就指针做一点总结。
简单变量
在C语言中定义一个简单变量,例如int a = 4,这个时候,就会在内存空间中开辟一个4个字节大小的空间,并且给这个变量赋值为4。这里的int可以换成float、double、long都可以,只不过类型不同,会占用不同大小的内存空间。
指针(pointer)
指针也是变量,大家一定要注意这一点,很多教科书上关于指针的说法都是不准确的。那么既然指针也是变量,那么指针与一般的变量有什么区别呢?
其实很简单,指针变量里存放的是地址。指针变量用来存放地址这句话其实可以换一种说法,换成指针变量指向某一个地址,这是一种比较形象的说法,这个更符合指针这一词的含义。
既然指针也是变量,那么它同样也占据一定大小的内存空间。指针占据的大小与平台有关。对于32位的平台而言,指针变量一般占用4个字节。对于64位的平台而言,指针变量一般占用8个字节。
指针的定义与初始化
定义一个指针:int *p;
int表明表明这个指针变量所指向的地址里存放的是int型数据,也可以是char 、double、struct等。
*用来区别于简单变量,表明这是一个指针变量。
p表示这个指针变量名为p。
指针初始化,一般习惯于将指针初始化为空: p = NULL;
指针的赋值
指针的赋值分为两种情况:
直接复制:
int a = 4;
int *p = &a;
(这里补充一下字符串常量可以直接给char型指针赋值: char *t = "dasdadasd")
这样指针P就指向了变量a的地址,这里面&为取地址符,顾名思义就是获得变量地址的。
指针之间的相符赋值:
int *t = p;
通过这种赋值指针变量p就指向了变量a的地址,与指针p的指向是相同的。
二级指针
也就是我们常说的指针的指针。二级指针也不难理解。同样它也是一个指针,它与普通指针的区别在于,它所指向的地址中所存放的是指针而已,不再是其他类型的变量了。
定义一个二级指针:char **p ;
通过指针来访问它指向地址里存放的数据
这个就不多说了,很简单通过*号就可以实现了,这里就不多说了。
指针与数组的关系
我们可以设想以下:如何我们让一个指针指向一个数组的首地址,那么这样是不是就能够操作这整个数组了呢?
这样假设是可以理解的,因为我们都知道数组在内存中是连续的,只要知道了首地址的位置就可以确定每一个元素的位置了。
实际上,指针与数组名在写法上是完全等价的,但是这两者在概念上还是有所区别。
例如:定义了一个数组 int a[100]; 这个时候数组名a可以给一个int型指针赋值,但是反过来就不行,因为这个数组是经过完整定义过的,它在内存空间里开辟100的连续的存储单元,数组的首地址a已经确定了,是不能再修改的。
但是还有一种情况,通过数组名进行传参,例如int a [ ]这种形式,这种写法严格来说没有定义数组,它只是进行一个声明,数组名a是可以接受指针赋值的。
由以上概念所引出来的概念:
数组指针:就是指数组名。
指针数组:是一个数组,只不过每一个数组元素中存放的是一个指针,数组名是一个二级指针。
指针的用处
可能会有人会问指针到底有什么用?
指针可以直接操作内存,使得内存管理更加灵活。
指针可以解决传递参数的问题。
注:以上所提及到的内存空间均是指逻辑上的地址空间,计算机用户一般不直接接触真实的物理内存。