一.
头文件:不参与编译,变量的声明,函数的声明,类的定义.
源文件:自上而下独立编译,变量的定义,函数的定义,成员定义初始化
头文件里放变量的声明不能放定义,因为当两个及以上的文件引用该头文件就会发生重定义的错误。函数也同理。
extern int a;//变量的声明,注意不能赋值,如果赋值则为非法声明
extern int a;//可以声明多份
int b;//此为定义。
extern关键字:
在源文件A里定义的函数,在其它源文件里是看不见的(即不能访问)。为了在源文件B里能调用这个函数,应该在B的头部加上一个外部声明:
extern 函数原型;
这样,在源文件B里也可以调用那个函数了。
注意这里的用词区别:在A里是定义,在B里是声明。一个函数只能(也必须)在一个源文件里被定义,但是可以在其它多个源文件里被声明。定义引起存储分配,是真正产生那个实体。而声明并不引起存储分配。
当一个函数或者变量在.h文件中被extern修饰声明了,这就是在告诉编译器该函数可以跨文件使用。别的源文件要使用该函数或者变量只要包含该头文件即可。
//头文件中类的定义
class te
{
public:
int m_a;
te();
void show1();
~te();
static void show2();//静态函数
void show3() const;//常函数
virtual void show4();//虚函数
};
//源文件的成员函数的实现
#include"aa.h"
te::te()
{
m_a = 10;
}
void te::show1()
{
cout << m_a << endl;
}
te::~te()
{}
void te::show2(){}//静态函数源文件中不用static修饰
void te::show4()}{}//虚函数也不用virtual修饰
void te::show3()const{}//常函数要用const修饰
#pragma once:预处理的命令,告诉编译器,当前头文件在某个源文件中只包含一次。可以解决头文件重复包含的问题。还可以用宏判断的方式来解决,#ifndef.....#define....#endif
二.程序的生成过程
1.预处理:头文件的展开。宏的替换,预处理指令解析。去掉注释。(.i文件)
2.编译: 词法解析,语法解析,语意生成。预处理后的文件进一步处理(生成汇编文件.asm)
3.汇编:汇编文件进一步处理,生成目标机器指令(二进制文件.obj)
4.链接:将多个目标文件(库文件)链接生成可执行程序(.exe)
三.
宏的定义一般放在头文件里。宏作用就是用于替换,但不会做表达式的计算和求解。
#define aa 10 //将aa替换为10
#define bb for(int i=0;i<aa;i++)\ //也可以替换多行。“\”用于链接本行和下一行,其
{ cout<<"sad "<<endl;\ //后面不加任何东西,且最后一行不加"\"
}
#define dd(num) for(int i=0;i<num;i++)\ //也可以传参数
{ cout<<"dd "<<endl;\
}