标签:
说起指针,不知道有多少的C学者被这座大山所困住,很多人都说数组是最难学的,但是没想到指针比数组还难。没听多久就完全被绕晕了,什么一级指针啊,二级指针啊,三级指针啊,最后还莫名其妙的出来一个n级指针,就这样一节课下来就完全晕了。当然这里面还包括一些和指针搭配用的伙伴。数组、函数、结构体等等,我接下来说的可能只是指针的皮毛,你们也可以认为是概念,所以我希望你们看看就行,具体还要自己去想。
int a = 1; int *p = &a; printf("p = %p\n",p); printf("a = %p\n",&a);
由上面的代码,我们能得出运行结果是一样的,而且两个等式打印的都是地址。由此可以得出p = &a,这也就是地址的意思。当然我们可以通过他们俩的地址相等得出*p的值也和a的值相等,不信我们来看看代码的实现吧。
int a = 1; int *p = &a; printf("p = %d\n",*p); printf("a = %d\n",a);
这其实就可以充的说明了p是通过先找到a的地址,然后再找到了a的值。但是你们要千万记得,以下打印出来的结果是不相等的。
int a = 1; int *p = &a; printf("p = %p\n",p); printf("p = %p\n",&p);
看见等式没有,两个打印出来的地址是完全不相等的。这其实就牵扯出来了一个概念,就是本身p也有自己的地址,并且和其它数的地址是完全不相等的,当元素把地址赋值给指针之后,指针的地址并没有改变,它还是拥有自己的地址,改变的只是它指向的是那个地址,谁把地址赋值给它,它就指向谁。我们接下来在看看一个情况。
int a = 2; int *p = &a; p = &a; *p = a;
永远要记住定义时候*p是分开的,只是单独的把&a赋值给了p,并不是赋值给了*p,有些人一直认为*p是永远在一起的,总是不知道分开来怎么用,所以我告诉你们。*p在不用来定义的时候就是等于你所指向的那个元素的值,也就是内存空间。不要搞晕了啊。
其实我想说你既然已经知道一级指针的用法了,那么还会怕二级指针么?它不过是指向指针的指针罢了,其实没那么可怕啊,学习的时候放宽心就好。下面我们来看看吧。
int a = 2; int *p = &a; int **p1 = &p; printf("p1 = %p\n",p1); printf("p = %p\n",&p);
前面你不知明白了一级指针的用法了么,这里我们来看看。首先打印出来的结果肯定一样,为什么呢?看**p1 = &p这个等式其实就很明白了,*p1指向了p的地址,所以打印出来的结果一定相等,既然*p1指向了p的地址,而p又是a的地址,那么**p1是不是等于a的值呢,所以么,你看代码的时候只要把**p1上一个p当做一个桥梁就好,那你实在是不懂,那么我给你们画了一个类似元素在内存的分布图,先看看吧。
int a = 2; int *p = &a; int **p1 = &p; printf("p1 = %d\n",**p1); printf("a = %d\n",a);
看上面这张元素在内存当中地址的分布图不难看出,首先p1的地址(上面写的地址的位置,我里面只写了尾号,中间的就没写了)、p的地址和a的地址不难看出,要问我为什么会是这样分部的,我说个大概吧。也就是先定义的元素分配在内存的高字节,而后分配的一次往字节减小的地方分配,由于是整型嘛,所以就占4个字节。由图可以看出(*p1指向p的地址),(p的指向a的地址)那么自然而然(**p1就指向a的地址)了也就是通过这样的方法找到了a的值等于2.所以这就是二级指针,当然什么三级指针啊,四级指针啊,n级指针啊,原理都是一样的,你只要掌握了二级指针,其它的都不在话下。好了,那么接下来我再给大家普及一些小知识吧。
指针数组,指针和数组连接起来一起的用法。代表的是什么呢?指针数组其实就是一个数组,只不过它里面存的元素都是指针类型,换句话说就是用来存放一系列痛类型的指针的数组,可以具体看下代码。
int a1 = 1; int a2 = 2; int a3 = 3; int *p[3] = {&a1,&a2,&a3};
这就是指针数组的定义和赋值,下面我给大家说下怎么对指针数组取值,下面写的代码就是对指针数组取值。具体怎么取得我就不多说了。
int *a = p[0];
数组指针,顾名思义就是一个指针,而且这个指针的类型就是一个数组。怎么用呢,我们来看看代码吧。
int arr[3] = {1,2,3}; int (*p)[3] = &arr;
这里给告诉大家一个诀窍,就是数组指针里面*p = &arr,要记住不要问我为什么,其实他们不相等的,但是在C语言学习阶段只要记住这个那么数组指针基本就没问题了,除非你如果要搞科研项目,那么这是万万不能用的,因为它们实质是不相等的。
指针函数,函数,那说明它肯定是一个函数了,前面的指针只不过是表示返回值是一个指针罢了。那具体的格式是什么呢,我们来看看代码是怎么写的吧,可能写的有些短,希望不要介意啊。
*add(int *a){ 代码块; return &a; }
这就是一个最简短的指针函数,可以看出当调用函数之后,其返回值的类型是指针类型,很多时候它的用法是在main函数中直接将实参的地址传入进形参,把地址给a然后在具体操作。这就是指针函数,下面我们来看看最后一个指针类型吧。
最后一格就是函数指针了,看最后两个字就知道是一个指针。集体是这样的,函数也会在内存开辟一个空间,函数指针即是这块空间的地址。明白了么,就是在定义完函数后,没使用它之前内存是不会给它分配空间的,只有在使用的时候才会有自己的空间,而函数指针里的指针就是这块空间的地址。具体代码实现是这样的。
int add(int a){ 代码块; } int (*p)(int) = add;
然后在附上函数指针具体怎么传值吧,看下面代码。
p(3); add(3);
p(3)可以等效于add(3)。
函数我这里讲的差不多了,不管你们明不明白,希望我的这篇短问能帮助你,帮助你解答心中的疑问,后续我还会将有关指针的知识分享给大家,就当是我给你们的回报吧,要是有什么不明白的,可以留言给我,我会尽力解答。。。。。。
标签:
原文地址:http://www.cnblogs.com/yuluoluoluo/p/5018202.html