c语言程序输出中的指针

时间:2014-05-21 08:59:47

标签: c pointers char output

我有一个问题:

char *c[] = {"GeksQuiz", "MCQ", "TEST", "QUIZ"};
char **cp[] = {c+3, c+2, c+1, c};
char ***cpp = cp;

int main()
{
    printf("%s ", *--*++cpp+3);

}

我无法理解输出= sQUIZ, 我的方法:首先它将指向cpp + 3,即c现在++ c意味着指向“MCQ”,*那将给出值“MCQ”,无法理解 - 之前*会在这里做什么。还是我的方法完全错了?

2 个答案:

答案 0 :(得分:2)

我会将其发布为评论中提到的答案。您应该先阅读此内容:http://en.wikipedia.org/wiki/Sequence_point也可以查看here,您可以在互联网上搜索有关sequence points的数十篇文章。这个内容与undefined behaviourunspecified behaviour一样 BAD 。您可以在接受的答案中阅读this帖子,尤其是What is the relation between Undefined Behaviour and Sequence Points?部分。

这个面试问题可能暗示了你对序列点的了解,然后它并不像我看到的那么深,但是NEVER EVER即使你的宠物项目也写*--*++cpp+3这样的代码而且我不会这样做。甚至想提及生产代码。这太傻了。

如果他们寻找经验丰富的C ++ / C开发人员,他们根本不应该提出这样的问题。

修改

关于序列点的提示,因为我在其他已发布的答案和评论中看到了一些误解。这是unspecified behaviour而不是undefined behaviourint i =1; *--*++cpp+i+i++; (我的意思是它通常是一个错误的代码),但是 IS:

unsequenced

上面的代码是unspecifiedundefined behaviour。请阅读unspecified behaviourimplementation-defined behaviorsequence pointsillegal e.g. here之间的差异。我写了这一切是为了解释你为什么要避免这么糟糕代码(从语言标准的角度来看是否合法)。是的,您的代码是合法的,但却不可读,而且正如您在我的修改中看到的那样,小的更改使其成为WHY。不要以为我们不想帮助你,我的意思是类似于你的代码一般都是一个糟糕的代码。如果他们要求你解释{{1}}这样的代码是坏的和脆弱的话会更好 - 那么这将是一个很好的面试问题。

P.S。实际输出是一个空字符串,因为您打印一个空终止符。请看下面的一个很好的答案 - 它解释了之前C运算符的输出(你也应该学习它然后这些问题根本不会打扰你)。

答案 1 :(得分:0)

此表达式中的所有变量仅修改一次。也许我对序列点不了解,但我不知道为什么人们将这个表达式称为未定义的行为。

char *c[] = {"GeksQuiz", "MCQ", "TEST", "QUIZ"};
char **cp[] = {c+3, c+2, c+1, c};
char ***cpp = cp;

/*1*/       cpp;   // == &cp[0]
/*2*/     ++cpp;   // == &cp[1] (`cpp` changed)
/*3*/    *++cpp;   // == cp[1] == c+2
/*4*/  --*++cpp;   // == c+2-1 == &c[1] (`cp[1]` changed)
/*5*/ *--*++cpp;   // == "MCQ"
/*6*/ *--*++cpp+3; // == "MCQ"+4   - it's pointer to '\0'

所以它不应该打印任何东西。