逻辑应用于指向字符串数组的指针

时间:2015-04-09 19:31:39

标签: c arrays string pointers

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

#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 - &gt; cpp会指向TEST的基地址,并且将其解除引用2次会产生TEST,这很好。

但在第二个陈述中我无法揭开逻辑的神秘面纱:
*--*++cpp+3 - &gt; ++cpp MCQ的{​​{1}} *++cpp地址为M的地址,--*++cpp将是M的先前地址,现在我被困在这里。如何将sQuiz作为输出?
(afaik ++(后缀)和*具有相同的优先级和从右到左的关联性)

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

3 个答案:

答案 0 :(得分:5)

首先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会将cpp增加到c+1
*++cpp会取消引用cpp,并会c+1 --c+1递减1因此,*--*++cpp最终会c。{  c+3将指向"GeksQuiz"的4 th 字符,即s
请注意,在第二个printf cpp后,指向cp[0]的{​​{1}}现在指向c

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

答案 1 :(得分:4)

*--*++cpp+3被处理为*(--(*(++cpp)))+3,表示以下内容:

*++cpp指向"MCQ"(由于指针初始移动到&#34;列表中的下一个&#34;两次),指向"TEST"后的第一个printf 1}}结束了

--*++cpp指向"GeksQuiz"

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

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

答案 2 :(得分:2)

最初:

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"