s is array of three character pointers and p is capabale of holding a address of a pointer variable which in turn points to a character.
up to p = s statement situation is like below :

Here, few assumptions : size of char variable = 1 Byte, size of pointer varibale = 4 Byte.
[addresses are assumed]
Addresses of first,second and third element of s are 4000,4004,4008. Address of p is 5000.
First string : starting address = 1000
Second string : starting address = 2000
Third string : starting address = 3000
[ These starting locations are linker/compiler dependent, not a C language standard http://stackoverflow.com/questions/38997119/storing-of-string-literals-in-consecutive-memory-locations?noredirect=1#comment65347237_38997119]
[I have just assumed for easy explanation purpose]
and values of s[0] = 1000,s[1] = 2000,s[2] = 3000;
printf("%s ",++*p);
*p gives the 1st element of s, and value of 1st element of s, ( s[0] ) is = 1000. [ *p is an lvalue ,so, no issue with ++ operator ]
We pre-increment this first element and s[0] becomes 1001. 1001 points to 'n' of the first string. By using %s specifier printf() prints the entire string starting from n.
=> O/P = nowledge

printf("%s ",*p++);
Here we have a little bit of precedence comparison, (post increment ) ++ wins. So, exp. evaluation : *(p++)
Since it is a post-increment dereference will take place on the old_value of p which is 4000. after dereferencing resulting address points to 1001 again.
=> O/P = nowledge.
value of p is incremented to 4004.

printf("%s ",++*p);
*p gives the 2nd element of s, and value of 2nd element of s, ( s[1] ) is = 2000. [ *p is an lvalue ,so, no issue with ++ operator ]
We pre-increment this second element and s[1] becomes 2001. 2001 points to 's' of the second string. By using %s specifier printf() prints the entire string starting from s.
=> O/P = s
