如何多维数组在内存格式化?
-
23-09-2019 - |
题
在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个int
s阵列)。
拼图的另一部分是,数组总是在存储器布局连续。如果你问:
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;
}