还是关于二级指针的问题
int a[]={10,11,12};
int*p=&a[0];
int**q=&p;
现在我们都知道一级指针p存储了a[0]的地址,即p=&a[0],这样就很容易知道p+1=&a[1]
现在我们也当然知道二级指针q存储了p的地址,即q=&p,这样很容易知道*q=&a[0],
那么也可以知道*q+1=&a[1]。
**********************************************************************************************************
现在又有一个例子:假如有
int**q=calloc(10,sizeof(int*));
这条语句说明了一个二级指针q,它存储了一级指针 的地址,这个一级指针的地址就是这个内存空间的地址,这个内存空间中存储的是int*类型的值,即一级指针的值,即int类型元素的地址
现在第一个int类型元素的地址为*q,那么第二个int类型元素的地址为多少?为什么是*(q+1)而不是上面的*q+1??为什么?强烈不解 展开
如果你纠结几级指针,你就输了。整个3级、4级指针,指定蒙圈完蛋。分析多星指针主要两个小技巧:1、关注指针的含义、作用;2、将type* 看作一个新的类型。
=================================================
分析一下你的例子:
int**q=calloc(10,sizeof(int*));
从意义角度来讲,这是一个申请指针数据的语句。于是,在sizeof里面填写的是int*,表明这个指针数组是一个int型的指针数组。那么在q中存储的便是指针数组的首地址。申请成功后,访问这个数组有两种方式,即提到的*(q+1)以及q[1]。
为什么不是*q+1呢?我们假设q的值是addr_0,那么从第一个元素开始的各元素地址是addr_0、addr_1、...、addr_9。而各元素的内容分别为content_0、content_1、...、content_9。其中addr_×是连续地址,content_×是用户填的不连续内容。
*q表示,将q中存储的数据addr_0,作为地址,返回内容。明显地址addr_0的值是content_1嘛,于是*q的结果是content_0。接着*q+1,那么此时的执行结果是content_0+1。这是什么意思呢?就是将指针数组的第2个元素的值,看作另外一个数组的首地址,取这个数组的第2个元素。
同理*(q+1),q的值是addr_0,那么,q+1为,addr_0+1,又知道addr_0与addr_1地址连续,那么addr_0+1便是addr_1。此时对addr_1取内容的话,便是content_1。
=================================================
Tips:
从上面的分析中,你也可以看出,始终没有讨论过几级指针的事情,而是讨论指针的含义。指针分级讨论的坏处是僵化,造成不理解。而理解代码,最重要的是理解代码的含义,而不是代码的形式。C语言指针相当灵活,也就是说,使用限制几乎没有。在不严格的程序员那里,他可能会用的很爽,但是代码的阅读性会非常低。要理解某段代码中的指针用法,始终不能脱离这个指针的功能背景。
另外呢,写代码的时候可以有些小习惯,实践将指针看作一个新类型,而不是从属于某个主类型的指针。比如:
int* *q = calloc( 10, sizeof( int* ) );
代码中加了点空格。我们将int*看作是一个类型。那么*q表征数组。这与非指针的申请多类似啊。
double *q = calloc( 10, sizeof( double ) );
此时,double的数组怎么用,int*的数组就该怎么用。