在C,我知道可以用下面的代码动态地分配在堆上的二维数组:

int** someNumbers = malloc(arrayRows*sizeof(int*));

for (i = 0; i < arrayRows; i++) {
    someNumbers[i] = malloc(arrayColumns*sizeof(int));
}

显然,这实际上创建指针的一维阵列一堆整数单独的一维阵列,和“系统”可以找出我的意思是当我要求:

someNumbers[4][2];

但是,当我声明静态的2D阵列,如下面的线...

int someNumbers[ARRAY_ROWS][ARRAY_COLUMNS];

...没有类似的结构得到在堆栈上创建的,或者是它的另一种形式的完全? (即是它的指针一维数组?如果不是,它是什么,以及如何引用它得到想通了?)

此外,当我说,“系统”,什么是真正的负责搞清楚了这一点?内核?抑或是C编译器把它清除出来,而编译?

有帮助吗?

解决方案

一个静态二维阵列看起来像一个数组的数组 - 它只是在存储器布局连续。数组是不一样的东西作为指针,而是因为你可以经常使用他们几乎可以互换它可以变得混乱,有时。编译器会跟踪正常,虽然,这使得一切都排队很好。你必须要小心静态二维数组就像你提到的,因为如果你试图通过一个采取一个int **参数,不好的事情将要发生的功能。下面是一个简单示例:

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

在存储器看起来像这样:

0 1 2 3 4 5

<强>准确相同:

int array2[6] = { 0, 1, 2, 3, 4, 5 };

但是,如果你尝试通过array1这个功能:

void function1(int **a);

你会得到一个警告(和应用程序将无法正常访问数组):

warning: passing argument 1 of ‘function1’ from incompatible pointer type

由于2D阵列是不一样的int **。数组的自动衰减成一个指针仅变为“一层深”可以这么说。您需要声明函数为:

void function2(int a[][2]);

void function2(int a[3][2]);

为使一切快乐。

此相同的概念延伸到名词维阵列。趁着这种不道德的行为的应用程序中一般只就更难理解,虽然。所以,要小心在那里。

其他提示

答案是基于这样的思想:C没有真正的的二维数组 - 它有数组-的阵列。当你声明如下:

int someNumbers[4][2];

您所要求的someNumbers是4个元素的阵列,其中该阵列的每个元素是类型int [2]的(它本身的2个ints阵列)。

拼图的另一部分是,数组总是在存储器布局连续。如果你问:

sometype_t array[4];

然后,将始终是这样的:

| sometype_t | sometype_t | sometype_t | sometype_t |

(4 sometype_t对象之间布置彼此相邻,没有空格)。因此,在您someNumbers阵列阵列的-,它会是这样的:

| int [2]    | int [2]    | int [2]    | int [2]    |

和每个int [2]元件本身是一个阵列,看起来像这样:

| int        | int        |

所以,总体来说,你得到这样的:

| int | int  | int | int  | int | int  | int | int  |
unsigned char MultiArray[5][2]={{0,1},{2,3},{4,5},{6,7},{8,9}};

在存储器等于:

unsigned char SingleArray[10]={0,1,2,3,4,5,6,7,8,9};

在回答你的也:两者虽然编译器做最繁重的工作。

在静态分配阵列的情况下,“系统”将是编译器。它会预留存储器像它会为任何堆栈变量。

在malloc分配阵列的情况下,“系统”将是的malloc实施者(内核通常)。所有的编译器将分配是基指针。

在编译器总是要处理的类型,因为他们宣布什么是除了在卡尔给了它可以找出互换使用的例子。这就是为什么如果在[] []传送给函数它必须假定它是静态分配的平面,其中**假定为指针的指针。

要访问一个特定的2D阵列考虑为一个数组声明存储器映射中所示代码如下:

    0  1
a[0]0  1
a[1]2  3

要访问的每个元素,其足以只传递你有兴趣作为参数,其功能阵列。然后使用偏移对每个元素单独列的访问。

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

void f1(int *ptr);

void f1(int *ptr)
{
    int a=0;
    int b=0;
    a=ptr[0];
    b=ptr[1];
    printf("%d\n",a);
    printf("%d\n",b);
}

int main()
{
   f1(a[0]);
   f1(a[1]);
    return 0;
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top