在 C 中,我知道我可以使用以下代码在堆上动态分配一个二维数组:
int** someNumbers = malloc(arrayRows*sizeof(int*)); for (i = 0; i < arrayRows; i++) { someNumbers[i] = malloc(arrayColumns*sizeof(int)); }
显然,这实际上创建了一个指向一组单独的一维整数数组的指针的一维数组,当我要求时,“系统”可以弄清楚我的意思:
someNumbers[4][2];
但是当我静态声明一个二维数组时,如下行…:
int someNumbers[ARRAY_ROWS][ARRAY_COLUMNS];
…是否在堆栈上创建了类似的结构,或者它完全是另一种形式?(即它是一维指针数组吗?如果不是,它是什么,以及如何计算出对它的引用?)
另外,当我说“系统”时,究竟是什么负责解决这个问题?内核?还是C编译器在编译时对其进行排序?
静态二维数组看起来像一个数组数组——它只是在内存中连续布局。数组与指针不同,但因为您经常可以互换使用它们,所以有时会让人感到困惑。但是,编译器会正确跟踪,这使得一切都很好。你必须小心你提到的静态二维数组,因为如果你尝试将一个传递给一个带int **参数的函数,就会发生不好的事情。这是一个简单的例子:
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给这个函数:
array1
void function1(int **a);
你会得到一个警告(应用程序将无法正确访问数组):
warning: passing argument 1 of 鈥榝unction1鈥� from incompatible pointer type
因为二维数组与int **. 可以说,数组自动衰减为指针只会“深一层”。您需要将函数声明为:
void function2(int a[][2]);
或者
void function2(int a[3][2]);
让一切快乐。
同样的概念扩展到 n 维数组。但是,在您的应用程序中利用这种有趣的业务通常只会使其更难理解。所以在外面要小心。