今日被摆了一道,多级指针传参过程中丢失了数组信息。惭愧惭愧啊,仔细翻书,总算明白,所以在这里记下先。
首先,c语言中只有一维数组,所谓的多维数组也是用一维数组来模拟的。
其次,很多时候数组可以用指针操作的互换,但是数组并不等于指针。
如下代码:
void foo(char **** temp)
{
char * a[10][20] = {NULL};
// 这里a实际上是代表一个数组,并不是指针,是一个包含10个元素的一维数组
// 每个元素的类型是:有20个char*元素的数组
// 但是除了在sizeof这样的操作符中做转换之外,a可以自动被转换成a数组第一个元素的指针
// 在这里这个指针并不是普通的指针,而是指向char * [20]数组的指针,
// 这里可以把数组看成一种特殊的类型。
// 所以下面的语句编译会无法通过
(*temp) = a;
// 我们可以这样定义一个数组变量
char * (*p)[20];
// 这里p是一个包含20个char*元素的数组类型的变量,而不是多个变量元素的数组
// 下面的赋值是正确的
p = a;
// 而对于a[i],可以同样的推理知道,a[i]是a数组的第i个元素,由于a数组的元素是数组
// 所以这里a[i]也是表示数组,也是在很多时候会自动转换成指向a[i]数组第一个元素的指针
// 由于a[i]是一个包含20个char*的数组,所以a[i]的第一个元素是char*,
// 所以a[i]可以自动转换成char**
// 下面的编译可以通过
(**temp) = a[0];
(***temp) = a[0][0];
// 而这样的代码则无法通过编译,因为这里右边得到的是一个指向数组的指针
(*temp) = &(a[0]);
// 可以这样写
p = &(a[0]);
}
因此,在函数传递参数的过程中,尽量不要使用多维的数组进行传递,因为在传递的过程中会丢失数组的
信息,对于用一维来模拟多维数组的C语言来说,这种信息是只有编译器才知道的,隐式的,我们无法
通过显示的方法来获得,较为可行的就是避免它。