Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 关于指针和多维数组的混淆_C_Pointers_Multidimensional Array - Fatal编程技术网

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