C语言 为什么我们需要传递指针作为参数来打印字符?



我正在学习C,我想使用函数打印一个名字,所以我做了这个代码:

#include <stdio.h>
void pn(char x);
void main()
{
pn("HHH");
}
void pn(char x)
{
printf("Hello %sn",x);
}

并且输出什么都没有,所以我更改参数并将其作为指针,然后它就可以工作了:

void pn(char* x);
void main()
{
pn("HHH");
}
void pn(char* x)
{
printf("Hello %sn",x);
}

输出是:你好HHH

据我所知,指针是存储变量的地址,但这里我不发送任何地址? 那么为什么只有当我把指针作为参数时它才有效呢?

在第一个程序中,函数参数

void pn(char x);

具有类型char,即函数期望作为参数的单个字符。

但是,该函数以字符串文字"HHH"作为其参数调用

pn("HHH");

C 中的字符串文本具有字符数组的类型。例如,字符串文本"HHH"的类型为char[4],因为字符串文本还包括一个不可见的终止零字符。

例如,在表达式中使用,例如作为函数参数,数组被隐式转换为指向其第一个元素的指针。因此,字符串文本"HHH"被转换为指向第一个字符'H'char *类型的临时对象。

因此,由于参数和相应参数不兼容,函数具有未定义的行为。

在第二个程序中,函数参数被正确地更改为类型char *并且程序产生了预期的结果。

如果你想在第一个程序中只输出一个字符,那么至少应该按以下方式更改它

#include <stdio.h>
void pn(char x);
void main()
{
pn("HHH"[0]);
}
void pn(char x)
{
printf("Hello %cn",x);
}

或者调用函数会更清楚,例如

pn( 'H' );

传递字符文本。

C 中的字符串定义为以空字符结尾的字符数组。 C 中的数组由指向数组中第一个元素的指针定义。

您的函数不起作用,因为它的参数只接受单个字符作为参数,而不是指向字符数组的指针。

">那么为什么只有当我把指针作为参数时它才有效?

"HHH"是 4char(char [4]( 数组类型的字符串文字。

当您在 C 中使用字符串文字作为函数参数时,字符串文字将被计算为指向构成字符串的char数组的第一个元素的指针,键入指向char(char *的指针(。

在这种情况下,"HHH"将获得一个指向包含第一个H的第一个char元素的内存地址的指针。

如果您现在使用x作为类型char的参数,则有:

  1. 调用函数时的类型不匹配pn参数和参数 -char *char,它调用未定义的行为,以及

  2. 此外,printf("Hello %sn",x);处的类型不匹配,因为%s转换说明符需要指向 char 的类型指针的参数。这也调用了未定义的行为,因为您提供了类型char的参数,根据 C 标准,这是不允许的。

    "如果转换规范无效,则行为未定义。288(如果任何参数不是相应转换规范的正确类型,则行为是未定义的

    "288(请参阅"未来的图书馆方向"(7.31.11(。

    来源:C18,7.21.6.1/9 - "fprintf 函数">


旁注:

  • 通常,编译器应默认警告您这两种类型不匹配(没有任何其他标志(。因此,您似乎要么忽略编译器警告,要么没有合适的编译器。将编译器切换到GCCClang(如果尚未完成(,并且永远不要忽略编译器警告:

    为什么我应该始终启用编译器警告?

相关内容

  • 没有找到相关文章

最新更新