C 关于指针和多维数组的混淆
如果可能的话:C 关于指针和多维数组的混淆,c,pointers,multidimensional-array,C,Pointers,Multidimensional Array,如果可能的话: MyFunction(int *array, int size) { for(int i=0 ; i<size ; i++) { printf(“%d”, array[i]); } } main() { int array[6] = {0, 1, 2, 3, 4, 5}; MyFunction(array, 6); } MyFunction(int*array,int size) { 对于(int i=0;i,因为
MyFunction(int *array, int size)
{
for(int i=0 ; i<size ; i++)
{
printf(“%d”, array[i]);
}
}
main()
{
int array[6] = {0, 1, 2, 3, 4, 5};
MyFunction(array, 6);
}
MyFunction(int*array,int size)
{
对于(int i=0;i,因为指针与数组指针的类型不同。有关详细信息,请参阅
此外,这还有一些好信息:编辑:以下是我根据您的新示例代码,根据您的要求,尝试给出更切题的答案:
不管数组的维度如何,您传递的是一个“指向数组的指针”——它只是一个指针,尽管指针的类型可能会有所不同
在第一个示例中,int数组[6]
是由6个int
元素组成的数组。传递array
会传递指向第一个元素的指针,该元素是int
,因此参数类型为int*
,可以等效地写为int[]
在第二个示例中,int数组[3][3]
是一个由3行(元素)组成的数组,每个行(元素)包含3个int
s。传递array
将指针传递到第一个元素,该元素是一个由3个int
s组成的数组。因此类型为int(*)[3]
-指向由3个元素组成的数组的指针,可以等价地写成int[][3]
我希望您现在看到区别。当您传递int**
时,它实际上是指向int*
s数组的指针,而不是指向2D数组的指针
实际的int**
示例如下:
int a[3] = { 1, 2, 3 };
int b[3] = { 4, 5, 6 };
int c[3] = { 7, 8, 9 };
int *array[3] = { a, b, c };
这里的array
是一个由3个int*
s组成的数组,将其作为参数传递将导致int**
原始答案:
第一个示例不是真正的2D数组,尽管它的使用方式类似。在这里,您创建了行
个char*
指针,每个指针指向不同的col
字符数组。这里有两个间接级别
第二个和第三个示例实际上是2D数组,其中整个行*COLS
字符的内存是连续的。这里只有一个间接级别。指向2D数组的指针不是char**
,而是char(*)[COLS]
,因此可以执行以下操作:
char (*p)[SIZE] = arr;
// use p like arr, eg. p[1][2]
第一个示例是可能的,因为数组作为函数参数传递时会退化为指针
第二个示例不起作用,因为int[3][3]
退化为int(*)[3],不是双指针<代码> int *>代码>。这是因为2D数组在内存中是连续的,如果没有这些信息,编译器就不知道如何访问第一行的元素。考虑一个简单的数字网格:
1 2 6
0 7 9
如果我们将这些数字存储在数组int nums[6]
,我们将如何索引到数组中以访问元素7?当然,通过1*3+1
,或者更一般地说,通过row*num columns+column
。为了访问超过第一行的任何元素,您需要知道网格有多少列
当您将数字存储为nums[2][3]
,编译器使用完全相同的row*num columns+column
算法,就像您手动使用1D数组一样,它只是对程序员隐藏。因此,在传递2D数组时必须传递列数,以便编译器能够执行此算法
在许多其他语言中,数组携带有关其大小的信息,因此在将多维数组传递给函数时无需手动指定维度。如果您想得到更为切中要害的答案,或许我们可以期待一个更为“切中要害”的问题。您的想法有两个问题:
二维数组int a[3][3]
使用时
在一个表达式中衰减为
其第一个元素的地址
类型为int(*)[3]
的指针。要通过数组,必须使用&a[0][0]
获取指向第一个“内部”成员的指针
在你的职能范围内进行操作
A[i][j]
无法执行,因为
您的编译器没有有关的信息
行的长度,在那里
其他人已经大致总结了这一点。
int**A表示A是指向数组的指针,而不是对二维数组的引用。
但是,这并不意味着它不可用。因为C中的数据是按行的主要顺序存储的,一旦知道行的长度,检索数据应该很容易。这段代码有两个主要问题
MyFunction(int **array, int row, int col);
第一个是int**array
使用的类型错误。这是指向指针的指针,而
int array[3][3] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
是多维数组。组成该多维数组的内存都是一个块,从该块的开头到该数组的任何元素的偏移量都是根据对该数组中行的大小的了解来计算的
int *A[99];
这是一个指向整数的指针数组。指向的整数可以是内存中几个整数中的第一个,这意味着它们实际上指向整数数组
在许多情况下,当您在程序中使用数组名称时,它的计算结果是指向数组开头的指针。如果您说:
int array[3][3] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
printf("%p %p %p\n", array, array[0], &(array[0][0]) );
int **A;
您应该打印3次相同的地址,因为它们都引用相同的地址,但它们的类型不同。后两次的数据类型相似,并且在许多方面兼容,因为array[0]
将被视为指向数组第一行的第一个元素的指针,而这一行本身就是一个数组
如果你说:
int array[3][3] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
printf("%p %p %p\n", array, array[0], &(array[0][0]) );
int **A;
您的意思是有一个指向int
的指针。虽然a[2][4]
是一个有效的表达式,但这不是一个多维数组,其方式与:
int B[3][3];
如果你说A[1]
,这将计算为一个int*
,类似于B[1]
,除了你可以说A[1]=(int*)0x4444;
,但是如果
int myarray[3][3];
MyFunction(myarray, 3, 3);
int MyFunction(int (*array)[3], int row, int col)
void MyFunction(int *arr, int row, int col)
{
int i, j;
for (i = 0; i < row; i++)
for (j = 0; j < col; j++)
printf("%d", a[i*col+j]);
}
int main(void)
{
int myarray[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
...
MyFunction(&myarray[0][0], 3, 3);
void AnotherFunc(int **arr, int row, int col)
{
int i, j;
for (i = 0; i < row; i++)
for (j = 0; j < col; j++)
printf("%d", arr[i][j]);
}
int main(void)
{
int d0[3] = {1, 2, 3};
int d1[3] = {4, 5, 6};
int d2[3] = {7, 8, 9};
int *a[3] = {d0, d1, d2};
AnotherFunc(a, 3, 3);
...
}
Declaration Expression Type Implicitly Converted (Decays) to
----------- ---------- ---- --------------------------------
T a[N] a T [N] T *
&a T (*)[N]
*a T
a[i] T
T a[M][N] a T [M][N] T (*)[N]
&a T (*)[M][N]
*a T [N] T *
a[i] T [N] T *
&a[i] T (*)[N]
*a[i] T
a[i][j] T
T a[L][M][N] a T [L][M][N] T (*)[M][N]
&a T (*)[L][M][N]
*a T [M][N] T (*)[N]
a[i] T [M][N] T (*)[N]
&a[i] T (*)[M][N]
*a[i] T [N] T *
a[i][j] T [N] T *
&a[i][j] T (*)[N]
*a[i][j] T
a[i][j][k] T