http://blog.163.com/yui_program/blog/static/18415541520115177852896/

一、源文件如何根据#include来关联头文件

1,系统自带的头文件用尖括号括起来,这样编译器会在系统文件目录下查找。

2,用户自定义的文件用双引号括起来,编译器首先会在用户目录下查找,然后在到C++安装目录(比如VC中可以指定和修改库文件查找路径,Unix和Linux中可以通过环境变量来设定)中查找,最后在系统文件中查找。

#include “"xxx.h”(我一直以为””和<>没什么区别,但是tinyxml.h是非系统下的都文件,所以要用””)

二、头文件如何来关联源文件

这个问题实际上是说,已知头文件“a.h”声明了一系列函数,“b.cpp”中实现了这些函数,那么如果我想在“c.cpp”中使用“a.h”中声明的这些在“b.cpp”中实现的函数,通常都是在“c.cpp”中使用#include “a.h”,那么c.cpp是怎样找到b.cpp中的实现呢?

其实.cpp和.h文件名称没有任何直接关系,很多编译器都可以接受其他扩展名。比如偶现在看到偶们公司的源代码,.cpp文件由.cc文件替代了。

在Turbo C中,采用命令行方式进行编译,命令行参数为文件的名称,默认的是.cpp和.h,但是也可以自定义为.xxx等等。

谭浩强老师的《C程序设计》一书中提到,编译器预处理时,要对#include命令进行“文件包含处理”:将file2.c的全部内容复制到#include “file2.c”处。这也正说明了,为什么很多编译器并不care到底这个文件的后缀名是什么----因为#include预处理就是完成了一个“复制并插入代码”的工作。

编译的时候,并不会去找b.cpp文件中的函数实现,只有在link的时候才进行这个工作。我们在b.cpp或c.cpp中用#include “a.h”实际上是引入相关声明,使得编译可以通过,程序并不关心实现是在哪里,是怎么实现的。源文件编译后成生了目标文件(.o或.obj文件),目标文件中,这些函数和变量就视作一个个符号。在link的时候,需要在makefile里面说明需要连接哪个.o或.obj文件(在这里是b.cpp生成的.o或.obj文件),此时,连接器会去这个.o或.obj文件中找在b.cpp中实现的函数,再把他们build到makefile中指定的那个可以执行文件中。

在Unix下,甚至可以不在源文件中包括头文件,只需要在makefile中指名即可(不过这样大大降低了程序可读性,是个不好的习惯哦^_^)。在VC中,一帮情况下不需要自己写makefile,只需要将需要的文件都包括在project中,VC会自动帮你把makefile写好。

通常,编译器会在每个.o或.obj文件中都去找一下所需要的符号,而不是只在某个文件中找或者说找到一个就不找了。因此,如果在几个不同文件中实现了同一个函数,或者定义了同一个全局变量,链接的时候就会提示“redefined”。

内部连接和外部连接:

编译时每个文件会被编译成一个含有必要信息的源文件(又叫编译单元),然后编译单元会联结成一个和主文件同名的.o文件,.o文件把不同的编译单元中产生的符号联系起来,构成一个可执行文件。有两种截然不同的链接:内部的和外部的,将这些编译单元联系起来。

内部连接:对这个定义的访问被局限在当前编译单元,其他编译单元无法访问。

外部连接:可被其他单元访问,因此名称在整个执行文件中必须唯一。

类的定义(同时也是声明),enum,struct,都是内部连接,内联函数,静态的非类成员数据也是

typedef声明的类型也是内联结。

非内联成员函数(包括静态成员)有外部连接,非内联函数,非静态自由函数(非类的成员函数)也是外连接。

声明只对当前编译单元有用,他们不会影响到.o文件

.h文件,由于该文件会被其他.cpp文件包含,但由于声明只是对当前编译单元有效,是不会将符号引入.o文件,所以该文件不能含有任何外部连接的符号(数据成员和函数)的定义。一般情况下也不要包含内连接符号的定义。

综上所诉:

.h文件中能包含:

1。类成员数据的声明,但不能赋值

2.类静态数据成员的定义和赋值,但不建议,只是个声明就好。

3。类的成员函数的声明

4。非类成员函数的声明

5.常数的定义:如:const int a=5;

6.静态函数的定义

7.类的内联函数的定义

不能包含:

1. 所有非静态变量(不是类的数据成员)的声明

2。 默认命名空间声明不要放在头文件,using namespace std;等应放在.cpp中,在.h文件中使用std::string

http://blog.csdn.net/pjw100/archive/2010/01/18/5208879.aspx

----------------------------------------------------------------------------------------------------------------------

编译器不管头文件的,头文件只是用来被cpp文件包含的,被包含之后,它就成了那个cpp文件的一部分了,而编译器只编译.cpp文件,不会去单独编译一个头文件的。编译器这样做之后,针对每个编译过的cpp文件生成一个obj文件。然后连接器把所有这些obj文件连接成一个程序,或能是exe或dll(或做成静态的lib)。如果在连接的过程中,有些实体(比如变量或函数)找不到定义,则会报link错误。

我们通常把类的定义都放在头文件,而其成员函数以及静态成员变量的定义都放在一个主名相同,扩展名不同的cpp文件——这只是一种风格和传统,而不是C++语言规定的。

如果你不嫌乱,你当然可以把所有的代码都放到一个cpp文件中,整个工程就一个源文件。

你也可以把一个类的10个函数分别在10个不同的cpp文件中实现,甚至有4个实现在cpp文件中,另外3个是打包在以前做好的静态库(lib)中,还有3个内联定义在头文件中——都没问题。只要每个cpp文件都能顺利通过编译,而且连接器在连接时都能找到这些定义就OK了。

