我在编写带有矩阵的程序时遇到了这个问题,我曾经int** m
声明过我的矩阵-因为我需要动态分配和使用的函数int a[][]
。我不记得有任何问题。但是当我使用一个简单的m[6][6]
矩阵时,f(int**m, int** m2, rest params)
我遇到了麻烦。
它编译了,当我运行程序(带有GCC的代码块)时,它刚刚崩溃了。我尝试通过添加printf()
s进行调试if()
,它在没有崩溃的块处崩溃。将第一个函数参数从修改int a[][]
为int* a[6]
并继续运行,稍后修改了第二个参数,并且我的程序进行了第一次尝试。通过更仔细的调试,我可以保存int m[i][j]
并检查是否为垃圾值,而不是我要放入的内容,这只是在放置1
或0
标记某些东西。
这些年来,除非我在执行此类操作时遇到GCC编译器错误,否则我将只写第一种想到的方法。
在所有4种组合中使用int**
和int [][]
声明变量/获取函数参数的背后的逻辑是什么?我int**
在函数头中使用的大多数预定义函数。
我知道int [][]
这不等于int**
,它是int* []
正确的,但是我想念的是什么?int[][]
是一个多维数组,表示数组的数组,所有3种编写方式都相同。而且因为int[][]
它几乎总是要求只让第一个参数为空,就像int array[][][][]
我需要将int数组a[][n1][n2][n3]
放入函数参数中,对吗?它需要知道除第一个数组之外的多维数组的维数,因为在声明函数参数时可以毫无问题地使用int*
和int[]
?
C和C ++之间
int **a
以及int a[][]
作为函数参数的确切区别是什么?
int *a
。这是一个指向int的指针。
int **a
。这是一个指向int的指针。
int a[]
在所有其他上下文中,这将是未指定数量的int数组,但是作为函数参数声明符,它被调整为int的指针,在这种情况下,它与您编写的相同int *a
。
int a[][]
这将是未指定数目的数组,未指定整数数目的数组,但是这种类型格式错误,因为array元素不能是未指定大小的数组。
int *a[]
在所有其他上下文中,这将是未指定数量的int指针的数组,但是作为函数参数声明符,它被调整为指向int的指针,即在这种情况下,与您编写的相同int **a
。
int (*a)[N]
这是指向N个整数的数组的指针。
int a[][N]
在所有其他上下文中,这将是未指定数量的N个int数组的数组,但是作为函数参数声明符,它被调整为指向N个int数组的指针,即在这种情况下,它与您编写的相同int (*a)[N]
。
一些例子:
void fun_1D(int*); // argument is pointer to int
void fun_1D(int[]); // same as above
void fun_1D(int[10]); // same as above; note that 10 is ignored
int arr_1D[20]; // array of int
fun_1D(arr_1D); // implicit conversion
fun_1D(&arr_1D[0]); // same as above
void fun_2D(int (*)[20]); // note that 20 is not ignored
void fun_2D(int[][20]); // same as above
void fun_2D(int[10][20]); // same as above; note that 10 is ignored
int arr_2D[20][20]; // array of array of int
fun_2D(arr_2D); // implicit conversion
fun_2D(&arr_2D[0]); // same as above
fun_1D(arr_2D[i]); // implicit conversion
fun_1D(&arr_2D[i][0]); // same as above
void fun_ptrs(int**); // argument is pointer to pointer to int
void fun_ptrs(int*[]); // same as above
void fun_ptrs(int*[10]); // same as above; note that 10 is ignored
int *arr_ptr[20]; // array of pointers
fun_ptrs(arr_ptr); // implicit conversion
fun_ptrs(&arr_ptr[0]); // same as above
fun_1D(arr_ptr[i]); // no conversion needed
// broken examples
fun_2D(arr_ptr); // int*[20] is not int(*)[20]
fun_ptrs(arr_2D); // int[20][20] is not int**
请注意,如何将声明为数组的函数参数调整为与左值到右值转换时数组将衰减到的指针类型相同的指针类型。
需要记住的一些简单经验法则:
如果我在main中声明int a [6] [6]并调用需要int ** a的函数,那么它会起作用吗?
不,因为int[6][6]
不是int**
,它也不衰减为一。int[6][6]
衰减到int(*)[6]
如上所述。int(*)[6]
并且int**
不能互相转换。一个是指向数组的指针,另一个是指向指针的指针。
反过来
否,因为int[6][6]
参数已调整为int(*)[6]
。为何不兼容,请参见上一段。
似乎
int a[][]
不被接受
正确。正如我在顶部的第四段中所解释的(不包括引号)。
如果我有函数f1(int * a)和f2(int a [])和f2(int a [6]),在这些情况下,sizeof(a)返回什么?
如上所述,所有这些都声明了type的参数int*
。sizeof a
就是sizeof(int*)
因为那是类型。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句