预处理器(3)

来源:互联网 发布:淘宝网 我的购物车 编辑:程序博客网 时间:2024/05/29 03:20

5.文件包含 #include

#include<stdio.h>

我们在一开始学习C语言的时候,照猫画虎的敲下的第一行代码,就是上面这一行。

它的意思就是当程序编译之前,把stdio.h的内容替换到test.c文件中。

#include<系统库文件一般用尖括号< >来包含系统库文件

#include本地文件”    本地文件必须用双引号” ”来包含。使用” ”预处理器会先从本地文件查找,如果找不到,就去函数库文件查找。所以,用” ”包含系统库文件也没有错,不过很效率较低。

当然#include”filename”中的filename大多数情况下,直接写一个文件名就OK了。

我们在IDE(比如VC6.0VS2010)下编程,在IDE中我们建立工程,然后建立cpp文件,然后写进代码,调试运行。这是大多数人的编程习惯。

其实这样写,

#include"C:\Users\Administrator\Desktop\c\Pro1.h" //windows \  

#include" /Desktop/c/Pro1.h"                                  // Linux /

也是可以的。只要能使预处理器找到目标文件,就可以通过编译。

所以,filename的含义并不只是文件名那么简单。

 

#include是不仅仅可以包含.h文件的,.cpp同样也可以包含进去。

//Pro1.cppint sum(int a,int b){return a+b;}


 

//main.cpp#include"stdio.h"#include"Pro1.cpp"int main(){         printf("%d\n",sum(12,23));return 0;}

 

注意一点,如果在Linux环境下,用gcc编译Main.cpp,运行程序即可。

但如果使用的是windows下的IDE来编写代码,直接点工具栏上的编译、运行按钮的话,就会出现如下链接错误:

Pro1.obj : error LNK2005: "int __cdecl sum(int,int)" (?sum@@YAHHH@Z)已经在 main.obj中定义

fatal error LNK1169:找到一个或多个多重定义的符号

/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

IDE很方便,这不可否认。但它隐藏了很多程序实现的细节,对于只想过二级的同学来说,大可不必关心这些。但如果是专业相关的同学,没有理由不去了解这些东西。

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/

使用gcc时,在编译之前的预处理阶段,Pro1.cpp中的代码被包含进了Main.cpp中。然后,gcc编译源文件Main.cpp,并生成Main.out文件(文件名可指定),在终端输入./Main就可以运行了。

而用VS2010的时候,选中Main.cpp按下编译按钮,编译Main.cpp,(预编译阶段已经把Pro1.cpp的内容包含进去了)这时候在Debug文件夹下生成一个Main.obj的目标文件。再点击执行按钮的时候,就会出现链接错误,这是为什么呢?

如上面的错误信息所示,仔细看Debug文件夹下发现了Pro1.obj文件。当连接器链接Main.objPro1.obj的时候就会出现多重定义的错误。在VS里面,工程下的C文件或者CPP文件,在链接阶段之前都会默认编译输出目标文件。

 注:

目标文件,一般是程序编译后的二进制文件,再通过链接器和资源文件链接就成可执行文件了。

OBJ只给出了程序的相对地址,而可执行文件是绝对地址。

链接器(Linker)是一个程序,将一个或多个由编译器或汇编器生成的目标文件外加库链接为一个可执行文件。

 

解决这个问题的方法,有很多。

第一种:修改Pro1的文件类型,可以把Pro1.cpp修改成Pro1文件或者Pro1.txt文件,总之能储存字符流的文件类型就OK,相应的#include也要包含修改过的文件,这样VS就会只生成一个Main.obj,不影响连接器的执行。

第二种:不用IDE,而使用VS的命令行,来链接目标文件生成可执行文件,思想和Linux下的Gcc是一样的。步骤如下:

 

 

打开VS命令提示符,把目录切换到main.cpp所在目录下。

输入cl main.obj  回车

/out:main.exe

main.obj

 

输入main就可以得到正确的结果了。


 


 

0 0
原创粉丝点击