用复杂指针算法输出C程序

时间:2015-05-17 21:37:05

标签: 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;
}

输出

TEST sQuiz Z CQ

任何人都可以帮我理解为什么输出这个?

2 个答案:

答案 0 :(得分:6)

绘制指针图片很有帮助,但在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然后打印:{{1 }}

TEST

增量printf("%s ", *--*++cpp+3); (现在指向cpp),取消引用并减少(将cp[2]更改为现在指向cp[2]),然后再取消引用(获取{{1} }})。最后添加3(c[0])并打印:s0

s0+3

sQuizprintf("%s ", *cpp[-2]+3); == cp[2])获取2个广告位的值,然后取消引用它以获得cp[0]。然后添加3,并打印:c+3

s3

Zprintf("%s ", cpp[-1][-1]+1); == cp[2])获取1个广告位的值,然后从该广告位获取一个广告位的值(cp[1] = = c+2),然后添加1并打印:c[1]

要记住的重要事项是:

  • 每个s1CQ都是一个取消引用,引用指针指向的值
  • 递增/递减运算符对最后一个解除引用的东西进行操作(如果还没有解除引用,则直接对变量进行操作。
  • 一元运算符的优先级高于二进制,因此(禁止括号),所有一元postfix运算符首先发生,然后是一元前缀,然后才是二进制。
  • *实际上是一个一元的后缀运算符,而不是一个中缀二元运算符(即使它有两个操作数),因为第二个操作数在括号内。

答案 1 :(得分:4)

创建以下临时变量以理解某些表达式会很有帮助。

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],与:

相同

s2,评估为"TEST"

在该声明的最后,cppcp+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"

在该声明的最后,cppcp+2相同。

第三printf

printf("%s ", *cpp[-2]+3);

*cpp[-2]+3

相同

*(cpp[-2])+3,与

相同

*(cp)+3因为++上的cpp次操作,与

相同

c[3]+3,与

相同

s3+3,评估为"Z"

第四个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"