为什么p不显示相同的地址?

时间:2014-11-04 15:55:51

标签: c arrays pointers memory-address

我正在学习C中数组中的指针。我真的很困惑指针数组是什么。看看这个例子 -

#include<stdio.h>
int main()
{
    static int a[] = { 0, 1, 2, 3, 4 };
    int *p[] = { a, a+1, a+2, a+3, a+4 };

    printf( "%p %p %p %d ", p, *p, a, *(*p));
    return 0;
}

当我运行此程序时,我会为ap获取不同的地址。为什么?据我所知,a是指向数组的第0个元素的指针,p是指向指针的指针。 a指向第0个元素的地址,但是p呢?有地址的地址吗?

5 个答案:

答案 0 :(得分:1)

地址由位组成,任何由位组成的地址都可以放入存储器中。记忆中的一切都有一个地址。

这并不意味着程序中的每个地址值都在内存中。地址也可以是用作表达式一部分的临时值。

同样适用于整数值。其中一些是在记忆中,一些不是。你可以这样:

int i = 7;
int *p = &i;

但你不能这样做:

int *q = &7;

i是内存中存在的变量的名称,您可以使用&获取其地址。值7存储在该地址。 &7无法正常工作,因为程序源代码中存在文字7并不足以导致值7在运行时存在于内存中。

稍微提一点技术术语,i左值7右值。前缀&运算符要求其操作数为左值,但它不会产生左值结果。 &i是一个右值,就像7一样。这就是&(&i)无效的原因。

答案 1 :(得分:1)

将变量视为地址的别名。当你有

int v1 = 10;

v1是包含10的地址的别名。

当你有:

int* v2 = &v1;

v2是包含v1地址的地址的别名。

地址可以包含可以是其他地址或原始值的值,例如int s,char s等。

要回答你的问题,

  

有地址的地址吗?

严格来说,答案是否定的。但如果你有:

int** v3 = &v2;

然后,v3是地址的别名,地址的值为地址的值,其地址值为int

在你的情况下,

static int a[] = { 0, 1, 2, 3, 4 };
int *p[] = { a, a+1, a+2, a+3, a+4 };

a是一个数组,是int的数组。在表达式中使用时,它会衰减为指针。 aa+1等评估指向int s。

的指针

p也是一个数组,int*的数组。在表达式中使用时,它会衰减为指针。 pp+1等评估指向int* s。

的指针

p评估为包含int* - a的地址 a评估的地址包含int - 0

*p评估为a *a评估为0

答案 2 :(得分:1)

C中没有两个变量可能具有相同的地址。

数组a和数组p是变量。所以他们必须有不同的地址。

这是另一个例子:

int x[3] = { 0, 1, 2 } ;
int y[3] = { 0, 1, 2 };

printf("%p %p\n", &x , &y);

示例中的数组存储的数据类型与int不同,这没有区别。

此外,数组的第一个元素始终位于数组的开头,因此输出x(当您尝试打印其值时衰减为&x[0])将获得与&x

答案 3 :(得分:0)

p 指向内存块的第一个位置,包含:

{ a,a+1,a+2,a+3,a+4 }

a 指向包含

的内存块的第一个位置
{0,1,2,3,4}

这两个因此指向不同的内存块。

p [0] (或 * p )和 a 应具有相同的地址。

答案 4 :(得分:0)

想想事情在记忆中的组织:

a:包含5个整数到0到4的连续内存区域 - a是一个数组而&a == &(a[0])(并且与a相同)

p是一个指向int的指针数组:它又是一个包含5个指针的连续内存区域。 p是一个数组,因此p == &(p[0])。但现在p[0]是一个包含地址a的指针。

所以p是包含a地址的内存区域的地址:它实际上是地址的地址

当然,*p(或p[0])与a相同,**pa[0]。但至于任何数组p p[0]相同