Mah*_*aha 1 c pointers pointer-arithmetic
我正准备进行有关猜测C代码输出的编程测验.
经过长时间的尝试,我仍然在努力理解以下代码的输出:
#include <stdio.h>
char *c[] = {"GeksQuiz", "MCQ", "TEST", "QUIZ"};
char **cp[] = {c+3, c+2, c+1, c};
char ***cpp = cp;
int main()
{
printf("%s ", **++cpp);
printf("%s ", *--*++cpp+3);
printf("%s ", *cpp[-2]+3);
printf("%s ", cpp[-1][-1]+1);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
产量
TEST sQuiz Z CQ
Run Code Online (Sandbox Code Playgroud)
任何人都可以帮我理解为什么这个输出?
它有助于绘制指针的图片,但这在StackOverflow上很难做到:
cpp: cp
cp: c+3, c+2, c+1, c
c: s0, s1, s2, s3
s0: 'G', 'e', 'K', 's', 'Q', 'u', 'i', 'z', '\0'
s1: 'M', 'C', 'Q', '\0'
s2: 'T', 'E', 'S', 'T', '\0'
s3: 'Q', 'U', 'I', 'Z', '\0'
Run Code Online (Sandbox Code Playgroud)
这是一个显示每个数组的表,以及静态字符串(我给它们命名以使它们更容易讨论).
现在让我们看一下这些语句的作用:
printf("%s ", **++cpp);
Run Code Online (Sandbox Code Playgroud)
增量cpp(改为指向cp[1]),然后deref两次 - 第一次获取c+2,第二次s2打印:TEST
printf("%s ", *--*++cpp+3);
Run Code Online (Sandbox Code Playgroud)
递增cpp(现在指向cp[2]),取消引用和递减(cp[2]改为现在指向c[0]),并再次取消引用(获得s0).最后添加3(s0+3)并打印:sQuiz
printf("%s ", *cpp[-2]+3);
Run Code Online (Sandbox Code Playgroud)
从cp[2](从cp[0]= = c+3)获取2个槽的值,然后取消引用它以获取s3.然后添加3,并打印:Z
printf("%s ", cpp[-1][-1]+1);
Run Code Online (Sandbox Code Playgroud)
从cp[2](从cp[1]= = c+2)获取值1槽,然后从该值返回一个槽(即c[1]== s1),然后加1并打印:CQ
要记住的重要事项是:
*或者[]是一个引用指针指向的值的dereference[] 实际上是一个一元的后缀运算符,而不是一个中缀二元运算符(即使它有两个操作数),因为第二个操作数在括号内.创建以下临时变量以理解某些表达式将很有帮助。
char s1[] = "GeksQuiz";
char s2[] = "MCQ";
char s3[] = "TEST";
char s4[] = "QUIZ";
char *c[] = {s1, s2, s3, s4};
char **cp[] = {c+3, c+2, c+1, c};
char ***cpp = cp;
Run Code Online (Sandbox Code Playgroud)
第一 printf
printf("%s ", **++cpp);
Run Code Online (Sandbox Code Playgroud)
**++cpp具有的副作用cpp = cpp+1,并且评估为
**(cpp+1),与
*(cp[1]),与
*(c+2),与以下内容相同:
c[2],与以下内容相同:
s2,其值为"TEST"。
该语句末尾cpp与相同cp+1。
第二 printf
printf("%s ", *--*++cpp+3);
Run Code Online (Sandbox Code Playgroud)
*--*++cpp+3 是相同的
*(--(*(++cpp))) + 3,具有的副作用cpp = cpp+1,并且评估为:
*(--(*(cpp+1))) + 3,与
*(--(*(cp+2))) + 3,与
*(--(cp[2])) + 3
*(--(cp[2])) + 3具有的副作用cp[2] = cp[2]-1 = c+1-1 = c,其计算结果为:
*(cp[2]-1) + 3,与
*(c+1-1) + 3,与
*(c) + 3,与
c[0] + 3,与
s1 + 3,其计算结果为 "sQuiz"
该语句末尾cpp与相同cp+2。
第三 printf
printf("%s ", *cpp[-2]+3);
Run Code Online (Sandbox Code Playgroud)
*cpp[-2]+3 是相同的
*(cpp[-2])+3,与
*(cp)+3由于之前++对cpp。进行的操作与
c[3]+3,与
s3+3,其值为"Z"。
第四 printf
printf("%s ", cpp[-1][-1]+1);
Run Code Online (Sandbox Code Playgroud)
cpp[-1][-1]+1 是相同的
*(cpp-1)[-1]+1,与
*(*(cpp-1) -1) + 1,与
*(*(cp+1) -1) + 1,与
*(cp[1] -1) + 1,与
*(c+2-1) + 1,与
*(c+1) + 1,与
c[1] + 1,与
s2 + 1,其值为"CQ"。