首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用复指针算法输出C程序

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

Stack Overflow用户
提问于 2015-05-17 21:37:04
回答 2查看 3.2K关注 0票数 6

我正在准备关于程序设计的小测验,包括猜测C代码输出。

经过很长一段时间的尝试之后,我仍然很难理解以下代码的输出:

代码语言:javascript
复制
#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;
}

输出

代码语言:javascript
复制
TEST sQuiz Z CQ

有谁能帮我弄清楚为什么是这个输出?

EN

回答 2

Stack Overflow用户

发布于 2015-05-17 22:59:46

创建以下临时变量将有助于理解其中的一些表达式。

代码语言:javascript
复制
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 First

代码语言:javascript
复制
printf("%s ", **++cpp);

**++cppcpp = cpp+1的副作用,并评估为

**(cpp+1),它与

*(cp[1]),它与

*(c+2),它与以下相同:

c[2],它与以下相同:

s3,它的计算结果为"TEST"。(最初它被s2修正了)

在该语句的末尾,cppcp+1相同。

printf 第二

代码语言:javascript
复制
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 第三

代码语言:javascript
复制
printf("%s ", *cpp[-2]+3);

*cpp[-2]+3

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

*(cp)+3,因为以前在cpp.上执行++操作,这与

c[3]+3,它与

s4+3,它的计算结果为"Z"。(最初更正为s3+3)

printf 第四

代码语言:javascript
复制
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"

票数 10
EN

Stack Overflow用户

发布于 2015-05-17 22:02:35

它有助于绘制指针的图片,但在StackOverflow上很难这样做:

代码语言:javascript
复制
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'

这是一个表,显示了每个数组,以及静态字符串(我已经给出了名称,以使它们更易于讨论)。

现在让我们看看这些语句是做什么的:

代码语言:javascript
复制
printf("%s ", **++cpp);

增量cpp (更改为指向cp[1]),然后是deref两次--第一个得到c+2,第二个s2被打印出来:TEST

代码语言:javascript
复制
printf("%s ", *--*++cpp+3);

增量cpp (现在指向cp[2]),取消引用和减少(将cp[2]改为现在指向c[0]),再次取消引用(获取s0)。最后添加3 (s0+3)并打印:sQuiz

代码语言:javascript
复制
printf("%s ", *cpp[-2]+3);

cp[2] (即cp[0] == c+3)获取值返回两个插槽,然后取消引用以获取s3。然后添加3,然后打印:Z

代码语言:javascript
复制
printf("%s ", cpp[-1][-1]+1);

cp[2] (即cp[1] == c+2)中获取返回1槽的值,然后从该槽(即c[1] == s1)中获取一个槽的值,然后添加1并打印:CQ

要记住的重要事情是:

  • 每个*[]都是一个取消引用,它指的是指针指向的值。
  • 增量/递减运算符对最后一个取消引用的事物进行操作(如果还没有取消引用,则直接对变量进行操作。
  • 一元运算符的优先级高于二进制运算符,因此(不加括号),所有一元后缀运算符都会先发生,然后是一元前缀,然后才是二进制。
  • []实际上是一元后缀运算符,而不是infix二进制运算符(尽管它有两个操作数),因为第二个操作数在括号内。
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30292412

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档