【问题标题】:logic applied to pointer to string array应用于指向字符串数组的指针的逻辑
【发布时间】:2015-04-09 19:31:38
【问题描述】:

我最近在面试过程中遇到了这个问题。 我需要一些帮助来理解这个程序的第二个输出背后的逻辑。

#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);     //1st statement
    printf("%s ", *--*++cpp+3);  //2nd statement
    printf("%s ", *cpp[-2]+3);    //3rd statement
    printf("%s ", cpp[-1][-1]+1);  //4th statement
    return 0;
}

输出:- TEST sQuiz Z CQ

我从上面的代码中了解到:

为了简单起见,我们可以将 cp[] 视为 {QUIZ TEST MCQ GeksQuiz}
第一条语句:
**++cpp -> cpp 将指向TEST 的基地址,并且将其取消引用两次得到TEST,这很好。

但在第二条语句中我无法揭开逻辑的神秘面纱:
*--*++cpp+3 -> ++cpp 指向 MCQ *++cpp 将是 M 的地址,--*++cpp 将是以前的地址到M,现在我被困在这里。它是如何将sQuiz 作为输出的?
(afaik ++(后缀)和 * 具有相同的优先级和从右到左的关联性)

(免责声明:请开阔思路。并非所有代码都用于产品开发。此代码评估对 C 指针的理解)

【问题讨论】:

  • 版主备注我已经清除了cmets,如果你觉得有必要继续跑题,请带它去聊天。

标签: c arrays string pointers


【解决方案1】:

在第一个printf 之后,cpp 指向c+2

                 CP
              +------+                                                                     
              |      |                                                                     
            0 |  C+3 +----------------------------------------------------------------+    
              |      |                                                                   |    
              |      |                                                                |    
              +------+                                                                |    
              |      |                                                                |    
            1 |  C+2 +-------------------------------------------------+              |    
CPP --------> |      |                                                 |              |    
              |      |                                                 |              |    
              +------+                                                 |              |    
              |      +---------------------------------------+         |              |    
            2 |  C+1 |                                       |         |              |    
              |      |                                       |         |              |    
              |      |                                       |         |              |    
              +------+                                       |         |              |    
              |      +-----------------------+               |         |              |    
            3 |  C   |                       v               v         v              v    
              |      |                                                                     
              |      |                +-------------+------------+-----------+------------+
              +------+             C  |  "GeksQuiz" | "MCQ"      | "TEST"    | "QUIZ"     |       
                                      |             |            |           |            |
                                      +-------------+------------+-----------+------------+
                                        0             1           2            3       

在第二个printf++cpp 将增加cppc+1
*++cpp 将取消引用cpp 并将给出c+1
-- 将减少@987654333 @ by 1 因此,*--*++cpp 最终将给出c
c+3 将指向"GeksQuiz" 的第4 个字符,即s
请注意,在第二个 printf cpp 之后将指向 cp[0],它现在指向 c

              +------+                                                                     
              |      |                                                                     
            0 |  C+3 +----------------------------------------------------------------+    
              |      |                                                                   |    
              |      |                                                                |    
              +------+                                                                |    
              |      |                                                                |    
            1 |  C+2 +-------------------------------------------------+              |    
              |      |                                                 |              |    
              |      |                                                 |              |    
              +------+                                                 |              |    
              |      +-------------------------+                       |              |    
            2 |  C   |                         |                       |              |    
 CPP -------->|      |                         |                       |              |    
              |      |                         |                       |              |    
              +------+                         |                       |              |                                                  
              |      +-----------------------+ |                       |              |    
            3 |  C   |                       v v                       v              v    
              |      |                                                                     
              |      |                +-------------+------------+-----------+------------+
              +------+                |  "GeksQuiz" | "MCQ"      | "TEST"    | "QUIZ"     |
                                      |             |            |           |            |
                                      +-------------+------------+-----------+------------+
                                        0             1           2            3       

【讨论】:

  • thnks.so 在第二个 stmnt 之后,cpp 应该指向 Geksquiz 的基地址。现在为 *cpp[-2]+3 -> *cpp[-2] 点 2 个 pos,即 TEST 但它指向 3 个 pos,即 QUIZ
  • 在第二个printf 语句之后,cpp 指向c+1cpp[-2] 指向cpp - 2,即c+3
  • @hacks 在第二条语句 cpp 指向 c+1 最初所在的位置之后是,但该元素的值现在只是 c。这并不重要,因为该元素再也不会被访问。
  • @MooseBoys;这就是我的回答。
  • @hacks 但是您的第二个图表中仍然有一个c+1 - 不应该是c 吗?
【解决方案2】:

*--*++cpp+3 被处理为*(--(*(++cpp)))+3,这意味着:

*++cpp 指向"MCQ"(由于指针初始移动到“列表中的下一个”两次),在第一个printf 结束后指向"TEST"

--*++cpp 指向"GeksQuiz"

*--*++cpp 指向"GeksQuiz" 的开头,指向它的第一个字符

然后你将结果指针前进 3,得到你看到的输出。

【讨论】:

  • 如何 --*++cpp 指向“GeksQuiz” -- 标志应该将指针移回 TEST?
  • 您将指针前进一格,取消引用它(指向列表中的特定位置),然后移动到列表中的“上一个”成员
  • cpp 在第一个 printf 完成时已经指向“TEST”
  • @YePhIcK;它不是指向TESTcpp,而是它的*cpp
  • 是的,是的,我只是在简化。当然cpp 并不是直接指向它。它指向一个指向"TEST" 的指针 :)
【解决方案3】:

最初:

0x100: "GeksQuiz"
0x200: "MCQ"
0x300: "TEST"
0x400: "QUIZ"
0x500: { 0x100, 0x200, 0x300, 0x400 } // c
0x600: { 0x518, 0x510, 0x508, 0x500 } // cp
0x700: 0x600 // cpp

在语句 1 之后:

0x700: 0x608 // ++cpp = 0x608
// *cpp = 0x510
// **cpp = 0x300 = "TEST"

语句2之后:

0x700: 0x610 // ++cpp = 0x610
0x600: { 0x518, 0x510, 0x500, 0x500 } // --*++cpp = 0x500
// *--*++cpp = 0x100 = "GeksQuiz"
// *--*++cpp+3 = 0x103 = "sQuiz"

在语句 3 之后:

// cpp = 0x610
// cpp[-2] = 0x518
// *cpp[-2] = 0x400 = "QUIZ"
// *cpp[-2]+3 0x403 = "Z"

在语句 4 之后:

// cpp = 0x610
// cpp[-1] = 0x510
// cpp[-1][-1] = 0x200 = "MCQ"
// cpp[-1][-1]+1 = 0x201 = "CQ"

【讨论】:

    猜你喜欢
    • 2014-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-28
    • 1970-01-01
    • 1970-01-01
    • 2012-02-08
    • 2013-09-27
    相关资源
    最近更新 更多