3

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)

1
  • 6
    Moderator Note I've purged the comments, if you feel the need to continue the off-topic conversation please take it to chat. Commented Apr 9, 2015 at 20:02

3 Answers 3

5

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       
Sign up to request clarification or add additional context in comments.

6 Comments

thnks.so after 2nd stmnt, cpp should be poiting to base address of Geksquiz. now for *cpp[-2]+3 -> *cpp[-2] points 2 pos back i.e. TEST but it is pointing 3 pos back i.e.QUIZ
After second printf statement, cpp is pointing to c+1. cpp[-2] is pointing to cpp - 2, i.e. at c+3.
@haccks Yes after the second statement cpp is pointing to where c+1 was originally, but the value of that element is now just c. Not that it matters since that element is never accessed again.
@MooseBoys; That's what my answer says.
@haccks But your second diagram still has a c+1 in it - shouldn't it be c instead?
|
4

*--*++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.

5 Comments

how --*++cpp points to "GeksQuiz" -- sign should move pointer back to TEST?
you advance the pointer by one, dereference it (pointing to a particular spot in the list), then move to a "previous" member in the list
cpp was already pointing to "TEST" by the time the first printf was done
@YePhIcK; Its not cpp that is pointing to TEST, but its *cpp.
Yes-yes, I was just simplifying. Of course cpp is not directly pointing to it. it is pointing to a pointer that is pointing to "TEST" :)
2

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"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.