【问题标题】:How does the compiler know the prototype of printf( ) in this code?编译器如何知道这段代码中 printf() 的原型?
【发布时间】:2018-07-06 20:30:57
【问题描述】:

在下面的代码中,

#include<conio.h>
clrscr();
gotoxy(10, 20);
ch= getch(a);

我们可以看到库函数在没有定义原型的情况下被调用,三个库函数:clrscr() gotoxy(int int)getch()在conio.h头文件中定义了它们的原型,它们出现在头文件本身中是这样的,

void clrscr();
void gotoxy(int int);
int getch();

但是在下面的代码中,编译器是如何知道printf() 函数的原型的呢?由于代码执行时没有任何错误,尽管在第一个 printf() 最后一个 int 格式说明符打印垃圾值,而在第二个中,j 的值根本没有被打印,因为它没有被指定。

#include<stdio.h>
int i=10, int j=20;
printf("%d%d%d",i,j);
printf("%d",i,j);

printf()函数的格式说明符是float或char变量时,头文件stdio.h如何描述场景?

【问题讨论】:

标签: c printf


【解决方案1】:

任何像printf这样的预定义函数都应该在使用前在相应的头文件中进行原型化或声明,以便在执行程序时编译器可以验证程序员是否使用了正确的格式。

printf() 函数 prototypeheader file 中声明,称为 stdio.h

当编译器执行你的第一行代码#include&lt;stdio.h&gt;时,它就知道了printf原型。

man 3 printf

 int printf(const char *format, ...);// last 3 dots specifies the variable no of arguments printf can take 

在您下面的代码中,printf 导致 未定义的行为,因为 printf 需要 3 参数,但您只提供了 2 参数。

printf("%d%d%d",i,j);

【讨论】:

  • the 随机 code formattingyour 答案中是什么?
  • 我很抱歉听起来很困惑,但是我知道你提到了什么,我唯一要问的是,如果我在代码中有一个 float 或 char 常量,那么头文件将如何如果我错过了格式说明符或变量声明本身,请定义原型,就像我给出的示例中一样?
  • @AndrewGates printf 开始将参数从Right 映射到Left。如果您提供了%d 并提供了double 变量,那么它将是未定义的行为,否则它会打印预期的结果。
  • @AndrewGates 如果我在代码中有一个 float 或 char 常量,那么头文件将如何定义原型 。只有1st argument 固定在printf 中,即const char*,这意味着string(double quotation)double quotation 内部任何格式说明符都会映射到相应的参数。如果它丢失它会打印一些垃圾数据。
【解决方案2】:

stdio 标头始终包含相同的 printf() 声明,即:

int printf(const char *fmt, ...);

无论您将哪个占位符放入格式字符串,声明始终相同。

通常 printf 的定义\实现会遍历 fmt 字符串中的每个字符,并将每个标识的占位符替换为适当的参数。编译后的代码将尝试以与源代码中指定的顺序相同的顺序使用参数而不是占位符。

【讨论】:

  • 所以这意味着如果 printf() 有 char/float 参数,那么原型将保持为“int printf()”?
  • @AndrewGates intprintfreturn value。无论 printf 采用的参数可能是 char、float 或 double ,它总是返回 integer(no of printable char)
  • @AndrewGates int printf() 是一个没有原型的函数声明。 “原型”是 ( ) 之间的东西。
  • @AndrewGates 如果您对 printf 如何处理可变数量的参数感兴趣,“va_start”、“va_arg”和“va_end”是用于替换格式中每个找到的占位符的函数字符串。
【解决方案3】:

编译器知道原型,因为它是在 &lt;stdio.h&gt; 中声明的,您将其包括在内。

&lt;stdio.h&gt; 没有描述格式说明符。它只是说

int printf(const char *, ...);

... 表示printf 采用可变数量的参数(未知类型)。


您对printf 的第一次调用具有未定义的行为(格式字符串的参数不足)。你的第二个电话很好(多余的参数被简单地忽略)。 C 编译器不需要检测这样的格式字符串问题。

【讨论】:

  • 好的,stdio.h头文件中printf()函数的原型是什么?
  • 什么意思?正如我的回答所说,它是const char *, ...
  • @AndrewGates cont char * 是语法错误,..... 也是如此。你从什么来源学习 C 语言?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-22
  • 1970-01-01
  • 2017-10-31
相关资源
最近更新 更多