【问题标题】:Pointers in c language program outputc语言程序输出中的指针
【发布时间】:2014-05-21 08:59:47
【问题描述】:

我有一个问题:

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”,无法理解 -- before * 会在这里做什么。还是我的方法完全错误?

【问题讨论】:

    标签: c pointers char output


    【解决方案1】:

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

    可能这个面试问题暗示了你对序列点的了解,那么它并不像我看到的那么基础,但是NEVER EVER 即使为你的宠物项目写这样的代码,我什至不想提及生产代码。这很愚蠢。

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

    编辑

    只是关于序列点的提示,因为我在其他发布的答案和 cmets 中看到了一些误解。这是 *--*++cpp+3 不是 unspecified behaviour 或 undefined behaviour(我的意思是一般来说这是一个糟糕的代码),但是这个 IS:

    int i =1;    
    *--*++cpp+i+i++;
    

    上面的代码是unsequenced和unspecified。请阅读 undefined behaviour、unspecified behaviour、implementation-defined behavior 和 sequence points e.g. here 之间的区别。我写这一切是为了向你解释为什么你应该完全避免这样一个糟糕的代码(无论它是否合法语言标准与否)。是的,您的代码是合法的,但不可读,而且,正如您在我的编辑中看到的,小改动使它成为 illegal。不要以为我们不想帮助你,我的意思是与你类似的代码通常是一个糟糕的代码,无论它被问到哪里。如果他们让你解释一下WHY 这样的代码很糟糕而且很脆弱,那就更好了——那么这将是一个很好的面试问题。

    附:实际输出是一个空字符串,因为您打印了一个空终止符。请参阅下面的一个很好的答案 - 它解释了前面 C 运算符的输出(你也应该学习它,这样这些问题就不会打扰你了)。

    【讨论】:

      【解决方案2】:

      此表达式中的所有变量只修改一次。可能我不太了解序列点,但我不明白为什么人们称这个表达式为未定义行为。

      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'
      

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

      【讨论】:

      • 你是对的,上面的代码不是未指定的。你可以看到我的编辑 - 我提到了这一点。我们只是想强调,这样的代码通常是一件坏事。您从运算符优先级的角度解释是好的,可以标记为接受,因为它直接回答了一个问题。您可以阅读我提供的示例和链接,以更好地理解序列点。
      猜你喜欢
      • 2023-02-02
      • 2018-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多