array [ROWS] [COLS]和**数组有什么区别

ric*_*ard 1 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)
Run Code Online (Sandbox Code Playgroud)

Ker*_* SB 6

尽管这两个函数的参数可以被消耗以同样的方式,通过即m[i][j],他们是完全不同的:

  • int m[M][N]是一组int 的M数组N.

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

您不能将数组作为函数参数传递,因此" K类型的元素数组T"会衰减为"指针指向T",指向数组的第一个元素.因此,允许和等效于int m[][N]在函数参数中写入第一个表单,因为该值M丢失.然而,该值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}.
Run Code Online (Sandbox Code Playgroud)

对于第二种形式,含义相当不同:

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
Run Code Online (Sandbox Code Playgroud)

表达式arr指定指向N整数数组数组的第一个元素的指针,即其类型为int (*)[N].取消引用它会给出一个N整数数组,而不是一个指向整数的指针.

没有办法将表达式arr转换为指针指针:如果你说,

int ** fool = (int**)arr;
Run Code Online (Sandbox Code Playgroud)

然后*fool指向第一个数组(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])"
Run Code Online (Sandbox Code Playgroud)