如何在C中完成自动数组的排序?

时间:2016-06-17 05:27:20

标签: c arrays pointers cygwin

假设我有三个数组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编译器

2 个答案:

答案 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+1b+1之间的关系做出承诺。编译器可以自由选择如何为ab分配内存。

通过检查ab元素的地址值,可以判断编译器如何为数组分配内存。但是,只有当您有兴趣了解编译器的工作原理时,才会感兴趣。作为该语言的常规用户,您不应该关注这些关系,并且绝对不会编写任何依赖于这些关系的程序

答案 1 :(得分:0)

首先,您会混淆数组和指针。虽然它们在C中的表现非常相似,但它们并不是一回事。在您的示例中,您可以非常轻松地将数组分配给指针以便打印其地址,从而有效地进行转换。

这种区别的相关部分是当您通过以下方式定义数组时:

int a1[]={1,2,3,4,5};

a1定义为整个数组的实际大小(即-5个整数)。 a1没有自己的地址,并将其转换为指针实际上会给出其第一个元素的地址(即(int*)a1 == &a1[0])。

现在回答你的实际问题。在C上未定义堆栈上定义的顺序局部变量。它可能会像您期望的那样上升。它也可能会下降。它也可能是随机的。如果编译器决定从不同时使用两个变量,它甚至可以分配两个相同的地址。如果这不是一个普遍的理解问题,如果你想通过了解订单来实现某些目标,我最好的建议就是不要

至于实际顺序:大多数平台上的堆栈,特别是英特尔,都在向下增长。这意味着考虑较低的地址&#34;稍后&#34;比更高的地址。你的编译器非常合理地将数组按顺序排列(即 - 向下增长)。

以上都不适用于单个数组的元素顺序。在单个数组中,元素的顺序是明确定义的,并且必须按升序排列。在这一点上,标准没有给予编译器任何余地,并且非常欢迎您依赖它(尽管我不明白你为什么要这样做)。这与我上面所说的并不矛盾,因为单个数组的所有元素都在堆栈上一起分配,因此内部排序没有超出我们赋予它们的含义。