繁体   English   中英

&(p [*(i + j)])究竟做了什么?

[英]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)])评估如下:

这里iarray ibase address 因此i+4将是array i fifth elementaddress *(i+j)将等于6 P[6]oW &(p[*(i + j)]) 等于 &p[6] 因此,在printf您传递的address of oaddress 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 * asdasd + 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM