![](/img/trans.png)
[英]Don't fully understand the output of very small C program using void*/char* to refer to and int + pointer arithmetic
[英]Output of C program with complex 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;
}
输出
TEST sQuiz Z CQ
谁能帮我理解为什么这个输出?
创建以下临时变量有助于理解一些表达式。
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;
第一个printf
printf("%s ", **++cpp);
**++cpp
具有cpp = cpp+1
的副作用,计算结果为
**(cpp+1)
,与
*(cp[1])
,与
*(c+2)
,等同于:
c[2]
,等同于:
s3
,其评估为"TEST"
。(最初是 s2 更正)
在该语句的末尾, cpp
与cp+1
相同。
第二个printf
printf("%s ", *--*++cpp+3);
*--*++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);
*cpp[-2]+3
与
*(cpp[-2])+3
,与
*(cp)+3
因为前面对cpp
. 的++
操作,与
c[3]+3
,与
s4+3
,其计算结果为"Z"
。(最初更正为 s3+3)
第四个printf
printf("%s ", cpp[-1][-1]+1);
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"
。
它有助于绘制指针的图片,但在 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'
这是一个表格,显示了每个数组,以及静态字符串(为了便于讨论,我已经给出了名称)。
现在让我们看看这些语句的作用:
printf("%s ", **++cpp);
增加cpp
(改为指向cp[1]
),然后 deref 两次——第一个得到c+2
,第二个s2
然后打印: TEST
printf("%s ", *--*++cpp+3);
增加cpp
(现在指向cp[2]
),取消引用并减少它(将cp[2]
更改为现在指向c[0]
),然后再次取消引用(获得s0
)。 最后添加 3 ( s0+3
) 并打印: sQuiz
printf("%s ", *cpp[-2]+3);
从cp[2]
(即cp[0]
== c+3
)取回 2 个槽的值,然后取消引用它以获得s3
。 然后加3,并打印: Z
printf("%s ", cpp[-1][-1]+1);
从cp[2]
取回 1 个槽的值(即cp[1]
== c+2
),然后从中取回一个槽的值(即c[1]
== s1
),然后加 1 和打印: CQ
要记住的重要事项是:
*
或[]
是一个解引用,它引用指针指向的值[]
实际上是一元后缀运算符,而不是中缀二元运算符(即使它有两个操作数),因为第二个操作数在括号内。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.