6-1 函数基础
6.1.1 局部变量
变量分类
变量类型 | 作用域 | 生命期 | 初始化 |
---|---|---|---|
全局对象 | 整个程序 | 整个程序 | 默认初始化 |
自动对象 | 块作用域 | 声明时自动创建,出作用域后自动销毁 | 默认初始化 |
局部静态对象 | 块作用域 | 整个程序 | 值初始化 |
- 自动变量会多次创建和初始化,全局对象和局部静态变量只会创建和初始化一次
- 值初始化时内置类型初始化为0
//举例: 用局部静态变量统计某函数的调用次数
#include<iostream>
using namespace std;
int cout_calls(){
static int num = 0;
return ++num;
}
int main(){
for(int i = 0; i < 10; ++i)
cout << cout_calls() << endl;
return 0;
}//输出:0、1、2、......、10
6.1.2 函数的声明
-
也称函数原型,只需包含函数的三要素,不必包含函数体(也就是不必实现函数)
- 返回类型
- 函数名
- 形参列表
int cout_calls(int val);
就是一条函数声明
-
在工程项目中,函数声明最好包含在头文件中
看起来把函数的声明直接放在使用该函数的源文件中是合法的,也比较容易被人接受;但是这么做可能会很烦琐而且容易出错。相反,如果把函数声明放在头文件中,就能确保同一函数的所有声明保持一致。而且一旦我们想改变函数的接口,只需改变一条声明即可。
6.1.3 分离式编译
概念
分离式概念随着程序越来越复杂,我们希望把程序的各个部分分别存储在不同文件中。为了允许编写程序时按照逻辑关系将其划分开来,C++语言支持所谓的分离式编译(separate compilation)。分离式编译允许我们把程序分割到几个文件中去,每个文件独立编译。
-
g++ -c helloworld.cpp
:生成目标文件helloworld.o -
g++ helloworld.o
:生成可执行文件a.exeg++ helloworld.o -o main.exe
:生成可执行文件main.exe
-
./a.exe
:运行a.exe
编译和链接多个文件
举个例子,假设fact函数的定义位于一个名为 fact.cpp 的文件中,它的声明位于名为 fact.h 的头文件中。显然与其他所有用到fact函数的文件一样,fact.cpp应该包含fact.h头文件。另外,我们在名为 factMain.cpp的文件中创建main函数,main函数将调用fact函数。要生成可执行文件(executable file),必须告诉编译器我们用到的代码在哪里。
fact.h
#ifndef FACT_H
#define FACT_H
int fact(int val);
#endif
fact.cpp
#include"fact.h"
int fact(int val){
int res = 1;
while(val > 1)
res *= val--;
return res;
}
factMain.cpp
#include<iostream>
#include"fact.h"
using namespace std;
int main(){
int val = 5;
cout<<fact(val)<<endl;
return 0;
}
-
编译
g++ -c fact.cpp
:生成目标文件fact.og++ -c factMain.cpp
:生成目标文件factMain.o
-
生成可执行文件a.exe
g++ fact.o factMain.o
-
执行a.exe
./a.exe