地址如何具有多个值?

时间:2014-10-01 19:51:02

标签: c arrays pointers

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有两个值?

3 个答案:

答案 0 :(得分:4)

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)i相同,见上文。

答案 1 :(得分:2)

我会尝试借助图解释。

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

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

enter image description here

现在让我们看看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 (见上文)。请注意,此中间值(与任何其他值一样!)具有类型。在这种情况下,类型是int (*)[5] - 指向数组的指针
    • *(&i) - “获取存储在地址 2358832 ”的数组值。我们已经知道,“数组的值”表示此数组的第一个元素的地址 - 2358832

答案 2 :(得分:0)

之后,你会感到困惑
int i[5]={0,1,2,3,4,};
int *ip=&i[0];

" ip =& i = 2358832但* ip = 0且*(& i)= 2358832。在这种情况下,一个地址如何解析2358832有两个值?"。

两个表达式各自产生一个具有相同数值的地址。如何通过打印取消引用这些相同地址的结果来证明相同地址中存储了不同的值?

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

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

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

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

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

#include<stdio.h>
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;
}