[英]What exactly does &(p[*(i + j)]) do?
Running the following code will print out orld
. 运行以下代码将打印出orld
。 What is happening here? 这里发生了什么? What exactly does &(p[*(i + j)])
do? &(p[*(i + j)])
究竟做了什么?
#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: &(p[*(i + j)])
评估如下:
here i
is the base address
of array i
. 这里i
是array i
的base address
。 Thus i+4
will be the address
of the fifth element
in the array i
. 因此i+4
将是array i
fifth element
的address
。 *(i+j)
will be equal to 6
. *(i+j)
将等于6
。 P[6]
will be o
after W
. P[6]
将o
后W
。 &(p[*(i + j)])
would be equal to &p[6]
. &(p[*(i + j)])
等于 &p[6]
。 Thus in printf
you are passing the address of o
and the output would be orld
. 因此,在printf
您传递的address of o
的address of o
输出将是orld
。
Let's start off by learning these couple of facts: 让我们从了解这几个事实开始:
1) Arrays are sequence of allocated memory locations. 1) 数组是分配的存储位置序列。 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; 2)当程序遇到一个字符串文字时,即双引号内的任何内容,例如你的例子中的"HelloWorld"
,它用这些字符填充一些内存位置,然后再添加一个字符, '\\0'
作为结束标记,以便程序可以知道何时停止; 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. 换句话说, "HelloWorld"
单独创建一个数组并返回该数组的标签。
3) asd[3]
, *(asd + 3)
and 3[asd]
, all are the same; 3) asd[3]
, *(asd + 3)
和3[asd]
,都是一样的; they all point to the content of the memory location that has the address asd + 3
. 它们都指向具有地址asd + 3
的内存位置的内容。 The pointer type of the asd
is important here, it determines how much bits/bytes to offset from the asd
. asd
的指针类型在这里很重要,它确定从asd
偏移多少位/字节。 As for int * asd
, asd + 3
will advance 3 * sizeof ( int )
bytes ahead of the asd
. 至于int * asd
, asd + 3
将在asd
之前提前3 * sizeof ( int )
字节。
Now, with all this, let's examine what &( p[ *(i + j) ] )
really is: 现在,有了这一切,让我们来看看&( p[ *(i + j) ] )
究竟是什么:
&( 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. 然后将其作为const char *
参数推入printf
,打印'o'
,然后'r'
,然后'l'
,然后'd'
,然后遇到'\\0'
,从而理解字符串是结束并停在那里。
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 characters p
是一个包含10个字符的数组 i
is an array of 5 integers i
是一个5个整数的数组 j
is an integer and has the value 4 j
是一个整数,其值为4 printf(&(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
. 现在,你必须知道什么*address
给你,是在价值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
&something
为您提供something
地址 So this "slices" the array HelloWorld
to orld
. 所以这将“ HelloWorld
”数组“切片”到orld
。 In Python you would write p[6:]
, in C you write &p[6]
. 在Python中,您可以编写p[6:]
,在C中编写&p[6]
。
Let's go by steps: *(i+j)
it's the same as i[j]
, that is 6
. 让我们一步一步: *(i+j)
它与i[j]
相同,即6
。 p[6]
is the value at p pointer plus 6. p[6]
是p指针加上6的值。
The address of operator get the address of that character, thus a char*
. 运算符的地址获取该字符的地址,因此为char*
。
A char pointer pointing to the 6th character of p
passed to the printf function print the text "orld". 指向传递给printf函数的p
的第6个字符的char指针打印文本“orld”。
&(p[*(i + j)])
leads to below expression which is address of p[6]
being j = 4
. &(p[*(i + j)])
导致下面的表达式,即p[6]
地址为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. 是的,您可以使用printf
进行打印而不使用格式%s
说明符,因为它将字符串作为参数。
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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.