汉扬编程 编程大纲 include的用法、区别?重定义错误及extern \”C\”

include的用法、区别?重定义错误及extern \”C\”

卷首语从一包源代码里的头文件,就能够看出其模块功能、架构形式,且有许多注释信息,例如接口参数、使用方法等等,对于编写高质量代码,会很有帮助,所以我们应该养成阅读头文件的习惯。同时,编写代码的时候,在头文件中写好函数接口及其注释也是必要的。

常说的头文件是什么?C语言的头文件,即名称后缀为.h的文件。

头文件为编译器提供编译所需的各种信息。

在C语言中,头文件和对应的的实现(后缀为.c的文件)是分离的,所以也可以将头文件看成是一份清单文件,是具体实现的一份清单(有哪些函数、类型等等),而.c文件会被编译成库,或者.o目标文件,根据需要将目标文件链接到一起,就形成了最终的可执行文件。

所以在调用一个函数的时候,只需要引用到对应的头文件,在所需地方调用其函数,而不用去关心其实现部分。(如上所述,实现部分由链接器完成拼接。)

理论上,多包含一些头文件,或者包含大型的头文件,不会显著增加程序的体积。除了一些会产生空间分配的static,const 变量,但这些变量所占空间相对于程序而言,一般较小。

所以不用担心多包含了几个头文件,程序体积就变得很大,但就编程而言,我们应该只包含所需的头文件。

使用形式及区别(1)文件名放在尖括号内#include < stdio.h>解析:尖括号<>告知编译器,要在系统目录里查找名为 stdio.h 的文件,在windows和Linux系统中,系统目录的路径均定义在环境变量path下(2)文件名放在双引号内#inlcude \”xxxx.h\”解析:双引号\”\”告知编译器,现在当前目录或双引号中指定的目录中查找,如果找不到,再到系统目录中查找。注意:所谓的“当前目录”,根据不同平台、不同编译器的差异,可能是当前所编译源文件的目录;也可能是项目文件的TOP目录;或者是系统当前的工作目录。include指令原理当编译器,更准确的应该说是预处理器,在发现#include指令后,就会查找其后尖括号或者双引号中的文件,如果查找到,则用其全部文本内容替换这条#include指令。如果查找不到,则报出编译错误,停止编译。

例如:

#include <stdio.h>#include \”constant.h\”#include \”/usr/inc/xxxx.h\”头文件包含哪些内容?一般包含如下内容:

1.常量2.宏定义3.函数声明4.结构类型5.typedef的类型定义string.h头文件,省略中间大部分,主要看其格式

重复include,导致的重定义错误在一个稍大规模的工程原码里,同一个头文件,可能会被多个文件同时包含,当这些文件编译链接成一个可执行文件时,就会出现大量“重定义”的编译错误。利用宏指令#ifndef,下面的写法,可以防止重定义错误:#ifndef _HELLOWORLD_H //一般是文件名的大写, 避免宏定义重名#define _HELLOWORLD_H //….. 省略 …..//头文件的实际内容// ….. 省略 …..#endif //头文件结尾写上一行endif与ifndef配对如此在出现重复包含helloworld.h时,就不会出现重定义的错误了。

从宏指令的名称,可以看出其逻辑。只有在第一次包含的时候,宏是没有被定义的,如此可以展开为头文件的实际内容。后续的第二次,第N次包含,宏已经被定义,其内容就不会被展开,即内容为空。

典型写法,兼容C++的include格式C与C++经常存在相互调用的情况,但C编译器编译函数时不带参数的类型信息,而C++是带参数类型信息的,这样就会导致一个问题:

举例:void foo(int a, int b);用C编译后的符号可能是这样(不带参数信息):_foo用C++编译后的符号可能是这样(带参数信息):_fooii同一个头文件里的函数,使用C和C++编译出来的符号名称却不一样,这样在C和C++交叉调用的时候,就会出现相互不认识,符号不存在,链接不上的错误。在C++里,通过链接指示:extern \”C\” 来解决此问题,指明其作用域内的函数,编译时使用C语言的规则产生符号,也就是不带参数信息,这样,在链接的时候,就能调用C编译器编译的库文件。同样的,C也能调用C++编写的库文件。(问题:遇上重载函数,怎么办?)典型写法:

#ifndef _HELLOWORLD_H#define _HELLOWORLD_H #ifdef __cplusplus //指明编译器的类型,_cplusplus被定义,代表采用C++编译器extern \”C\” {#endif/* ……省略…… */void foo();/* ……省略…… */#ifdef __cplusplus}#endif#endif /* _HELLOWORLD_H */卷尾语extern \”C\” 的具体原理(真相如何?),及用法将在另外一篇文章中详细描述。

原创虽不易,欢迎批评、校正,有疑问的可以留言、评论、私信,。^_^

本文来自网络,不代表汉扬编程立场,转载请注明出处:http://www.hyzlch.com/mianfei/6424.html

用C实现输入二叉树的前序和中序遍历

大学C语言考试易错知识点总结

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

返回顶部