C头文件和源文件的连的更多相关文章

  1. 理解C++中的头文件和源文件的作用【转】

    一.C++编译模式通常,在一个C++程序中,只包含两类文件--.cpp文件和.h文件.其中,.cpp文件被称作C++源文件,里面放的都是C++的源代码:而.h文件则被称作C++头文件,里面放的也是C+ ...

  2. C++基础之头文件和源文件的关系

    今天找了个解析xml的开源C++项目tinyxml,按照网上的说法去编译,但是一直编译不通过,"无法打开头文件tinyxml.h",但是明明我在工程底下有了这个文件,对于我这种初学 ...

  3. idea 开发javaee 时,出现访问的文件和源文件不一样,没有正常更新的解决方案

    这是因为我配置的idea debug 运行模式 输出的文件在 out 和 target 目录下,因为idea本身的原因,导致这两个目录没有及时更新, 导致前端在访问时的页面源码和ide中的一直不一样, ...

  4. C++学习笔记(一):头文件和源文件

    说明: 当一个源文件(a.cpp)要调用另一个源文件(b.cpp)定义的方法时,需要在a.cpp中写上这个方法的声明(只需要该方法的名称.返回值和参数,类似Java的接口): 如果每次调用其他文件的方 ...

  5. C语言中,头文件和源文件的关系(转)

    简单的说其实要理解C文件与头文件(即.h)有什么不同之处,首先需要弄明白编译器的工作过程,一般说来编译器会做以下几个过程: 1.预处理阶段 2.词法与语法分析阶段 3.编译阶段,首先编译成纯汇编语句, ...

  6. C++中的头文件和源文件

    一.C++编译模式 通常,在一个C++程序中,只包含两类文件——.cpp文件和.h文件.其中,.cpp文件被称作C++源文件,里面放的都是C++的源代码:而.h文件则被称作C++头文件,里面放的也是C ...

  7. 学习:C++中的头文件和源文件详解

    一.C++编译模式: 通常,在一个C++程序中,只包含两类文件――.cpp文件和.h文件.其中,.cpp文件被称作C++源文件,里面放的都是C++的源代码:而.h文件则被称作C++头文件,里面放的也是 ...

  8. c语言头文件和源文件不在同一个目录

    http://www.cnblogs.com/ShaneZhang/archive/2013/05/20/3088688.html 从工程上讲,头文件的文件名应该与对应的源文件名相同便于维护,如果头文 ...

  9. C++中头文件(.h)和源文件(.cpp)都应该写些什么

    头文件(.h): 写类的声明(包括类里面的成员和方法的声明).函数原型.#define常数等,但一般来说不写出具体的实现. 在写头文件时需要注意,在开头和结尾处必须按照如下样式加上预编译语句(如下): ...

随机推荐

  1. [ACM_模拟] ZJUT 1155 爱乐大街的门牌号 (规律 长为n的含k个逆序数的最小字典序)

    Description ycc 喜欢古典音乐是一个 ZJUTACM 集训队中大家都知道的事情.为了更方便地聆听音乐,最近 ycc 特意把他的家搬到了爱乐大街(德语Philharmoniker-Stra ...

  2. [C++] socket -8 [命名管道]

    ::命名管道不但能实现同一台机器上两个进程通信,还能在网络中不同机器上的两个进程之间的通信机制.与邮槽不同,命名管道是采用基于连接并且可靠的传输方式,所以命名管道传输数据只能一对一进行传输. /* 命 ...

  3. 免费好用的web应用托管平台-续

    上一篇博客给大家推荐了目前处于免费阶段的PAAS平台,可以托管各种应用,大家反响很不错,说明大家还是很需要和认可这个免费托管各种web应用的京东云擎平台.但是很多用户还是很担心未来可能还是会收费,对于 ...

  4. JS原型链简单图解

    JS中原型链,说简单也简单. 首先明确: 函数(Function)才有prototype属性,对象(除Object)拥有__proto__. 首先,我画了一张图. 所谓原型链,指的就是图中的proto ...

  5. js 停止事件冒泡 阻止浏览器的默认行为(阻止超连接 # )

    在前端开发工作中,由于浏览器兼容性等问题,我们会经常用到“停止事件冒泡”和“阻止浏览器默认行为”. 1..停止事件冒泡 JavaScript代码 //如果提供了事件对象,则这是一个非IE浏览器if ( ...

  6. 连接Oracle错误:800a0e7a未找到提供程序的解决

    一.现象: C#程序中需要以Provider=OraOLEDB.Oracle.1方式访问ORACLE数据库.但程序执行时报异常:未在本地计算机注册“OraOLEDB.Oracle.1”提供程序 二.解 ...

  7. 几种你不知道的获取浙A牌照的方法

    http://www.19lou.com/forum-464848-thread-18191429174490953-1-1.html 杭州限牌政策执行已有一年多,因为限牌政策,很多人买车之前,都不得 ...

  8. Python 3 数值计算

    Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:43:06) [MSC v.1600 32 bit (Intel)] on win32Type & ...

  9. oprofile

    一.原理 在关注事件发生一定次数时,进行一次采样,记录下需要的信息(比如指令寄存器或栈寄存器信息). 二.参数 项 说明 eventname   要关注的事件名称,常用的事件名称及功能如下:   CP ...

  10. Linux 下安装Samba 文件共享服务器

    samba文件共享服务可以让linux和linux系统.linux和windows系统之间共享文件 服务查询 默认情况下,Linux系统在默认安装中已经安装了Samba服务包的一部分,为了对整个过程有 ...