为什么我不能将指向固定大小数组的指针的地址传递给期望指向C中指针的函数?

时间:2017-10-21 13:48:57

标签: c pointers

我有以下(看似无辜)的代码:

void singleLeftPadZero(char**);
int main () {
  char foo[10] = "0";

  singleLeftPadZero(foo); // <-- causes warning
  singleLeftPadZero(&foo); // <-- same exact warning, but different "note"
}

我从gcc收到的警告是:

  

警告:传递'singleLeftZeroPad'的参数1不兼容   指针类型

第一个案例的注释是:

  

注意:预期'char **'但参数类型为'char *'

我理解这意味着我需要将指针传递给指针,但我只是传递一个指针。因此,我添加了&#34;&amp;&#34;我的论点引起了同样的警告,但是这个说明:

  

注意:预期'char **'但参数类型为'char(*)[10]'

我做了什么看起来修复它是为了创建一个额外的变量: char* fooPntr = foo; 然后将该地址作为函数参数传递: singleLeftPadZero(&fooPntr);但我不确定为什么会有效!

2 个答案:

答案 0 :(得分:1)

数组名foo衰减为char *,这是一个指向foo第一个元素的字符指针。它不是char **,它是指向指向内存位置的字符指针的字符指针。

你的数组是单维的。所以char *将你的函数原型修改为

void singleLeftPadZero(char*);

当数组名称衰减为指向数组第一个元素的指针时,foo本身就是一个给出一个地址。所以&foo表示指向10个元素数组的指针的地址,因此消息argument is of type ‘char (*)[10]’

char (*)[10]表示指向10个元素数组的字符指针。

虽然数组名称衰减为指针,但指针和数组并不相同。看here

答案 1 :(得分:1)

你错误地认为指针和数组是相同的东西。他们不是。在某些情况下,它们可以以相同的方式使用(这与说“它们是同一个东西”完全不同),而不是其他情况。您的示例位于上下文中,指针和数组是不同的东西,不能像使用它们一样使用。

在第一种情况下,将foo传递给singleLeftPadZero()首先执行“数组到指针转换” - foo是一个十char的数组,并且转换为char *类型的指针,其值等于&foo[0]char *不是char **,因此会出现关于不兼容类型和注释的警告。

在第二种情况下,将&foo传递给singleLeftPadZero()不会进行转换。相反,&foo的类型为“指向10 char数组的指针”,或者(与编译器中的注释一致)char (*)[10],这与“指向a的指针完全不同”指向char“的指针(char **。这些指针类型 - char (*)[10]char ** - 不能隐式转换为彼此。

最后一个案例char* fooPntr = foo实际上是等价的(感谢foochar *fooPntr = &foo[0]的数组到指针的转换。换句话说,fooPntr的类型为char *(因为您已经这样声明)并且包含单个char的地址 - 数组中名为{{1}的第一个字符}}。由于foofooPntr类型的变量,因此可以评估其地址char *,并且类型为&fooPntr。这正是函数char **接受的内容,因此singleLeftPadZero()有效。