C++中通过int**/char**获取二维数组大小可行吗?
关于C语言中int**/char**无法获取二维数组大小的问题解答
嗨,作为C语言新手碰到这个问题太正常啦,我来给你讲明白为什么你的代码得不到正确结果,以及到底能不能通过int** A获取二维数组的大小~
核心结论
仅靠int** A(或者char** A)是没办法直接获取二维数组的行列数的,你的代码之所以出错,本质是混淆了「数组」和「指针」在C语言中的区别,尤其是函数参数传递时的数组退化问题。
为什么你的代码得不到正确结果?
我们来拆解你写的这段代码:
int help(int** A){ int rows = sizeof(A)/sizeof(A[0]); int columns = sizeof(A[0])/sizeof(A[0][0]); }
当你把一个二维数组(或者指针数组)传给help函数时,参数A已经不是数组了,而是一个指向指针的指针变量。这是C语言的一个关键特性:数组作为函数参数传递时,会自动退化成指向其首元素的指针。
sizeof(A)得到的是指针变量本身的大小(比如64位系统是8字节,32位是4字节),而不是整个数组的总大小;A[0]是int*类型的指针,sizeof(A[0])同样是指针的大小,所以sizeof(A)/sizeof(A[0])的结果永远是1(比如8/8=1),根本不是你想要的行数;- 同理,
sizeof(A[0][0])是int的大小,但你不知道A[0]指向的数组有多少个元素,所以columns的计算也是错误的。
要搞清楚的两个概念:二维数组 vs 指针数组
你可能还混淆了这两个容易搞混的结构:
- 真正的二维数组:比如
int arr[3][4],它在内存中是连续存储的3行4列的int数据。当它作为参数传递时,会退化成int (*)[4](指向包含4个int的数组的指针),而不是int**——这两种指针类型是不兼容的,编译器可能会给你警告。 - 指针数组:比如
int* arr[3],每个元素是一个指向int的指针,每个指针可以指向不同长度的int数组。它作为参数传递时会退化成int**,但此时你依然无法通过int**知道这个指针数组有多少个元素(即行数),也没法知道每个指针指向的数组长度(列数)。
那怎么才能在函数里获取数组大小?
通常有两种靠谱的解决方案:
- 方案一:额外传递行列数参数
直接把行数和列数作为参数传给函数,这是最通用、最清晰的做法,不管是二维数组还是指针数组都适用:void help(int** A, int rows, int cols) { // 直接用rows和cols操作数组即可 } - 方案二:针对固定列数的二维数组使用数组参数
如果你的二维数组列数是编译期固定的,可以用带列数的数组参数,这样能通过sizeof获取列数:#define COLS 4 void help(int A[][COLS], int rows) { int columns = sizeof(A[0])/sizeof(A[0][0]); // 这里能得到4,因为A[0]是int[4]类型 // rows是传入的参数,直接用 }
char**的情况同理
char**本质也是指向指针的指针,和int**完全一样:没法从这个指针本身获取它指向的指针数组的长度,也没法知道每个指针指向的字符数组的长度。如果要操作char**类型的结构,同样需要额外传递行数(以及每个字符串的长度,或者依赖字符串以'\0'结尾来判断长度)。
内容的提问来源于stack exchange,提问作者jd_sal
相关产品推荐
相关产品推荐

