首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

即使我们不在C程序中包含stdio.h,为什么我们不会得到编译时错误?

即使我们不在C程序中包含stdio.h,我们也不会得到编译时错误。这是因为C语言标准库中的一些函数(如printf、scanf等)在不包含stdio.h头文件的情况下,仍然可以正常使用。这是因为这些函数在C语言标准库中的其他头文件(如stdlib.h、string.h等)中被声明为外部链接。

然而,这种情况下,编译器可能会发出警告,因为在不包含stdio.h头文件的情况下使用这些函数可能会导致未定义的行为。为了避免这种情况,最佳实践是始终在使用这些函数之前包含stdio.h头文件。

总之,即使我们不在C程序中包含stdio.h,我们也不会得到编译时错误,但是为了避免未定义的行为和编译器警告,最佳实践是始终在使用这些函数之前包含stdio.h头文件。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

每天都在用printf,你知道变长参数是怎么实现的吗

那么,我们就可以通过第一个参数进行地址偏移,来得到第二个,第三个参数的地址,是不是可以实现呢?我们来看一个32位程序的例子。...程序清单如下: //来源:公众号【编程珠玑】#include /*要使用变长参数的宏,需要包含下面的头文件*/ #include /* * getSum:用于计算一组整数的和...我们举一个简单的例子,如果第二个参数传入一个浮点数,程序清单如下: //来源:公众号【编程珠玑】#include /*要使用变长参数的宏,需要包含下面的头文件*/ #include...2.getSum函数为什么第一个值是0? 3.getSum函数为什么第二个值是1075871744? 4.getSum函数为什么没有获取到5? 5.为什么最后的结果不是我们预期的值?...7.当传入参数个数少于使用的个数,可能会出现严重问题,当传入参数大于使用的个数,多出的参数不会被处理使用。 8.注意字节对齐问题。

4K20

变长参数探究

程序清单如下: #include /*要使用变长参数的宏,需要包含下面的头文件*/ #include /* * getSum:用于计算一组整数的和 * num...但是我们要注意的是,这个小程序不像printf那样,对传入的参数做了校验,因此一但传入的参数num和实际参数不匹配,或者传入类型与要计算的int类型不匹配,将会出现不可预知的错误。...我们举一个简单的例子,如果第二个参数传入一个浮点数,程序清单如下: #include /*要使用变长参数的宏,需要包含下面的头文件*/ #include /*...2.getSum函数为什么第一个值是0? 3.getSum函数为什么第二个值是1075871744? 4.getSum函数为什么没有获取到5? 5.为什么最后的结果不是我们预期的值?...7.当传入参数个数少于使用的个数,可能会出现严重问题,当传入参数大于使用的个数,多出的参数不会被处理使用。 8.注意字节对齐问题。

