[英]What exactly does &(p[*(i + j)]) do?
运行以下代码将打印出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;
}
char p[] = "HelloWorld";
int i[] = {2,1,3,5,6}, j = 4;
&(p[*(i + j)])
评估如下:
这里i
是array i
的base address
。 因此i+4
将是array i
fifth element
的address
。 *(i+j)
将等于6
。 P[6]
将o
后W
。 &(p[*(i + j)])
等于 &p[6]
。 因此,在printf
您传递的address of o
的address of o
输出将是orld
。
让我们从了解这几个事实开始:
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
将在asd
之前提前3 * sizeof ( int )
字节。
现在,有了这一切,让我们来看看&( 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'
然后将其作为const char *
参数推入printf
,打印'o'
,然后'r'
,然后'l'
,然后'd'
,然后遇到'\\0'
,从而理解字符串是结束并停在那里。
我会尝试逐步简化它
#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]
。
让我们一步一步: *(i+j)
它与i[j]
相同,即6
。 p[6]
是p指针加上6的值。
运算符的地址获取该字符的地址,因此为char*
。
指向传递给printf函数的p
的第6个字符的char指针打印文本“orld”。
&(p[*(i + j)])
导致下面的表达式,即p[6]
地址为j = 4
。
&(p[*(i + j)]) == &(p[(i[j])]) == &(p[(i[4])]) == &(p[6]) == &p[6]
是的,您可以使用printf
进行打印而不使用格式%s
说明符,因为它将字符串作为参数。
阅读评论以获得解释
#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.