运行以下代码将打印出orld
。这里发生了什么? &(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;
}
答案 0 :(得分:3)
char p[] = "HelloWorld";
int i[] = {2,1,3,5,6}, j = 4;
&(p[*(i + j)])
评估如下:
此处i
是base address
的{{1}}。因此array i
将是i+4
中address
的{{1}}。 fifth element
将等于array i
。在*(i+j)
之后,6
将为P[6]
。 o
与<{1}} 相等。因此,在W
中,您传递的是&(p[*(i + j)])
,而输出将是&p[6]
。
答案 1 :(得分:3)
让我们从学习这几个事实开始:
1) 数组是已分配内存位置的序列。数组标签本身是序列的第一个元素的内存位置的地址。例如:
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)当程序遇到字符串文字时,即双引号内的任何内容,例如示例中的"HelloWorld"
,它会用这些字符填充一些内存位置,然后一个更多字符,'\0'
作为结束标记,以便程序可以知道何时停止;然后,它返回第一个字符的内存位置。换句话说,"HelloWorld"
单独创建一个数组并返回该数组的标签。
3) asd[3]
,*(asd + 3)
和3[asd]
,都是一样的;它们都指向具有地址asd + 3
的内存位置的内容。 asd
的指针类型在这里很重要,它确定从asd
偏移多少位/字节。对于int * asd
,asd + 3
将在3 * sizeof ( int )
之前提前asd
个字节。
现在,有了这一切,让我们来看看&( 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'
然后将其作为printf
参数推入const char *
,其中'o'
,然后是'r'
,然后是'l'
,然后是{{1}然后遇到'd'
,从而理解字符串结束并停在那里。
答案 2 :(得分:2)
我会尝试逐步简化它
#include <stdio.h>
char p[] = "HelloWorld";
int i[] = {2,1,3,5,6}, j = 4;
int main()
{
printf(&(p[*(i + j)]));
return 0;
}
前三行显而易见:
p
是一个包含10个字符的数组i
是一个包含5个整数的数组j
是一个整数,其值为4 printf(&(p[*(i + j)]));
与
相同 printf(&(p[*(i + 4)]));
与
相同 printf(&(p[*([adress of first element of i] + 4)]));
与
相同 printf(&(p[*([adress of fourth element of i])]));
现在您必须知道*address
为您提供address
中的值。所以:
printf(&(p[6]));
现在这就是我猜你正在挣扎的地方。你必须知道:
&something
为您提供something
所以这会将数组HelloWorld
“切片”到orld
。在Python中,您可以编写p[6:]
,在C中编写&p[6]
。
答案 3 :(得分:1)
让我们一步一步:*(i+j)
它与i[j]
相同,即6
。 p[6]
是p指针加上6的值。
运算符的地址获取该字符的地址,即char*
。
指向传递给printf函数的p
的第6个字符的char指针打印文本“orld”。
答案 4 :(得分:1)
&(p[*(i + j)])
会导致以下表达式,p[6]
的地址为j = 4
。
&(p[*(i + j)]) == &(p[(i[j])]) == &(p[(i[4])]) == &(p[6]) == &p[6]
是的,您可以使用printf
打印而不使用格式%s
说明符,因为它将字符串作为参数。
答案 5 :(得分:0)
阅读评论以获取解释
#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;
}