数组[行][COLS]和**数组之间有什么区别

数组[行][COLS]和**数组之间有什么区别,c,C,为什么这些函数原型不是等价的 void print_matrix(char *name, int SX, int SY, int m[SX][SY]) void print_matrix(char *name, int SX, int SY, int **m) 尽管这两个函数参数可以以相同的方式使用,即通过m[i][j],但它们完全不同: void g(int **p); int a; int * pa = &a; g(&pa); // fine, po

为什么这些函数原型不是等价的

void print_matrix(char *name, int SX, int SY, int m[SX][SY])

void print_matrix(char *name, int SX, int SY, int **m)

尽管这两个函数参数可以以相同的方式使用,即通过
m[i][j]
,但它们完全不同:

void g(int **p);

int a;
int * pa = &a;

g(&pa);          // fine, pointer to 'pa'

int arr[M][N];

// g(arr);  // Error, makes no sense
  • int m[m][N]
    m
    数组中的
    N
    整数

  • int**m
    是指向int的指针

不能将数组作为函数参数传递,因此“类型为
T
K
元素数组”将衰减为“指向-
T
”的指针,指向数组的第一个元素。因此,由于值
m
丢失,因此允许并等效于在函数参数中写入第一个形式为
int m[][N]
。但是,值
N
没有丢失;这是类型的一部分

因此,对于第一种形式,以下内容是可接受的/错误的:

void f(int arr[M][N]);

int a[M][N];
int b[2*M][N];
int c[M][N + 1];

f(a);   // OK
f(b);   // OK; slowest extent is forgotten in the decay
//f(c); // Error! 'c' is not an array of {array of N ints}.
对于第二种形式,含义相当不同:

void g(int **p);

int a;
int * pa = &a;

g(&pa);          // fine, pointer to 'pa'

int arr[M][N];

// g(arr);  // Error, makes no sense
表达式
arr
指定指向
N
整数数组的第一个元素的指针,即其类型为
int(*)[N]
。解引用它会给出一个
N
整数数组,而不是指向整数的指针

无法将表达式
arr
转换为指向指针的指针:如果您说

int ** fool = (int**)arr;
然后
*dool
将指向第一个数组的第一个元素(
arr[0]
),而不是
int
指针。因此,不能进一步取消对该值的引用,因为该值不是指针

将二维数组作为双指针传递的唯一正确方法是构造中间辅助数组:

int * helper[M];   // array of pointers

for (size_t i = 0; i != M; ++i)
{
    helper[i] = arr[i]; // implicit decay
}

g(helper);  // or "g(&helper[0])"

尽管这两个函数参数可以以相同的方式使用,即通过
m[i][j]
,但它们完全不同:

void g(int **p);

int a;
int * pa = &a;

g(&pa);          // fine, pointer to 'pa'

int arr[M][N];

// g(arr);  // Error, makes no sense
  • int m[m][N]
    m
    数组中的
    N
    整数

  • int**m
    是指向int的指针

不能将数组作为函数参数传递,因此“类型为
T
K
元素数组”将衰减为“指向-
T
”的指针,指向数组的第一个元素。因此,由于值
m
丢失,因此允许并等效于在函数参数中写入第一个形式为
int m[][N]
。但是,值
N
没有丢失;这是类型的一部分

因此,对于第一种形式,以下内容是可接受的/错误的:

void f(int arr[M][N]);

int a[M][N];
int b[2*M][N];
int c[M][N + 1];

f(a);   // OK
f(b);   // OK; slowest extent is forgotten in the decay
//f(c); // Error! 'c' is not an array of {array of N ints}.
对于第二种形式,含义相当不同:

void g(int **p);

int a;
int * pa = &a;

g(&pa);          // fine, pointer to 'pa'

int arr[M][N];

// g(arr);  // Error, makes no sense
表达式
arr
指定指向
N
整数数组的第一个元素的指针,即其类型为
int(*)[N]
。解引用它会给出一个
N
整数数组,而不是指向整数的指针

无法将表达式
arr
转换为指向指针的指针:如果您说

int ** fool = (int**)arr;
然后
*dool
将指向第一个数组的第一个元素(
arr[0]
),而不是
int
指针。因此,不能进一步取消对该值的引用,因为该值不是指针

将二维数组作为双指针传递的唯一正确方法是构造中间辅助数组:

int * helper[M];   // array of pointers

for (size_t i = 0; i != M; ++i)
{
    helper[i] = arr[i]; // implicit decay
}

g(helper);  // or "g(&helper[0])"

嘿,伙计们,我们不要太挑剔@richard了——他可能没有做向下投票。我自己也忘记了C对于局部变量和参数类型有不同的规则。还有弗拉斯的问题。你不能指望richard会欣赏所有这些微妙之处。对不起,我起初以为你对这个问题改变太多了,你想让它回到原来的问题。我已经删除了那些过时的评论,但是你对这个问题有了一个很好的答案,所以一切都解决了。在未来,与其对一个完全改变其含义的问题做出戏剧性的改变,不如让它保持原样,在新的话题上提出一个新的问题。嘿,伙计们,我们不要太挑剔@richard——他可能没有做向下投票。我自己也忘记了C对于局部变量和参数类型有不同的规则。还有弗拉斯的问题。你不能指望richard会欣赏所有这些微妙之处。对不起,我起初以为你对这个问题改变太多了,你想让它回到原来的问题。我已经删除了那些过时的评论,但是你对这个问题有了一个很好的答案,所以一切都解决了。在未来,与其对一个完全改变其含义的问题做出戏剧性的改变,不如干脆别管它,在新的话题上提出一个新的问题。