将char数组传递给接受char指针的函数

4
在C语言中,为什么我可以将字符数组传递给以char *作为参数的函数,但无法将数组地址传递给以char **作为参数的函数呢? 更新:有趣的是,将参数类型更改为char* qux[12]并没有改变编译器的警告。
例如:
#include <stdio.h>

void foo(char* qux) { puts(qux); }
void bar(char** qux) { puts(*qux); }
void baz(char* qux[12]) { puts(*qux); }

int main() {
    char str[12] = "Hello there";

    foo(str);
    bar(&str); // Compiler warning
    baz(&str); // Same compiler warning

    return 0;
}

在第二种情况下,我会收到编译器警告:
warning: incompatible pointer types passing 'char (*)[12]' to
         parameter of type 'char **' [-Wincompatible-pointer-types]

这里发生了什么?


它们是不同的类型。问问自己:*qux 的大小是多少? - e0k
1
我觉得这个问题应该有一个重复的。 - MFisherKDX
@ThiruShetty 我理解单指针和双指针的区别,但是我不知道像Someprogrammerdude所提到的数组衰减。 - sleighty
我已经尝试了很多搜索词,但如果你找到任何有用的信息,请告诉我 @MFisherKDX! - sleighty
https://dev59.com/-G035IYBdhLWcg3wMM4G - Antti Haapala -- Слава Україні
显示剩余4条评论
2个回答

5

数组自然会衰减为它们第一个元素的指针。因此,在调用foo(str)时,它实际上与foo(&str[0])相同。这是char *类型,所以一切都没问题。

现在,对于第二个调用bar,情况就不同了。当使用&str时,你得到的是指向数组本身的指针,而不是指向数组第一个元素的指针。正如编译器所指出的,它的类型是char (*)[12],与char **非常不同且不兼容。

最后,当你声明baz时,你说参数的类型是char *[12],也就是说你有一个包含12个指向char的指针的数组,而不是一个指向包含12个char的数组的指针。此外,由于数组衰减成指针的事情,char *[12]实际上与char **是相同的。


哦,我猜我不知道数组衰减,那很有趣。有没有办法让该参数成为12个char的数组指针,而不是反过来的? - sleighty
试一下这种方法。char *qux1 = NULL; qux1=qux; bar(&qux1); - ntshetty
2
@BrunoEly 我刚刚告诉了你,这也是错误信息的一部分:“... passing 'char (*)[12]' to...”。例如使用 char (*qux)[12],你就有了一个指向包含12个字符的数组的指针。然而,像这样传递数组的指针通常是不必要的,传递一个简单的指向第一个元素的 char * 是常见的用法。 - Some programmer dude
@Someprogrammerdude 懂了!是的,那就是我通常的做法,只是我一直搞不清楚那个错误信息的含义,这让我困扰了一段时间。感谢你的解释。 - sleighty
此外,由于数组衰减为指针的特性,char *[12] 实际上与 char ** 相同。数组并不等同于指针。在很多情况下,数组类型的表达式隐式转换为其第一个元素的指针,但并不是所有情况都是这样。 - newacct

2
在C语言中,char *表示一个指向连续字符序列的指针。在C语言中,一个以null结尾的连续字符序列被称为字符串。 char **是一个指向连续字符串序列的指针,由于每个字符串都是以null('\0')字符结尾的连续字符序列,所以char **表示一个连续字符序列的连续序列,这些字符序列都以null结尾。
您的声明:
 char str[12] = "Hello there";

声明str为长度为12的字符数组,并初始化为12个字符{'H','e','l','l','o',' ','t','h','e','r','e','\0'}。这与foo()中的参数兼容,但与barbaz都期望一个指向字符串的连续序列不兼容。这就是为什么这两个会给你编译器警告,因为参数与传入的参数不兼容。请注意保留html标签。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接