Running the following code will print out orld. What is happening here? What exactly does &(p[*(i + j)]) do?
#include <stdio.h>
char p[] = "HelloWorld";
int i[] = {2,1,3,5,6}, j = 4;
int main()
{
printf(&(p[*(i + j)]));
return 0;
}
Running the following code will print out orld. What is happening here? What exactly does &(p[*(i + j)]) do?
#include <stdio.h>
char p[] = "HelloWorld";
int i[] = {2,1,3,5,6}, j = 4;
int main()
{
printf(&(p[*(i + j)]));
return 0;
}
char p[] = "HelloWorld";
int i[] = {2,1,3,5,6}, j = 4;
&(p[*(i + j)]) is evaluated as below:
here i is the base address of array i. Thus i+4 will be the address of the fifth element in the array i. *(i+j) will be equal to 6. P[6] will be o after W. &(p[*(i + j)]) would be equal to &p[6]. Thus in printf you are passing the address of o and the output would be orld.
Let's start off by learning these couple of facts:
1) Arrays are sequence of allocated memory locations. The array label itself, is the address of the memory location of the very first element of the sequence. Example:
int asd[5] = { 11, 12, 13, 14, 15 }; // <-- this is an array
/* the following is what it looks like in the memory:
11 12 13 14 15
the value of, for example, asd[4] is 15
the value of asd itself is the memory address of asd[0], the very first element
so the following is true:
asd == &asd[0] */
2) When the programme encounters a string literal, that is, anything inside double quotes, like "HelloWorld" in your example, it fills some memory location with those characters, and then one more character, '\0' as a mark of end, so that programme may know when to stop; then, it returns the memory location of the first character. So in other words, "HelloWorld" alone creates an array and returns the label of that array.
3) asd[3], *(asd + 3) and 3[asd], all are the same; they all point to the content of the memory location that has the address asd + 3. The pointer type of the asd is important here, it determines how much bits/bytes to offset from the asd. As for int * asd, asd + 3 will advance 3 * sizeof ( int ) bytes ahead of the asd.
Now, with all this, let's examine what &( p[ *(i + j) ] ) really is:
&( p[ *( i + j ) ] )
&( p[ *( i + 4 ) ] )
&( p[ i[4] ] )
&( p[ 6 ] ) // This will return the address of `7th` element to the printf.
( p + 6 ) // A pointer to second 'o'
Then this is pushed into the printf as the const char * argument, which prints 'o', then 'r', then 'l', then 'd', and then encounters the '\0', thus understands that the string is over and stops there.
I'll try to simplify it step by step
#include <stdio.h>
char p[] = "HelloWorld";
int i[] = {2,1,3,5,6}, j = 4;
int main()
{
printf(&(p[*(i + j)]));
return 0;
}
The first three lines are obvious:
p is an array of 10 charactersi is an array of 5 integersj is an integer and has the value 4printf(&(p[*(i + j)]));
is the same as
printf(&(p[*(i + 4)]));
is the same as
printf(&(p[*([adress of first element of i] + 4)]));
is the same as
printf(&(p[*([adress of fourth element of i])]));
Now you have to know what *address gives you the value that is in address. So:
printf(&(p[6]));
Now that's the point where I guess you were struggling. You have to know:
&something gives you the address of somethingSo this "slices" the array HelloWorld to orld. In Python you would write p[6:], in C you write &p[6].
Let's go by steps: *(i+j) it's the same as i[j], that is 6. p[6] is the value at p pointer plus 6.
The address of operator get the address of that character, thus a char*.
A char pointer pointing to the 6th character of p passed to the printf function print the text "orld".
&(p[*(i + j)]) leads to below expression which is address of p[6] being j = 4.
&(p[*(i + j)]) == &(p[(i[j])]) == &(p[(i[4])]) == &(p[6]) == &p[6]
Yes you can print using printf without format %s specifier since it takes strings as arguments.
Read comments for explanation
#include <stdio.h>
char p[] = "HelloWorld";
int i[] = {2,1,3,5,6}, j = 4;
int main()
{
printf(&(p[*(i + j)])); //*(i+j) = i[j] => i[4]= 6
// &(p[*(i + j)]) => place the pointer in memory block that his address p[6]
// so printf print the string starting from the p[6] ie from 'o' => orld
return 0;
}