讲讲指针

���Ľ�������л�����Ķ�

指针是什么?

百度百科说:在计算机科学中,指针(Pointer)是编程语言中的一个对象,利用地址,它的值直接指向(points to)存在电脑存储器中另一个地方的值。
由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。因此,将地址形象化的称为“指针”。意思是通过它能找到以它为地址的内存单元。

指针其实就是存有地址的变量,就和其他变量一样,他也有着自己的类型,唯一的区别就是,他在定义时需要加一个*号,就比如这样,int *p, 在32位的编译器下,指针都是4个字节。
指针身为变量,当然也可以进行正常的加减,但是它与普通变量的运算不同的是,指针的加减所加所减的是指针所指向的类型。

1
2
3
// 关于指针类型的加减:
// pa + n = pa + sizeof(指针所指向的类型)*n
//指针所指向的类型可以是int  char float这样的也可以是结构体类型的。

指针怎么用?

指针定义

1
2
int a;    
int *pa = &a;

这里可以看到,先定义了一个整型变量a,然后又定义了一个整型的指针pa。在pa的前面有个 * ,这个* 就是特指这个变量是一个新类型的变量是个指针变量。
这个指针变量pa将指向的内容不是一个整型数字,而是一个地址。在这个地址上存的一个“东西”。而这个“东西”是一个整型数(a)。

从目前来看,我们的数据类型中增加了一个新的成员。从最开始学习的int ,然后加入了float,后来又来了double,char,还有long int,long long int。
我们都能够接受他们是数据类型。现在我们就要接受一种新的数据类型int * 。对这种数据类型的规范形式比较不一样。就是在原来的int,float,char的基础上在后面加了一个*

这个就比较难受了。因为以前都在在前面加long的。这次是在后面加*。但是我们还是要接受啊。慢慢看习惯就ok。
所以我们现在看代码的时候,在定义的时候,在int等基础数据类型后面带*的时候,就知道后面的这个变量其实是一个指向了某个地址的变量。

我们在定义指针的时候,通常会这么写

1
int  *pointer =NULL;

这里的重点在=前面,就是这个*是直接贴着变量名的。这样做的效果和int* pointerint * pointer没有区别。

采用int *pointer的写法是为了看清pointer其实是一个指针变量。这样方便理解。

另外其他的定义方式如下:

1
2
int  a;
int *pa=&a;

这里解释说明一下:我们在脑子里过一下。一个指针变量,其实是一个变量,他里面的内容是一个地址。这个地址不是别的,正是物理内存上的物理地址。
而我们并步知道这个地址是个什么玩意。所以我们不能想当然觉得地址是个整数或者是字母什么的。

那么我们这个变量在声明初始化的时候,肯定要指向一个地址的。
那么这个指针变量指向的那个地址类型要和这个指针变量类型一样。不然就驴唇不对马嘴了。故而,一个整型的指针变量,就只能指向一个整型的变量地址。

那么问题来了,该怎么获得那个整数的地址呢?以前学过int a;就声明并且初始化了一个整型变量。
我们知道int是整型数据类型。那么我们就可以事先给他安排一个初始化的数。我们就给他安排为0。
而我们这样声明的时候:int b=9;这个时候,我们系统底部(编译器)的操作是先初始化为0,然后把0替换为9。
好了,现在我们的目标就是获得这个9的地址。然后把这个地址赋值给pa。

明确了这个问题,c语言的设计者也是很头疼啊。
该怎么办呢?智慧的人就是智慧的人。
引入指针必然会涉及到地址,涉及到地址必然会涉及到获取地址的操作。
所以设计者就涉及了一个操作来获取地址。这个操作使用一个符号来运算,就是&符号。以前我们学过+-*/
今天再学一个新的运算符,那就是&&就是取地址符。

这个符号的使用很简单,你要取哪个变量的地址直接在前面加上&就可以了。比如为想取刚刚声明的变量int b=9;中的b的地址,那么就写&b
这样就取到了b的地址。同样的道理&a;就取到了a的地址了。

现在问题解决了。我们有了a的地址,也有了指针变量。所以我们就可以使用int *pa=&a;来初始化这个变量pa了。

好了,我们再来讲讲这个pa。一定要看请逻辑关系和类比关系。

以前我们学了int a=0;,现在我们学了int *pa=&a;。这里,看清楚,我们的变量名是a ,是pa。所以你应该想到变量名的命名规则了吧。
所以我们的指针变量啊,他是pa。不是*pa。这个*是和int是一伙的。我们把*pa写在一起是为了我们理解pa的意思。
pa是个指针变量。仅此而已。故而,在非声明变量的代码里看到pa,要知道这个时候pa是指向地址的,不是指向整型数字的。

指针运算

指针是什么?

指针是地址,指针变量指向的是一个地址。这里的指向,其实就是=的意思,就是存储的意思,就是代表的意思。

指针的运算,翻译过来就是地址的运算。那么能有哪些运算呢?

+ -运算

地址是物理内存的地址,进入到计算机中就被转化成一串数字(这个数字没有什么意义,就表示当时内存的位置)。
计算机是二进制的,那么就会形成1和0。而在某些时候计算机使用八进制和十六进制还是有好处的,所以地址也会被表示成八进制或者十六进制。
本质上还是一个数字(或许很长的数字)。

讲完了这些,我们来说说,地址的加减运算是个什么玩意。

就像在桌子上把扑克整整齐齐的摆开,一张接一张的。我们有个打火机就站在第一章牌上。
这个打火机就是我们的指针。每一张扑克就代表一个地址。现在我们要使指针加1,那么就将打火机向前移动一张扑克,
站在了第二张扑克上。所以我们很明白这个指针+1和-1是什么意思了。就是移动了其本身这个类型的长度。

在这个例子中,打火机这个指针是指向扑克这中类型的。所以每次打火机只能移动扑克大小的N 倍。
这里打火机相当于int *,扑克相当于int。每次int *移动的大小只能是int的N倍。不能只移动半个int。

0%