为什么函数(char*array[])是有效的函数定义,而不是C中的(char(*array)[])?
我认为这是因为前者是指向char的指针数组,而后者是指向char数组的指针,我们需要为函数定义正确指定指向的对象的大小为什么函数(char*array[])是有效的函数定义,而不是C中的(char(*array)[])?,c,C,我认为这是因为前者是指向char的指针数组,而后者是指向char数组的指针,我们需要为函数定义正确指定指向的对象的大小 function(char * p_array[]) 指向的对象的大小已经包括在内(它是指向char的指针),但是后者 function(char (*p_array)[]) 需要将数组p_数组点的大小作为p_数组定义的一部分吗? 我现在正处于思考这个问题太久的阶段,我只是把自己弄糊涂了,请有人告诉我我的推理是否正确。因为 (1) function(char * p_arr
function(char * p_array[])
指向的对象的大小已经包括在内(它是指向char的指针),但是后者
function(char (*p_array)[])
需要将数组p_数组点的大小作为p_数组定义的一部分吗?
我现在正处于思考这个问题太久的阶段,我只是把自己弄糊涂了,请有人告诉我我的推理是否正确。因为
(1) function(char * p_array[])
相当于char**p_数组
;即有效的双指针
(2) function(char (*p_array)[])
您是对的,
p\u array
是指向char
array的指针。但是当它显示为函数参数时,需要具有固定的大小。您需要提供大小,并且该大小也将变为有效。在C中都是有效的,但不是C++。您通常是正确的:
char *x[]; // array of pointers to char
char (*y)[]; // pointer to array of char
但是,如果数组显示为函数参数,则会衰减为指针。因此,它们变成:
char **x; // Changes to pointer to array of pointer to char
char (*y)[]; // No decay, since it's NOT an array, it's a pointer to an array
在C中的数组类型中,允许未指定其中一个大小。这必须是最左边的一个(哎呀,我一开始说的是最右边的)。所以
(你可以把它们锁起来……但我们很少有理由这么做……)
有一个问题,问题是,其中包含[]
的数组类型是不完整的类型。您可以传递指向不完整类型的指针,但某些操作不起作用,因为它们需要完整的类型。例如,这不起作用:
void func(int (*x)[])
{
x[2][5] = 900; // Error
}
这是一个错误,因为为了找到x[2]
的地址,编译器需要知道x[0]
和x[1]
有多大。但是x[0]
和x[1]
有类型int[]
,这是一个不完整的类型,没有关于它有多大的信息。如果你想象该类型的“未衰减”版本为,即int x[][]
——显然是无效的C。如果您想在C中传递二维数组,您有几个选项:
- 传递带有大小参数的一维数组
void func(int n, int x[]) { x[2*n + 5] = 900; }
- 使用指向行的指针数组。如果你有真正的2D数据,这会有点笨重
void func(int *x[]) { x[2][5] = 900; }
- 使用固定尺寸
void func(int x[][5]) { x[2][5] = 900; }
- 使用可变长度数组(仅限C99,因此它可能不适用于Microsoft编译器)
当Q被标记为C++时,下面的答案被添加,并且它从C++的角度回答。标签被改变为只有C,两个样本在C.</P>中都是有效的。 是的,你的推理是正确的。
如果尝试编译,编译器给出的错误是:
parameter ‘p_array’ includes pointer to array of unknown bound ‘char []’
在编译时,C++的数组大小需要固定。C++标准也禁止可变长度数组(VLA)。一些编译器支持扩展,但这是非标准一致性。 < P>这两个声明非常不同。在函数参数声明中,<代码>直接应用于参数名的完全等同于一个*,因此您的第一个声明在所有方面都与此完全相同:
function(char **p_array);
但是,这不会递归地应用于参数类型。您的第二个参数的类型为char(*)[]
,它是指向未知大小数组的指针-它是指向不完整类型的指针。您可以愉快地使用此类型声明变量-以下是有效的变量声明:
char (*p_array)[];
就像指向任何其他不完整类型的指针一样,您不能在此变量(或函数参数)上执行任何指针运算-这就是错误产生的原因。请注意,[]
运算符被指定为a[i]
与*(a+i)相同
,因此运算符不能应用于指针。当然,您可以愉快地将其用作指针,因此这是有效的:
void function(char (*p_array)[])
{
printf("p_array = %p\n", (void *)p_array);
}
此类型还与指向任何其他固定大小的char
数组的指针兼容,因此您也可以执行以下操作:
void function(char (*p_array)[])
{
char (*p_a_10)[10] = p_array;
puts(*p_a_10);
}
…即使是这样:
void function(char (*p_array)[])
{
puts(*p_array);
}
(尽管这样做没有什么意义:您也可以使用类型char*
声明参数)
请注意,尽管允许使用
*p_数组
,但不允许使用p_数组[0]
。是(2)指向字符数组的指针或指向字符数组的函数指针?@Mahesh,第二个是指向字符数组的指针(但需要具有固定大小)。此外,字符数组是一种数据类型;我们不能让函数指针指向它。您可以指定为,char(*p)[3]=&a;
其中char a[3];
@iammilind:问题标题是“C"迪特里希编译:C++是一个C++语言,标题是C和C++,C++中的行为不同。C允许VLA而C++不允许。@克里斯:我道歉。我经常出错,使用编译器<代码> -PANANTIC-ANSI-WALW-WOTAU/COD>双重检查,如找到合适的T段。需要更多的时间。(适当的部分是n1570第6.7.6.2节和第6.7.6.3节,尽管您基本上必须阅读这两部分才能确定这是正确的。它们不是VLA,而是不完整类型的数组。VLA在C99中是新的,但不完整类型的数组与C本身一样古老。)这是关于C还是C++的问题?标题是“C”,但是标签都是“两个”,答案是不同的,这取决于你使用的是什么…@ Dietrich Epp -C和C++是不同的,但是TH是不同的。
void function(char (*p_array)[])
{
printf("p_array = %p\n", (void *)p_array);
}
void function(char (*p_array)[])
{
char (*p_a_10)[10] = p_array;
puts(*p_a_10);
}
void function(char (*p_array)[])
{
puts(*p_array);
}