引言

快到五一了,压力没有那么大了,blog可以小更新一波了。
诶,我就是不学习,就是玩
那么据我简单的调查呢,身边同学对指针还是不太熟悉,我们这次就对指针做一点点小的解读。

什么是指针

指针吧,个人认为,是C语言的灵魂
指针,顾名思义,是指向某块地址的一个值。
指针在我们的程序中,体现为一个指针型变量,其存储的值,是起所指向的内存空间的首地址。
也就是说

指针的实质是一个变量,只不过其存储的值是一个地址。


做个小小的比喻:

一个变量是一个保险柜,每个保险柜都有自己的编号。
当我们声明了一个变量的时候,我们会选择一个可用的保险柜,在里面放上这个值
当我们声明了一个指针类型变量的时候,我们也会选择一个可用的保险柜。但是在这个保险柜里面放上的,是某个保险柜的编号
这样一说,是不是就清楚多了?显然没有。

指针的用法

知道了上述基本的概念,我们来了解一下指针的简单使用

指针的定义

指针定义的标准格式是:

type *varName;

例如
int *p;

请注意:
定义后指针所指向的地址是未知的,很可能不存在或指向某些重要的地址
指针一定要给定值才能进行操作!

建议:
定义的时候顺手初始化。若暂时未确定指向哪个变量,应置为

int a;
int *p = &a;    // 指向变量a所在地址
int *t = NULL;  // NULL的值是0x00,即空指针

指针的运算

众所周知指针是一种变量,因此变量支持的运算它大多都支持
我们常用的有:

运算符含义示例
++自增运算符,指向相邻的下一个地址空间p++;
--自减运算符,指向相邻的上一个地址空间p--;
+=加且赋值运算符,指向相邻的下n个地址空间p+=n;
-=减且赋值运算符,指向相邻的上n个地址空间p-=n;

有了以上几个运算符,我们就能灵活的调整指针指向的地址。
例如

int a[5];
int *p = a;

需要注意的是,p+1并不是单纯的取后一位地址,而是取与数据类型对应的地址空间
例如

int a;
printf("%x\n%x", &a, &a + 1);

其输出为:
61fe1c
61fe20

可以看出上下两个地址的差值是sizeof(int),即4

指针的使用

假如我们想要将一个指针所指向的地址的值取出来,也就是按编号找保险箱中的内容,我们需要在指针前加上*
例如

int a = 5;
int *p = &a;
int b = *p;
printf("b = %d", b);

输出为b = 5
此时呢,*pa完全完全等效的,也就是说
a = 6;
*p = 6;

两句话是完全等效的。

指针与数组的孪生关系

指针跟数组,是一对孪生兄弟。
他们虽然写法上有一些不同,但是却有那么多那么多那么多相似之处。
甚至,指针和数组在某些情况下是可以混用的

现在大多数教材都把数组和指针分开来讲。这可以理解,毕竟数组跟指针在理解难度上不在一个层面。
但是,由于数组和指针的孪生关系是如此密切,又让人会自然的认为指针跟数组理应一起讲述。甚至,指针其实应该先于数组讲述。

打个比方,指针是存着保险箱编号的保险箱,数组则是一系列连续编号的保险箱。
而数组名,就是这一系列保险箱的第一个保险箱的编号,其本质也是一个指针。

数组提供了一种线性连续分配、管理地址空间的方法,但是指针同样可以做到类似的功能。
例如:

int num[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int *pointer = num;       // 这句不难看出 num 等效于 &num[0]
// 这句定义后,pointer跟num就是等效的了

利用指针进行传值

指针的妙处远不止上面所提到的,其中一个妙处就是利用指针我们可以很方便的在函数间进行值传递
由于篇幅有限,这部分内容放在下一次更新。
届时将结合常考题型进行解释。