2

im trying to wrap my head around a piece of code we got in our C lecture but I can't figure out what it does.

Here's the code:

int main() {
    static char *s[] = {"black", "white", "pink", "violet"};
    char **ptr[] = {s+3, s+2, s+1, s}, ***p; 
    p = ptr; 
    ++p; 
    printf("%s", **p+1); 
    return 0; 
}

The above code prints "ink", but how does it work?

Trying

printf("s: %c\n",*s[0]);

gives me 'b', *s[1] returns 'w', *s[2] returns 'p'and so on. So *s basically returns the first letter of the strings it has been initialized with. Trying

printf("s: %c\n",**ptr[0]);

returns v, so *s seemingly looks like this:

{b,w,p,v}; 

This, however, is not confirmed by sizeof(s) returning 16 and not 4.

So my question is: whats going on here? Where's the rest of the characters stored?

1
  • 1
    For starters, for any array or pointer s and index i, the expression s[i] is exactly equal to *(s + i). That also means that s + i is exactly equal to &s[i]. And don't forget that arrays naturally decays to pointer to their first elements, i.e. ptr will decay to &ptr[0]. Those two facts should help explain ptr and p. Now, with some pen and paper try to figure out the rest by drawing boxes for each array (and don't forget that the string literals are arrays as well) and using arrows for the pointers. Commented Oct 26, 2018 at 10:14

2 Answers 2

4

you are doing

printf("s: %c\n",*s[0])  // this prints the character 'b'

If you use %s you will get the entire string

printf("s: %s\n",s[0])

A line by line explanation of the code is below

static char *s[] = {"black", "white", "pink", "violet"};  
                         // Here s is an array of pointers to char. 
                         // s[0] will point to "black", s[1] will point to "white" etc.
char **ptr[] = {s+3, s+2, s+1, s}, ***p;  
                        //ptr is an array of pointer to pointer to char.  
                        // ptr[0] will be equal to s+3, i.e. &s[3].
                        // ptr[1] will be &s[2]
                        // p is a pointer to pointer to a pointer. (triple pointer)
p = ptr;                // p is set as the base addr of ptr.
++p;                    // p is incremented, i.e. it points to next element of ptr, i.e. ptr[1]
printf("%s", **p+1);    // This is equivalent to (**p) +1
                        // p = &s[2]. therefore
                        // *p = s[2]
                        // **p = *(s[2]) --> **p points to the `p` character in pink
                        // **p +1 will point to the `i` character in `pink'. That is what is printed.
return 0; 
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for your detailed answer! I think I got the gist, but why is ***pa pointer to a pointer? Shouldn't it be a pointer to a pointer to a pointer?
Sorry, i missed that. Corrected.
Right, got it. One more thing: sizeof(s) returns 16 since *s[] is an array of 4 pointers to char - which each has a size of 4 bytes? How come? s[0] = "black",right, which is a char array of size 5 ?
1

you are using %c which will print only one character so rather you should use, %s which will print complete string from startding address until \0 is encountered.

related to sizeof(s) , it will print the size of number of elements present in your array i.e 4 pointers of size each 4 bytes each pointing to a string.

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.