2d数组是双指针吗?

时间:2011-09-28 16:48:38

标签: c multidimensional-array

int main()
{
    matrix[2][4] = {{11,22,33,99},{44,55,66,110}};
    int **ptr = (int**)matrix;
    printf("%d%d",**matrix,*ptr);
}

但是当一个二维数组作为参数传递时,它被转换为(*矩阵)[2]。 编译器将这个数组存储为什么类型...是存储为2-d数组还是双指针或指向数组的指针。如果它作为数组存储,它在不同的情况下如何解释不同的情况。请帮我理解。

4 个答案:

答案 0 :(得分:38)

  

2d数组是否为双指针?

没有。你的程序的这一行不正确:

int **ptr = (int**)matrix;

This answer deals with the same topic

如果你想要具体的图像如何实现多维数组:

多维数组的规则与普通数组的规则没有什么不同,只是将“内部”数组类型替换为元素类型。数组项直接相继存储在内存中:

matrix: 11 22 33 99 44 55 66 110
        -----------               the first element of matrix
                    ------------  the second element of matrix

因此,要解决元素matrix[x][y],请使用the base address of matrix + x*4 + y(4是内部数组大小)。

当数组传递给函数时,它们会衰减到指向第一个元素的指针。如你所知,这将是int (*)[4]。然后,类型中的4将告诉编译器内部类型的大小,这就是它工作的原因。在对类似指针执行指针运算时,编译器会添加元素大小的倍数,因此对于matrix_ptr[x][y],您得到matrix_ptr + x*4 + y,这与上面的完全相同。

演员ptr=(int**)matrix因此不正确。一次,*ptr表示存储在矩阵地址的指针值,但没有。其次,在程序的内存中没有指向matrix[1]的指针。

注意:本文中的计算假定为sizeof(int)==1,以避免不必要的复杂性。

答案 1 :(得分:10)

没有。多维数组是单个内存块。块的大小是尺寸乘以元素类型的大小的乘积,并且每对括号中的索引通过剩余尺寸的尺寸的乘积偏移到阵列中。所以..

int arr[5][3][2];

是一个包含30 int s的数组。 arr[0][0][0]给出第一个,arr[1][0][0]给出第七个(偏移量为3 * 2)。 arr[0][1][0]给出第三个(偏移量为2)。

数组衰减的指针将取决于级别; arr衰减到指向3x2 int数组的指针,arr[0]衰减到指向2元素int数组的指针,而arr [0] [0]衰减到指向int的指针。

但是,您也可以拥有一个指针数组,并将其视为多维数组 - 但它需要一些额外的设置,因为您必须将每个指针设置为其数组。此外,您丢失了有关数组中数组大小的信息(sizeof将给出指针的大小)。另一方面,您可以使用不同大小的子数组并更改指针指向的位置,这在需要调整大小或重新排列时非常有用。像这样的指针数组可以像多维数组一样被索引,即使它的分配和排列方式不同,sizeof也不会总是以相同的方式表现。这种设置的静态分配示例是:

int *arr[3];
int aa[2] = { 10, 11 }, 
    ab[2] = { 12, 13 }, 
    ac[2] = { 14, 15 };
arr[0] = aa;
arr[1] = ab;
arr[2] = ac;

完成上述操作后,arr[1][0]12。但是,不是将int 1 * 2 * sizeof(int)字节超过数组arr的起始地址,而是在int字节处找到的0 * sizeof(int)超过地址由arr[1]指出。此外,sizeof(arr[0])相当于sizeof(int *)而非sizeof(int) * 2

答案 2 :(得分:2)

在C中,理解多维数组并不需要特别了解。它们的工作方式与从未特别提及的方式完全相同。您需要知道的是,您可以创建任何类型的数组,包括数组。

所以当你看到:

  

int matrix [2] [4];

试想一下,“matrix是一个由2个东西组成的数组 - 这些东西是4个整数的数组”。适用于数组的所有常规规则。例如,matrix可以很容易地衰减成指向其第一个成员的指针,就像任何其他数组一样,在本例中是一个包含四个整数的数组。 (当然,这可能会腐烂。)

答案 3 :(得分:0)

如果您可以将堆栈用于该数据(小体积),那么您通常会定义矩阵:

int matrix[X][Y]

如果要在堆中分配(大容量),通常会定义:

int** matrix = NULL;

然后使用malloc / calloc分配两个维度。 您可以将2d数组视为int **,但这不是一个好习惯,因为它会降低代码的可读性。除此之外

**matrix == matrix[0][0] is true