地址如何具有多个值?

int i[5]={0,1,2,3,4,}; int *ip=&i[0]; printf("%d,%d,%d,%d,%d,%d,%d,%d",*ip,ip,&ip,&i,&i[0],i,i[0],*(&i)); 

我在comp中得到的上面代码的输出是

 0,2358832,2358824,2358832,2358832,2358832,0,2358832 

观察到ip=&i=2358832*ip=0*(&i)=2358832 。 在这种情况下,一个地址如何解决2358832有两个值?

我将尝试借助图解释。

 int i[5]={0,1,2,3,4,}; int *ip=&i[0]; 

在这段代码之后,我们有两个变量:5个int的数组i和指向数组i第一个元素的指针ip (即包含数组i的第一个元素的地址)。 让我们看看这些变量是如何在内存中布局的(对于这个图,我假设int的大小为4,指针的大小为8,在你的系统上它可以是不同的,但对于你的问题,它现在无关紧要):

在此处输入图像描述

现在让我们看看printf参数并使用图解释它们:

  • *ip – “取变量ip的值 – 2358832 – 并将此值解释为地址,获取int类型的值(因为ip具有类型int * ),该值存储在此地址 – 0 ”;
  • ip – “获取变量ip的值 – 2358832 ”;
  • &ip – “获取变量ip的地址 – 2358824 ”;
  • &i – “获取变量i的地址 – 2358832 ”;
    • 注1:变量通常占用多个存储单元,在这种情况下,“变量地址”表示该变量占用的第一个存储单元的地址=>变量i占用多个单元但具有地址“2358832” – 其第一个地址细胞;
    • 注2:变量ip占用多个单元格(图中为8)
  • &i[0] – “获取数组i的第一个元素的地址 – 2358832 ”;
  • i – “获得变量i的值 – ”。 这个很棘手。 当编译器请求获取“数组的值”时,编译器获取该数组的第一个元素的地址。 通常它被称为“数组衰减到指针” 。 所以在我们的例子中, i => &i[0] => 2358832 (见上文);
  • i[0] – “获取数组i的第一个元素的值 – 0 ”;
  • *(&i) – 两个步骤:
    • &i => 2358832 (见上文)。 请注意,此中间值(与任何其他值一样!)具有类型。 在这种情况下,type是int (*)[5]指向数组的指针
    • *(&i) – “获取存储在地址2358832的数组值”。 我们已经知道,“数组的值”表示该数组的第一个元素的地址 – 2358832
 int i[5]={0,1,2,3,4,}; int *ip=&i[0]; printf("%d,%d,%d,%d,%d,%d,%d,%d",*ip,ip,&ip,&i,&i[0],i,i[0],*(&i)); 

首先,使用%d格式化地址是错误的。 使用%p 。 你侥幸成功,因为你的地址恰好是4字节整数,与平台的int类型大小相同。

我们一次来看看这个:

  • *ipi[0]相同。
  • ip包含数组的第一个元素的地址,它也是数组的地址,因为数组以其第一个元素开头。
  • &ip包含变量ip的地址。
  • &i包含数组的地址,与ip保存的地址相同,见上文。
  • &i[0]再次与ip相同。
  • i是数组,它衰减到一个指针,因此当被视为地址为ip&i[0]时具有相同的值。
  • i[0] ,你知道那是什么。
  • *(&i)相同,见上文。

令你困惑的是,之后

 int i[5]={0,1,2,3,4,}; int *ip=&i[0]; 

“两个ip =&i = 2358832但是* ip = 0和*(&i)= 2358832。一个地址怎么能在2358832中有两个值?”。

两个表达式各自产生具有相同数值的地址。 如何通过打印解除引用这些相同地址的结果来certificate存储在同一地址的不同值?

如果你想到它,答案必须是ip vs&i的类型(以及printf的弱类型检查)。 它与C / C ++(hi Lundin)类型系统的一个微妙之处有关。 通常,一个数组“衰变”,正如语言所说,指向其第一个元素的指针。 这就是为什么你可以将i传递给一个带有指针(例如printf)的函数,或者向它添加1并获取下一个元素的地址,或者简单地将其取消引用它就像* i。

获取数组的地址是不会衰减的情况之一。 它保持arrays; &我有“指向数组的指针”类型,而不是“指向int的指针”。 数组与第一个元素共享其地址,因此数值相同。 但是编译器对指针的作用是不同的:

解除引用&i为您提供数组,与任何其他类型一样; 当你把它传递给像printf这样的函数时会发生什么? 最后,它衰减到指向其第一个元素的指针,该元素碰巧位于众所周知的地址2358832。

如果你想象一个结构来代替数组,它可能会变得更清楚; 这两者是相关的(结构也是一系列对象,只有不同类型)。 指向第一个struct成员的指针肯定与指向struct的指针有不同的含义,尽管它们肯定具有相同的数值。

或者采取以下一些(严格说明,未定义的行为)程序,该程序显示相同的地址可以携带“不同的值”,具体取决于您告诉编译器对数据执行的操作:

 #include int main() { unsigned int sixpointo = 1086324736; float *fp = (float *)&sixpointo; printf("&sixpointo: %p, fp: %p, sixpointo: %d, *fp: %f\n", &sixpointo, fp, sixpointo, *fp); return 0; }