2017-10-21 59 views
0

我有以下的(貌似无辜的)代码:为什么我不能将一个指针的地址传递给一个固定大小的数组,而是将一个指针指向C中的一个指针?

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(*)[10]”

我做这看上去好像是固定的,是创建一个额外的变量: char* fooPntr = foo; 然后到该地址传递作为函数参数: singleLeftPadZero(&fooPntr);但我不知道为什么这个作品!

+3

所以一个数组不是一个指针。然后,指向数组的指针不是指向指针的指针。 –

回答

1

你犯的错误是相信指针和数组是相同的东西。他们不是。在某些情况下,它们可以以相同的方式使用(与“他们是同一事物”完全不同),但不能用于其他情况。你的例子是在上下文中指针和数组是不同的东西,并且不能像使用相同的东西那样使用。

在你的第一种情况下,通过首先执行“阵列到指针转换”传递到foo作品singleLeftPadZero() - foo是10 char的阵列,并且被转换为char *类型的指针具有值等于&foo[0]。A char *不是char **,因此警告不兼容的类型和音符。

在第二种情况下,通过&foosingleLeftPadZero()不会执行转换。相反,&foo的类型是“指向10 char的数组的指针”,或者(与来自编译器的注释一致)char (*)[10],它与“指向指向char的指针的指针”(这是char **。类型 - char (*)[10]char ** - 不是隐式转换为彼此

最后一种情况char* fooPntr = foo实际上相当于(多亏了阵列的foo指针转换)char *fooPntr = &foo[0]换句话说,fooPntrchar *型的(因为你。已经这样声明)并且包含单个地址char - 数组中的第一个字符foo。由于fooPntrchar *类型的变量,因此可以评估其地址&fooPntr,并且类型为char **。这正是singleLeftPadZero()接受的功能,所以singleLeftPadZero(&fooPntr)有效。

1

阵列名称foo衰减到char *,这是一个指向foo的第一个元素的字符指针。它不是char **这是一个指向指向内存位置的字符指针的字符指针。

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

void singleLeftPadZero(char*); 

由于数组名衰减的指针数组的第一个元素,foo本身是给出了一个地址。所以&foo意味着指向10个元素阵列的指针的地址,因此消息argument is of type ‘char (*)[10]’

char (*)[10]表示指向10个元素数组的字符指针。尽管数组名称衰变为指针,但指针和数组并不相同。看看here

相关问题