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 something
So 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;
}