GorvGoyl
GorvGoyl

Reputation: 49270

logic applied to pointer to string array

I recently came across this question in an Interview process. I need some help to understand the logic behind 2nd output of this program.

#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;
}

output:- TEST sQuiz Z CQ

What I understand from above code:

for the sake of simplicity we can consider cp[] as {QUIZ TEST MCQ GeksQuiz}
1st statement:
**++cpp -> cpp will points to base address of TEST and dereferencing it 2 times gives TEST which is fine.

but in 2nd statement I can't demystify the logic:
*--*++cpp+3 -> ++cpp points to MCQ *++cpp will be the address of M , --*++cpp will be previous address to M, now I'm stuck here. how it's getting sQuiz as output?
(afaik ++(suffix) and * have same precedence and right to left associativity)

(DISCLAIMER: please broaden your mind. not all codes are meant for product development. this code evaluates the understanding of C pointers)

Upvotes: 3

Views: 579

Answers (3)

haccks
haccks

Reputation: 106022

After first printf, cpp is pointing to 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       

In second printf, ++cpp will increment cpp to c+1.
*++cpp will dereference cpp and will give c+1.
-- will decrement c+1 by 1 therefore, *--*++cpp will ultimately give c.
c+3 will point to the 4th character of "GeksQuiz", i.e. s.
Note that after second printf cpp will point to cp[0] which is pointing to c now.

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

Upvotes: 5

MooseBoys
MooseBoys

Reputation: 6793

Initially:

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

After statement 1:

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

After statement 2:

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

After statement 3:

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

After statement 4:

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

Upvotes: 2

YePhIcK
YePhIcK

Reputation: 5856

*--*++cpp+3 is processed as *(--(*(++cpp)))+3 which means the following:

*++cpp points to "MCQ" (due to initial move of the pointer to "next in list" twice), was pointing to "TEST" after the first printf was over

--*++cpp points to "GeksQuiz"

*--*++cpp points to the beginning of the "GeksQuiz", to its first character

Then you advance the resulting pointer by 3, resulting in the output you see.

Upvotes: 4

Related Questions