为了允许把程序拆分成多个逻辑部分来编写,C++语言支持分离式编译机制,该机制允许将程序分割成若干个文件,每个文件可被独立编译。就比如,std::cout,std::cin他们定义于标准库,却能被我们写的程序使用。
为了支持分离式编译,C++语言将声明和定义分开。
我在b站看了一个视频,虽然是C语言。
函数
/*
* 定义(英文教材中称为:定义性声明)与声明(引用性声明)
* 1.定义是需要分配内存空间的,而声明则不需要
* 2.定义只能定义一次,重复定义会有语法错误,声明可以多次
* 3.如果想声明一个变量而非定义它,就在变量名前添加关键字extern,而且不要显式地初始化变量
函数可以定义可以声明
全局/局部变量可以定义,可以声明(这个地方和视频不一样,视频里是C语言)
*/
int main() {
return 0;
}
//这里我们定义两次函数
void fun() {
}
void fun() {
}
报错
#include<iostream>
int main() {
void fun();//声明(引用性声明),如果不声明,main函数并不知道有fun()
void fun();
void fun();//声明可以多次
fun();//执行fun函数
return 0;
}
//定义函数
void fun() {
std::cout << "I'm fun.Thank you,and you?";
}
执行成功,没有报错
我想试试如果直接在main函数体内定义fun函数,是不是就不用声明了。
任何一个C++程序都包含一个main函数,这是规定。main函数由系统直接调用,是程序执行的入口。
main函数与用户自己定义的函数都是各自独立的模块,即函数不能嵌套定义,通俗的说,你不能在一个函数的函数体内定义另一个函数,即使在main函数中也不行。但main函数可以对用户自己定义的函数进行调用(但main函数只能由系统调用)。用户自己定义多个函数时,这几个用户自己定义的函数之间都可以互相调用。
我想多了,我是傻狗。
这一次把fun函数定义在另外一个文件中,然后在main函数内声明,并执行,看看效果。
或者这样子
int main() {
extern void fun();
fun();
}
顺利执行。
变量
#include<iostream>
int main() {
std::cout << a;
}
int a;
报错
在main函数体内没有对a进行声明,接下来我们对a进行声明,但我们没有使用关键字extern
#include<iostream>
int main() {
int a;
std::cout << a;
}
int a;
也是不可以的,所以想要声明变量,我们应该使用关键字extern。这里在main函数内使用int a;相当于在函数作用域内,定义了一个名为a的局部变量,但是函数内部的变量初始化必须显式初始化变量。
添加后执行成功,输出0,因为int类型默认初始化的值为0.
也可以像函数那样,在另外一个文件中定义a,在main函数中声明,一样可以使用
几种比较奇怪的情况
1.任何包含了显式初始化的声明即成为了定义。
extern int a = 10;
在上面的代码中,我们给extern关键字标记的变量赋一个初始值,但是这么做也就抵消了extern的作用,语句也从声明变成了定义。
2.我们可以在两个文件中都使用extern int a;语句,编译时没有报错,但是,调试时不会通过。因为我们只有对a的声明,却从未定义过a
3.在视频下面的评论区,有人说
#include<iostream>
int main() {
int b = 20;
extern int b;
std::cout << b;
}
这段代码没法运行,但是我的倒是可以运行。。。。。
并且视频里不用extern就能声明变量,但是在C++里面好像必须加上extern才能声明变量。C语言和C++也是有差异的。。。
书中的截图。
C++是一种静态类型的语言,在编译阶段检查类型。
如果试图执行类型不支持的运算,编译器将报错并且不会生成可执行文件。
静态类型检查有助于发现问题,然而前提是编译器必须知道每一个实体对象的类型,这就要求我们使用某个变量之前必须声明其类型