当前位置:  开发笔记 > 程序员 > 正文

为什么#include <stdio.h>不需要使用printf()?

如何解决《为什么#include<stdio.h>不需要使用printf()?》经验,为你挑选了3个好方法。

会议记录:

>type lookma.c
int main() {
  printf("%s", "no stdio.h");
}

>cl lookma.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

lookma.c
Microsoft (R) Incremental Linker Version 8.00.50727.762
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:lookma.exe
lookma.obj

>lookma
no stdio.h

Chris Young.. 37

您最初标记了此C++,但它似乎是一个C程序.如果范围中没有原型(例如由于省略#include ),C将自动为函数提供隐式声明.隐含声明将是:

int printf();

这意味着printf是一个返回int的函数,可以接受任意数量的参数.这个原型恰好适合您的通话.你应该#include

最后,我要补充的是,当前的C标准(ISO/IEC 9899:1999或俗称"C99")都不会允许隐式声明,并将该软件将不符合.删除了隐式声明.我相信你的编译器不支持C99.C++还需要正确的原型,不进行隐式声明.



1> Chris Young..:

您最初标记了此C++,但它似乎是一个C程序.如果范围中没有原型(例如由于省略#include ),C将自动为函数提供隐式声明.隐含声明将是:

int printf();

这意味着printf是一个返回int的函数,可以接受任意数量的参数.这个原型恰好适合您的通话.你应该#include

最后,我要补充的是,当前的C标准(ISO/IEC 9899:1999或俗称"C99")都不会允许隐式声明,并将该软件将不符合.删除了隐式声明.我相信你的编译器不支持C99.C++还需要正确的原型,不进行隐式声明.



2> Jonathan Lef..:

在严格的合规模式(意思是"在理论上")中,当您调用一个函数时调用未定义的行为(这是不好的),该函数接受可变数量的参数而没有函数的原型声明.这意味着允许编译器使用printf()没有原型#include 或等效声明的程序执行任何它喜欢的操作."任何它喜欢的东西"包括正确地作为选项之一; 这似乎是你的例子选择的选项.

实际上,即使没有printf()函数的正式声明,代码也可以在大多数实用编译器中正常工作.

正如qrdl所指出的,找到了该函数,因为C编译器与C库链接.

请注意,Chris Young关于C99和'implicit int'的评论是准确的,但关于'变量参数函数必须在范围内具有原型'的规则适用于C89和C99.默认情况下,大多数编译器不能在严格的C99兼容模式下工作,因为有太多的代码无法像这样编译.

Chris Young评论道:

为了澄清,我的评论是关于C99删除隐式声明.通过说"隐式int",我认为你指的是允许声明的C89特性,如foo(void); 意思是int foo(void);, C99也删除了.

克里斯当然是正确的.从C99标准中删除了两个"隐式声明"功能.标准的前言将它们列为:

删除隐式 int

删除隐式函数声明

我没有想清楚(因而也没有写作).尽管如此,C89和C99都需要一个原型,用于采用可变数量参数的函数.

为了显示:

extern int pqr();
int main(void)
{
    int i = pqr(1, 3);
    return i;
}

如果没有第一行,这是一个正确的C89片段,其函数的隐式声明pqr()作为返回整数的函数(带有未指定的参数).如果第一行被替换为extern pqr();,那么这是一个正确的C89片段,其显式声明pqr()为返回整数的函数(带有未指定的参数),但返回类型为"隐式int".如上所述,该函数是显式声明的,并且具有显式的int返回类型 - 但它仍然具有未指定的参数.我相信这是有效的C99 - 尽管不是完全可取的.当然,GCC(3.4.4)接受选项' -std=c99 -pedantic".理想情况下,函数声明应该包括完整的原型.(如果pqr()用省略号定义,原型在理论上是必需!)



3> qrdl..:

printf() 位于标准C库中,链接器始终将标准库链接到您的可执行文件,因此将找到任何标准函数,并且不会出现链接问题.

未能包含适当的头导致使用非原型的函数可能导致问题,因为C编译器假定没有原型的函数返回int并且接受可变数量的参数.所以总是包括标题 - 这是你的安全围栏.


不是'可变数量的参数',而是一个未定义但固定数量的参数.
推荐阅读
ERIK又
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有