Reputation: 17
can someone explain why this prints out : "d ce" I think i understood why it prints out "d" but i don't understand the "ce"
#include <stdio.h>
int main(void){
char s1[]="abcd",*cp;
cp=s1+2;
printf("%c %s\n",(*(++cp))++,s1+2);
return 0;
}
Upvotes: 1
Views: 101
Reputation: 1738
Hope the inline comments makes it clear.
#include <stdio.h>
int main()
{
char s1[]="abcd",s2[]="cdef",s3[5],*cp;
printf("s1 = %p\n", (void*)s1); // prints start address of s1
cp = s1+2; // cp points to 2 chars advanced of s1 i.e 'c'
printf("cp = %p\n", (void*)cp); // prints address at 'c'
//first increment cp to point to next location, which now points at 'd' from 'c'
//the outer ++ increments 'd' to 'e' post-fix, so first prints 'd'
printf("(*(++cp))++ = %c\n", (*(++cp))++);
printf("s1 = %s\n", s1); // you will see "abce"
printf("s1+2 = %s\n", s1+2); // 2 chars advanced of s1, i.e "ce"
//printf("%c %s\n",(*(++cp))++,s1+2);
return 0;
}
Upvotes: 0
Reputation: 213513
TL;DR
In order to understand this code, you need rather in-depth C knowledge of sequence points, undefined behavior and misc "language-lawyer" stuff. If that isn't the case, then just simply forget about writing or understanding artificial crap code like this and you can stop reading here. Advanced explanation follows.
C11 6.5 states:
If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined. If there are multiple allowable orderings of the subexpressions of an expression, the behavior is undefined if such an unsequenced side effect occurs in any of the orderings.
Generally this renders weird code like this undefined behavior. But in this case, 1) s
is not a scalar but an aggregate. The scalar is rather the s[3]
lvalue. And 2) the )++
increment that changes the value is not unsequenced to another value computation using the object inside the same expression.
(*(++cp))++
and s1+2
are unsequenced in relation to each other but that doesn't matter for the purpose of making a case for undefined behavior.
cp=s1+2;
here cp
is pointing at the 'c'
.(*(++cp))++
first increases the pointer one step to point at s[3]
that contains 'd'
. Then it dereferences the pointer so that we get the value 'd'
.'e'
.s1+2
but it doesn't matter.printf
then spots %s
and de-references the string, a value computation, but sequenced in relation to the previous )++
. This prints ce
.So the code is actually well-defined, even though horribly written.
Upvotes: 2