I am preparing for quiz on programming involving guessing C code outputs.
After long try, I am still struggling to understand the output of the below code:
#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);
printf("%s ", *--*++cpp+3);
printf("%s ", *cpp[-2]+3);
printf("%s ", cpp[-1][-1]+1);
return 0;
}
Output
TEST sQuiz Z CQ
Can anyone please help me to understand why is this output?
It will be helpful to create the following temporary variables to understand some of the expressions.
char s1[] = "GeksQuiz";
char s2[] = "MCQ";
char s3[] = "TEST";
char s4[] = "QUIZ";
char *c[] = {s1, s2, s3, s4};
char **cp[] = {c+3, c+2, c+1, c};
char ***cpp = cp;
First printf
printf("%s ", **++cpp);
**++cpp
has the side effect of cpp = cpp+1
, and evaluates to
**(cpp+1)
, which is the same as
*(cp[1])
, which is the same as
*(c+2)
, which is the same as:
c[2]
, which is the same as:
s3
, which evaluates to "TEST"
.(initially it was s2 corrected)
At the end of that statement, cpp
is the same as cp+1
.
Second printf
printf("%s ", *--*++cpp+3);
*--*++cpp+3
is the same as
*(--(*(++cpp))) + 3
, has side effect of cpp = cpp+1
, and evaluates to:
*(--(*(cpp+1))) + 3
, which is the same as
*(--(*(cp+2))) + 3
, which is the same as
*(--(cp[2])) + 3
*(--(cp[2])) + 3
has the side effect of cp[2] = cp[2]-1 = c+1-1 = c
, and evaluates to:
*(cp[2]-1) + 3
, which is the same as
*(c+1-1) + 3
, which is the same as
*(c) + 3
, which is the same as
c[0] + 3
, which is the same as
s1 + 3
, which evaluates to "sQuiz"
At the end of that statement, cpp
is the same as cp+2
.
Third printf
printf("%s ", *cpp[-2]+3);
*cpp[-2]+3
is the same as
*(cpp[-2])+3
, which is the same as
*(cp)+3
because of the previous ++
operations on cpp
., which is the same as
c[3]+3
, which is the same as
s4+3
, which evaluates to "Z"
.(corrected initially it was s3+3)
Fourth printf
printf("%s ", cpp[-1][-1]+1);
cpp[-1][-1]+1
is the same as
*(cpp-1)[-1]+1
, which is the same as
*(*(cpp-1) -1) + 1
, which is the same as
*(*(cp+1) -1) + 1
, which is the same as
*(cp[1] -1) + 1
, which is the same as
*(c+2-1) + 1
, which is the same as
*(c+1) + 1
, which is the same as
c[1] + 1
, which is the same as
s2 + 1
, which evaluates to "CQ"
.
It helps to draw a picture of the pointers, but that's difficult to do on StackOverflow:
cpp: cp
cp: c+3, c+2, c+1, c
c: s0, s1, s2, s3
s0: 'G', 'e', 'K', 's', 'Q', 'u', 'i', 'z', '\0'
s1: 'M', 'C', 'Q', '\0'
s2: 'T', 'E', 'S', 'T', '\0'
s3: 'Q', 'U', 'I', 'Z', '\0'
This is a table showing each of the arrays, plus the static strings (which I've given names to make them easier to talk about).
So now lets look at what the statements do:
printf("%s ", **++cpp);
Increment cpp
(changing to point at cp[1]
), then deref twice -- the first gets c+2
, the second s2
which is then printed: TEST
printf("%s ", *--*++cpp+3);
Increment cpp
(now points at cp[2]
), dereferece and decrement that (changing cp[2]
to now point at c[0]
), and dereference again (getting s0
). Finally add 3 (s0+3
) and print: sQuiz
printf("%s ", *cpp[-2]+3);
Get the value back 2 slots from cp[2]
(which is cp[0]
== c+3
) and then dereference it to get s3
. Then add 3, and print: Z
printf("%s ", cpp[-1][-1]+1);
Get the value back 1 slot from cp[2]
(which is cp[1]
== c+2
), then get the value back one slot from that (which is c[1]
== s1
), then add 1 and print: CQ
The important things to remember are:
*
or []
is a dereference which refers to the value pointed at by a pointer[]
is really a unary postfix operator, not an infix binary operator (even though it has two operands), as the second operand is within the brackets.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With