在以下代码中,
#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如何描述场景?
答案 0 :(得分:0)
编译器知道原型,因为它是在<stdio.h>
中声明的,你要包含它。
<stdio.h>
未描述格式说明符。它只是说
int printf(const char *, ...);
...
表示printf
采用可变数量的参数(未知类型)。
您对printf
的第一次调用具有未定义的行为(格式字符串的参数不足)。你的第二次调用很好(多余的参数被忽略)。 C编译器不需要像这样检测格式字符串问题。
答案 1 :(得分:0)
任何predefined function
printf
prototyped
应该declared
或header file
才能使用printf()
所以在执行程序编译时可以验证程序员是否使用格式是否正确。
prototype
函数header file
在名为stdio.h
的{{1}}中声明。
当编译器执行代码的第一行#include<stdio.h>
时,它开始了解printf
原型。
man 3 printf
说
int printf(const char *format, ...);// last 3 dots specifies the variable no of arguements printf can take
在下面的代码printf
中导致未定义的行为,因为printf
需要3
个参数,但您只提供了2
个参数。
printf("%d%d%d",i,j);
答案 2 :(得分:0)
stdio标头总是包含相同的printf()声明:
int printf(const char *fmt, ...);
无论你把哪个放置在你的格式字符串中,声明总是一样的。
通常,printf的定义\实现迭代fmt字符串中的每个字符,并用适当的参数替换每个标识的占位符。编译后的代码将尝试使用参数而不是占位符,其顺序与源代码中指定的顺序相同。