65510
  • 代码%80的非逻辑性代码都可以被它发现

    也就是说,利用PC-lint对我们的代码进行扫描分析,在程序运行之前,就可以发现代码隐藏的问题。...安装方法不在此介绍,和其他普通软件的安装方式一样。安装完成后,在安装目录下会有lint-nt.exe程序。...如果源文件比较多,那么将源文件添加带files.lnt是一件很繁琐的事情,我们可以使用命令来得到我们的files.lnt文件: dir /S/B *.h *.c > files.lnt 示例程序...\test\main.c //我们的源代码文件 由于我们的代码包含stdio.h头文件,因此还需要stdio.h头文件,我把它放在了D:\pclint\include,并在lnt文件中指定了头文件的位置...(C) 这里除了修改了我们确定的问题之外,还屏蔽了PC-lint的534号警告,因为我们确认这不会我们程序本意造成任何影响,因此使用/*lint -e{534}*/屏蔽了main函数的534号警告

    1.6K40

    C语言 | 为什么写这三行代码

    为什么写#include #include是在程序编译之前要处理的内容,是编译预处理命令,一般以“#”开头,并且不用分号结尾。...在上述程序编译预处理命令称为文件包含命令,作用是在编译之前把程序需要使用的关于系统定义的函数printf()的一些信息文件stdio.h包含进来。...return 0的意思是程序运行到这里,就不往后运行了,程序结束了,这行代码可以省略。 运行C语言程序步骤 上机输入和编译源代码  通过键盘向计算机输入程序,如发现有错误,要及时改正。...最后将此源程序以文件形式存放在自己指定的文件夹内,文件用.c作为后缀。 对源程序进行编译 先用C编译系统提供的“预处理器”对程序 的预处理指令进行编译预处理。...在用编译系统对源程序进行编译,自动包括了预编译和正式编译两个阶段,一气呵成。

    91162

    Linux之动态库和静态库

    静态库(.a):库文件以.a为后缀,程序编译链接把库的代码链接到可执行文件(将需要的库函数拷贝一份到代码)。程序运行时不需要再跳转到静态库。...动态库(.so):库文件以.so为后缀,程序在运行时才去链接动态库的代码(运行时跳转到动态库,在动态库执行库函数)。多个程序共享库的代码。 链接的本质:我们调用库函数是如何与标准库联系的。...(在编译,只需要把源文件编译成.o文件,再将其链接即可形成一个可执行程序,因此我们可以直接提供,o文件)。...但是如果我们有很多.c文件,难道我们要将所有的.c文件全部编译成.o文件,然后一个一个提供给用户吗?未免太过麻烦。我们可以把编译得到的所有.o文件打包,直接给对方提供一个库文件即可。...但是我们自己制作的库并不在系统的默认路径下,因此OS无法找到库,就无法正常执行程序。那么我们要如何让OS找到我们的库呢? 我们可以将库路径添加到环境变量LD_LIBRARY_PATH

    52220

    你知道.c是如何变成.exe的吗

    链接器同时也会引入标准C函数库任何被该程序所用到的函数,而且它可以搜索程序员个人的程序库,将其需要的函数也链接到程序。 1. 编译 关于上述的翻译环境我们只是讲了一个大概,并没有进行深入的分析。...我们输入vim /usr/include/stdio.h进入到Linux环境stdio.h头文件我们发现有900多行的代码包含在内 接下来我们对比test.i与stdio.h,发现它们两者之间有些内容确实是一样的...那么回到上面那个问题,你知道为什么stdio.h文件的代码行数比test.i中代码数要多了吗 综上: 预处理过程实质上是处理“#”,将#include包含的头文件直接拷贝到.i文件当中; 将代码没用的注释部分删除...因为一旦使用宏替换出现错误时,我们在调试其实看到的已经是经过预处理过后的代码了,所以根本无法迅速判断错误出在哪,这也就增大了我们的维护成本。...我们先来看下正确的例子,它得到了正确答案: 下面我将Add函数注释掉看看会发生什么情况 答案显然而知肯定是发生了链接错误,因为test.c当中的Add函数的地址是无效的,自然就不能找到且调用Add函数了

    93520

    C语言进阶(十五) - 预处理与程序编译初步解析

    前言 本节主要介绍程序运行前的预处理(预编译)阶段的相关知识。同时简单介绍一个程序是如何从一行行代码到开始运行并得到结果的。 ---- 1....宏可能会带来运算符优先级的问题,导致程序出现错误。 ** 属性** #define定义宏 函数 代码长度 每次使用宏,宏代码都会插入程序。...如果找不到就提示编译错误。 可以知道即使是库函数头文件也可以使用""形式,只是查找的效率较低,同时也不容易区分查找的是库文件还是本地文件了。 一般建议:库文件用,本地文件用" "。...1.6.2 嵌套文件包含 一般我们写代码不会故意多次包含一个头文件,但同一个头文件被多次包含的情况也不是一定不会出现。 我们可以预防这样的意外情况的出现,即防止头文件被重复包含。...链接器同时也会要引入标准C函数库任何被该程序所用到的函数,而且他可以搜索程序员个人的程序库,将其需要的函数也链接到程序

    43320

    C++】C++入门知识详解(上)

    1.C++的第一个程序 C++需要把定义文件代码后缀改为 .cpp  我们在 test.cpp 来看下面程序 #include int main() { printf("hello...} 程序就会报下面的错误,说rand重定义了 多加了个头文件程序为什么会重定义呢? ...没有包含 ,全局只有一个rand变量,此时没有冲突,程序正常运行,但是,包含  这个头文件后就有问题了,是因为rand是C语言库里的函数,头文件stdlib.h...C++的输入输出需要包含这个头文件,就相当于C语言中使用printf我们需要包含这个头文件。那为什么iostream没有加.h呢?...当我们程序展开了std,也就是using namespace std; 使用cin, cout, endl就不需要加std::了,不过展开了std又加上了std:: 程序不会报错,但有点多此一举了

    5510

    解了这十道C语言题,你敢说你精通C语言?

    点击蓝字 关注我们 15.jpg 精通C语言? 本文展示了10个C语言的迷题以及答案,而且有相当的一些例子可能是我们日常工作可能会见得到的。通过这些迷题,希望你能更了解C语言。...#include int main() { int a = 1,2; printf("a : %d\n",a); return 0; } 参考答案: 这个程序得到编译出错...这个示例向我们说明printf并不是类型安全的,这就是为什么C++要引如cout的原因了。 5 下面的程序输出是多少?并解释为什么?...原因是,sizeof不是一个函数,是一个操作符,其求i++的类型的size,这是一件可以在程序运行前(编译)完全的事情,所以,sizeof(i++)直接就被4给取代了,在运行时也就不会有了i++这个表达式...不过,本例的问题不在这里,本例的输出会是:1,8,64,1000。其实很简单了,在C/C++,以0开头的数字都是八进制的。 9 下面的输出是什么?

    48930

    解了这十道C语言题,你敢说你学过C语言?

    本文展示了10个C语言的迷题以及答案,而且有相当的一些例子可能是我们日常工作可能会见得到的。通过这些迷题,希望你能更了解C语言。 如果你不看答案,不知道是否有把握回答各个谜题?让我们来试试。...#include int main() { int a = 1,2; printf("a : %d\n",a); return 0; } 参考答案: 这个程序得到编译出错...这个示例向我们说明printf并不是类型安全的,这就是为什么C++要引如cout的原因了。 5 下面的程序输出是多少?并解释为什么?...原因是,sizeof不是一个函数,是一个操作符,其求i++的类型的size,这是一件可以在程序运行前(编译)完全的事情,所以,sizeof(i++)直接就被4给取代了,在运行时也就不会有了i++这个表达式...不过,本例的问题不在这里,本例的输出会是:1,8,64,1000。其实很简单了,在C/C++,以0开头的数字都是八进制的。 9 下面的输出是什么?

    4623330

    解了这十道C语言题,你敢说你学过C语言?

    精通C语言?  本文展示了10个C语言的迷题以及答案,而且有相当的一些例子可能是我们日常工作可能会见得到的。通过这些迷题,希望你能更了解C语言。 如果你不看答案,不知道是否有把握回答各个谜题?...#include int main() { int a = 1,2; printf("a : %d\n",a); return 0; } 参考答案: 这个程序得到编译出错...这个示例向我们说明printf并不是类型安全的,这就是为什么C++要引如cout的原因了。 5 下面的程序输出是多少?并解释为什么?...原因是,sizeof不是一个函数,是一个操作符,其求i++的类型的size,这是一件可以在程序运行前(编译)完全的事情,所以,sizeof(i++)直接就被4给取代了,在运行时也就不会有了i++这个表达式...不过,本例的问题不在这里,本例的输出会是:1,8,64,1000。其实很简单了,在C/C++,以0开头的数字都是八进制的。 9 下面的输出是什么?

    3682118

    iOS开发你不知道的事-编译&链接

    我们平常Xcode开发就是集成的的开发环境(IDE),这样的IDE一般都将编译和链接的过程一步完成,通常将这种编译和链接合并在一起的过程称为构建,即使使用命令行来编译一个源代码文件,简单的一句gcc hello.c...正是因为集成开发环境的强大,很多系统软件的运行机制与机理被掩盖,其程序的很多莫名其妙的错误我们无所适从,面对程序运行时种种性能瓶颈我们束手无策。...编译流程分析 现在我们通过一个C语言的经典例子,来具体了解一下这些机制: #include int main(){ printf("Hello World"); return...首先是源代码文件hello.c和相关的头文件(如stdio.h等)被预编译器cpp预编译成一个.i文件。...保留所有的#pragma编译器指令 截图个大家看看效果 [1240] 经过预编译后的文件(.i文件)不包含任何宏定义,因为所有的宏已经被展开,并且包含的文件也已经插入到.i文件,所以当我们无法判断宏定义是否正确或头文件包含是否正确

    57000

    C语言】VS实⽤调试技巧&(Debug和Release)监视&内存

    Bug通常是由程序员在编写代码犯的错误或者设计缺陷引起的,需要通过调试和修复来解决。在软件开发和测试过程,发现和修复bug是非常重要的一部分。...一、调试(debug) 1. 1 Debug和Release 当我们发现程序的问题,下一步就是找到并修复它们。这个过程被称为调试,在英文中被称为debug(消灭bug)。...,编译产生的就是release版本的可执行程序,这个版本是用户使用的,无需包含调试信息。...如果没有那就是非法访问了,编译器会不会报错呢?Ctfl+F5,让程序走起来 代码运行结果:此时代码并没有停止,而是一直在打印,不断死循环,这是为什么呢?...⼀般是因为 • 标识符名不存在 • 拼写错误 • 头⽂件没包含 • 引⽤的库不存在 3.3链接型错误 运⾏错误,是千变万化的,需要借助调试,逐步定位问题,调试解决的是运⾏问题。

    89410

    解不了这十道C语言题,你敢说你精通C语言?

    本文展示了10个C语言的迷题以及答案,而且有相当的一些例子可能是我们日常工作可能会见得到的。通过这些迷题,希望你能更了解C语言。 如果你不看答案,不知道是否有把握回答各个谜题?让我们来试试。...#include int main() { int a = 1,2; printf("a : %d\n",a); return 0; } 参考答案: 这个程序得到编译出错...这个示例向我们说明printf并不是类型安全的,这就是为什么C++要引如cout的原因了。 微信搜索公众号【C语言中文社区】关注回复C语言,免费领取200G学习资料 5 下面的程序输出是多少?...原因是,sizeof不是一个函数,是一个操作符,其求i++的类型的size,这是一件可以在程序运行前(编译)完全的事情,所以,sizeof(i++)直接就被4给取代了,在运行时也就不会有了i++这个表达式...不过,本例的问题不在这里,本例的输出会是:1,8,64,1000。其实很简单了,在C/C++,以0开头的数字都是八进制的。

    47220

    C语言关键字详解(二) 带你全面了解 static 关键字

    ,所以一般都会将功能进行模块化处理,从而便于我们进行代码的复用、代码的修改与维护以及多人协作,自然我们一个程序中就需要多个.c文件 3、为什么要有头文件 单纯的使用源文件,组织项目结构的时候,项目越大越复杂维护成本会变得越来越高...,其实它是用来防止头文件被反复包含的,举个栗子 如上所示:我在test.h包含了头文件,但是在main.c我又同时包含了test.h 和 stdio.h ,这就造成了stdio.h...被包含了两次,使得程序编译的时候将stdio.h 里面的内容拷贝了两份,造成代码冗余,而#pragma once 会检查该头文件是否已经被包含,如若是就不在进行拷贝。...更深入的理解 static 修饰局部变量的作用:图三,我们程序从源文件(.c文件)变成可执行程序(.exe文件)需要经过编译链接运行三个环节,而编译环节又分为预处理、编译、汇编三个阶段,在汇编阶段,编译器会把我们的...本质上是:在编译环节的编译阶段编译器就会为被 static 修饰的局部变量分配空间,所以C程序在运行的过程中会直接跳过 static 修饰的语句,也就是说,在第二次及以上甚至第一次调用 test 函数

    33300

    CCPP分文件编写

    C语言对于语法的检查没有C++那么严格,即使头文件没有函数声明,编译的时候也只会报warning,但是依旧还是可以编译通过的。...= %d\n", len); return 0; } 这样编译就可以通过,不会报错了。...那么在真正的项目开发过程我们为什么不直接在调用之前直接声明一下而是将函数声明写入头文件呢?我们这么做就是为了编写代码方便,写入头文件中就不用重复的在各个.c/.cpp文件中去写函数声明。...这样只需要在调用myStrlen的.c/.cpp包含.h文件就可以了: //main.cpp: #include #include "myStrlen.h" int main(...那么还有一个问题啊,就是我们知道,函数和变量的定义只能有一次,但是函数的声明可以有多次。如果我在main.cpp多次包含了同一个头文件会怎么样呢?

    54920

    C语言】预处理详解(上)

    __STDC__ //意思:如果该C编译器完全遵顼ANSI C的标准,则其值为0。...如果在上述声明过后,把SQUARE(5);置于程序,与编译器就会用5*5这个表达式来替换SQUARE(5)。 但是,我们写的这一个宏有潜在的隐患。为什么这么说呢?...那我们该怎么修改上述的代码,使其能够得到正确的答案呢? 方法很简单,就是加括号,改变运算符的优先级。...宏替换的规则 在程序扩展使用#define定义符号和宏,需要涉及几个步骤: 在调用宏,首先对参数进行检查,看看是否包含任何由#define定义的符号。如果有,它们首先被替换。...替换后的文本会被插入到程序中原来文本的位置。对于宏来说,参数名被它们的值所替代。 最后,再次对结果文件进行扫描,看看它是否包含任何由#define定义的符号。如果有则重复上述步骤。

    9410

    宏(预编译)详解

    在学习预编译之前我们有必要先大致了解一下一个程序从开始到结束的过程,这样有利于我们加深对程序运行的理解。 一、程序编译环境 在ANSI C的任意一种实现,存在两个不同的环境。...如图所示,翻译环境 可以继续细分为编译和链接,编译还可以继续细分为预处理,编译,汇编,其中在翻译过程首先进行的是预处理过程,在预处理过程首先会把test.c源文件的注释删除以及#include头文件包含和...//文件被编译的时间 __STDC__ //如果编译器遵循ANSI C,其值为1,否则未定义 我们不妨打印出来这些预定义符号 #include int main() {...3.2.3#define替换规则 在程序扩展#define定义符号和宏, 需要涉及这几个步骤: 1.在调用宏,首先对参数进行检查,看看是否包含任何由#define定义的符号,如果是,他们首先被替换...3.4文件包含 我们不论写C语言还是写C++语言,我们都会用到头文件,像等,其实,#include指令可以使另外一个文件被编译

    21910

    文件结束符EOF

    system("stty cooked"); return 0;}编译运行该程序,则当如入一个字符,直接出处一个字符,然后程序结束。...但这个观点实际上是错误的,在文 件所包含的数据,并没有什么文件结束符. 对getc 而言, 如果不能从文件读取, 则返回一个整数 -1,这就是所谓的EOF....如果文件用 fgetc 读取, 刚好把最后一个字符读出, fp 的EOF标志不会打开,这时 用feof判断,将会得到文件尚未结束的结论. fgetc 返回 -1 , 我们仍无法确信文件已经结束,...(即即使读取错误可能也被认为文件结束,所以就需要用feof 和 ferror来判断是不是真的文件结束了)当用getchar(c)即使c定义成字符型,也可以结束,主要是c与-1比较c也会从char...得到的结果为ffffffff,所以c即使定义为char型,读取文件等还是能正常结束。

    4.5K10

    C++头文件和std命名空间

    实际上,编译器开发商不会停止对客户现有软件提供支持,可以预计,旧的 C++ 头文件在未来数年内还是会被支持。...下面是我总结的 C++ 头文件的现状: 1) 旧的 C++ 头文件,如 iostream.h、fstream.h 等将会继续被支持,尽管它们不在官方标准。这些头文件的内容不在命名空间 std 。...不过现实情况和 C++ 标准所期望的有些不同,对于原来C语言的头文件,即使按照 C++ 的方式来使用,即#include 这种形式,那么符号可以位于命名空间 std ,也可以位于全局范围...第 1) 种写法是标准的, 第 2) 种不标准,虽然它们在目前的编译器中都没有错误,但我依然推荐使用第 1) 种写法,因为标准写法会一直被编译器支持,非标准写法可能会在以后的升级版本不再支持。...前面几节我们使用了C语言的格式输出函数 printf,引入了C语言的头文件 stdio.h,将C代码和 C++ 代码混合在了一起,我不推荐这样做,请尽量使用 C++ 的方式。

    45930
    领券