假设我有三个数组a1[],a2[] and a3[]
。所有三个数组(a1,a2,a3)都指向它们各自数组的第一个元素。
在实现代码时,我声明:
int a1[]={1,2,3,4,5};
int a2[]={1,2,3,4,5};
int a3[]={1,2,3,4,5};
当我打印他们的地址时,地址的排序开始为
(a3+0)=2337376 :: (a3+1)=2337380 :: (a3+2)=2337384 :: (a3+3)=2337388 :: (a3+4)=2337392
(a2+0)=2337396 :: (a2+1)=2337400 :: (a2+2)=2337404 :: (a2+3)=2337408 :: (a2+4)=2337412
(a1+0)=2337416 :: (a1+1)=2337420 :: (a1+2)=2337424 :: (a1+4)=2337428 :: (a1+4)=2337432
我的问题是,我在a2和a3之前声明了a1。但是a1的地址位于之后 a3和a2。如果首先声明a1,它的地址应该具有a2和a3中的最小值,或者以不同的方式思考a1,a2和a3的地址之间应该没有关系。但是你可以看到在a3之后开始的a2的寻址,并且在a2之后开始寻址a1。为什么呢?
我使用的代码是:
#include<stdio.h>
int main()
{
int i,a1[]={1,2,3,4,5};
int *p1=a1;
printf("\n Addresses of 1st array:\n");
for( i=0;i<5;i++)
{
printf("%d ",(p1+i));
}
int a2[]={1,2,3,4,5};
int *p2=a2;
printf("\n Addresses of 2nd array:\n");
for( i=0;i<5;i++)
{
printf("%d ",(p2+i));
}
int a3[]={1,2,3,4,5};
int *p3=a3;
printf("\n Addresses of 3rd array:\n");
for( i=0;i<5;i++)
{
printf("%d ",(p3+i));
}
}
我得到的输出是:
Addresses of 1st array:
2337440 2337444 2337448 2337452 2337456
Addresses of 2nd array:
2337408 2337412 2337416 2337420 2337424
Addresses of 3rd array:
2337376 2337380 2337384 2337388 2337392
我正在使用CYGWIN编译器
答案 0 :(得分:3)
如何在C中完成数组的地址分配顺序?
该语言未指定如何分配不相关的数组。该语言要求单个数组中的项具有特定的地址序列。给定
int a[] = {10, 20, 30};
语言保证
a < a+1
a+1 < a+2
和
numerical value of (a+1) - numerical value of (a) == sizeof(int)
numerical value of (a+2) - numerical value of (a+1) == sizeof(int)
然而,鉴于
int a[] = {10, 20, 30};
int b[] = {100, 200, 300};
该语言不对a+1
和b+1
之间的关系做出承诺。编译器可以自由选择如何为a
和b
分配内存。
通过检查a
和b
元素的地址值,可以判断编译器如何为数组分配内存。但是,只有当您有兴趣了解编译器的工作原理时,才会感兴趣。作为该语言的常规用户,您不应该关注这些关系,并且绝对不会编写任何依赖于这些关系的程序。
答案 1 :(得分:0)
首先,您会混淆数组和指针。虽然它们在C中的表现非常相似,但它们并不是一回事。在您的示例中,您可以非常轻松地将数组分配给指针以便打印其地址,从而有效地进行转换。
这种区别的相关部分是当您通过以下方式定义数组时:
int a1[]={1,2,3,4,5};
a1
定义为整个数组的实际大小(即-5个整数)。 a1
没有自己的地址,并将其转换为指针实际上会给出其第一个元素的地址(即(int*)a1 == &a1[0]
)。
现在回答你的实际问题。在C上未定义堆栈上定义的顺序局部变量。它可能会像您期望的那样上升。它也可能会下降。它也可能是随机的。如果编译器决定从不同时使用两个变量,它甚至可以分配两个相同的地址。如果这不是一个普遍的理解问题,如果你想通过了解订单来实现某些目标,我最好的建议就是不要。
至于实际顺序:大多数平台上的堆栈,特别是英特尔,都在向下增长。这意味着考虑较低的地址&#34;稍后&#34;比更高的地址。你的编译器非常合理地将数组按顺序排列(即 - 向下增长)。
以上都不适用于单个数组的元素顺序。在单个数组中,元素的顺序是明确定义的,并且必须按升序排列。在这一点上,标准没有给予编译器任何余地,并且非常欢迎您依赖它(尽管我不明白你为什么要这样做)。这与我上面所说的并不矛盾,因为单个数组的所有元素都在堆栈上一起分配,因此内部排序没有超出我们赋予它们的含义。