0 c pointers increment pointer-arithmetic dereference
有人可以解释为什么在输出中3 4 4打印而不是打印吗4 4 4?
#include <stdio.h>
int main(){
int a[] ={0,1,2,3,4};
int *p[] = {a,a+1,a+2,a+3,a+4};
int **ptr= p;
ptr++;
printf("%d %d %d\n",ptr-p,*ptr-a,**ptr);
*ptr++;
printf("%d %d %d\n",ptr-p,*ptr-a,**ptr);
*++ptr;
printf("%d %d %d\n",ptr-p,*ptr-a,**ptr);
++*ptr;
printf("%d %d %d\n",ptr-p,*ptr-a,**ptr);
return 0;
}
Run Code Online (Sandbox Code Playgroud)

对于初学者来说,请注意两个指针的类型不同ptrdiff_t。您不能%d对这种类型的对象使用转换说明符。你必须使用%td. 举例来说
printf("%td %td %d\n",ptr-p,*ptr-a,**ptr);
Run Code Online (Sandbox Code Playgroud)
表达式 *++ptr 与 ++*ptr 有何不同?
这个表情
*++ptr
Run Code Online (Sandbox Code Playgroud)
相当于
*( ++ptr )
Run Code Online (Sandbox Code Playgroud)
也就是说,首先指针递增并指向数组的下一个元素,然后取消引用,提供指向元素的左值。
这个表情
++*ptr
Run Code Online (Sandbox Code Playgroud)
这相当于
++( *ptr )
Run Code Online (Sandbox Code Playgroud)
也就是说,首先取消引用指针,为指向的元素提供左值,然后元素本身递增。
至于显示的代码
int a[] ={0,1,2,3,4};
int *p[] = {a,a+1,a+2,a+3,a+4};
int **ptr= p;
ptr++;
printf("%d %d %d\n",ptr-p,*ptr-a,**ptr);
*ptr++;
printf("%d %d %d\n",ptr-p,*ptr-a,**ptr);
*++ptr;
printf("%d %d %d\n",ptr-p,*ptr-a,**ptr);
++*ptr;
printf("%d %d %d\n",ptr-p,*ptr-a,**ptr);
Run Code Online (Sandbox Code Playgroud)
那么最初指针ptr指向数组的第一个元素p。
int **ptr= p;
Run Code Online (Sandbox Code Playgroud)
然后指针递增
ptr++;
Run Code Online (Sandbox Code Playgroud)
现在它指向数组的第二个元素p。
结果这个表达式
ptr-p
Run Code Online (Sandbox Code Playgroud)
产生两个指针之间的元素数量ptr,并且p(在此表达式中,数组指示符转换为指向其第一个元素的指针)等于1。
Asptr指向数组中值为 a + 1 的元素,p则表达式
*ptr-a
Run Code Online (Sandbox Code Playgroud)
也产生值1。和表达
**ptr
Run Code Online (Sandbox Code Playgroud)
产生表达式 的值a[1]。
这个表达式语句
*ptr++;
Run Code Online (Sandbox Code Playgroud)
事实上相当于
ptr++;
Run Code Online (Sandbox Code Playgroud)
因为指针的解除引用没有副作用。
现在指针指向数组的第三个元素p。还有这个声明
printf("%td %td %d\n",ptr-p,*ptr-a,**ptr);
Run Code Online (Sandbox Code Playgroud)
输出
2 2 2
Run Code Online (Sandbox Code Playgroud)
再次声明这一点
*++ptr;
Run Code Online (Sandbox Code Playgroud)
相当于声明
++ptr;
Run Code Online (Sandbox Code Playgroud)
因为取消引用没有副作用。现在指针指向数组的第四个元素p。
还有这个声明
printf("%td %td %d\n",ptr-p,*ptr-a,**ptr);
Run Code Online (Sandbox Code Playgroud)
输出
3 3 3
Run Code Online (Sandbox Code Playgroud)
在这份声明中
++*ptr;
Run Code Online (Sandbox Code Playgroud)
p指针指向的数组元素(第四个元素)递增ptr。即数组的第四个元素现在等于a+4
所以数组p现在看起来像
int *p[] = { a, a + 1, a + 2, a + 4, a + 4 };
Run Code Online (Sandbox Code Playgroud)
所以这个声明
printf("%td %td %d\n",ptr-p,*ptr-a,**ptr);
Run Code Online (Sandbox Code Playgroud)
输出
3 4 4
Run Code Online (Sandbox Code Playgroud)