C++ Primer第六章①
C++ Primer
第六章 函数
这一章厉害了,有很多麻烦又好玩的东西,我应该会分六到七节来写,大家好好看,很有营养哦~ 先介绍函数的定义和声明,包括参数传递和函数返回;重载函数,就是几个不同的函数用同一个函数名;如何匹配调用,就是你调用的是谁;最后介绍函数指针(指针真是哪里都有)
函数基础
编写函数:
//写个简单的求阶乘函数
int fact(int val) //第一个int是函数返回类型,fact是函数名,
//int val是形参列表,这里只有一个
//下面花括号是函数体
{
int ret = 1;
while(val > 1)
{
ret *= val;
--val;
}
return ret; //返回类型一定得匹配,这里是int
}
如何调用函数:
int j = fact(5); //求5的阶乘
cout << j << endl;
函数的调用在主函数中完成两项工作:
- 用实参初始化对应的形参(5对应val)
- 将控制权转移给被调用函数(main()-->fact())
被调用函数的执行过程:
- 定义并初始化形参,当调用fact函数时,首先创建一个名为val的int变量(也就是说在定义函数的时候并没有创建val,所以说它是形式参数嘛,就是个形式,就跟一些空头项目一样,根本没做)。
- 遇到一条return语句时,结束执行过程,return语句完成两项工作:
- 返回return语句中的值
- 将控制权还给主调函数
形参和实参
一句话:用实参按顺序初始化形参,所以啊,实参类型必须和对应的形参类型匹配://错误调用示例 fact("hey"); fact(); fact(42, 10); //正确调用示例 fact(3.14) //等价于fact(3);隐式转换
函数的形参列表
可以为空:
可以多个:int f1(){ } //隐式定义空形参列表 int f2(void){ } //显式定义空形参列表
int f3(int v1, int v2){ } //用逗号隔开,一个类型一个变量名对应,变量名不能同名
函数返回类型
大多数类型都能用作函数的返回类型。一种特殊的返回类型为void,表示不返回任何值。 函数的返回类型不能是数组类型(因为数组不能被拷贝)或函数类型(目前不知道为啥),但是我们有指针啊,可以返回指向数组或者函数的指针就好了(慢着,函数也有指针,有的啊,这章后面就会介绍)局部对象
大部分变量都是局部变量,因为我们小程序员不太敢污染全局空间,局部变量还有个神奇的地方:
你猜会报错吗?不会报错的话输出是啥?答案是1 0,给你个代码自己体会吧。int a = 0; { int a = 1; cout << a << endl; } cout << a << endl;
自动对象:只存在于块执行期间的对象称为自动对象,比如里面的a,还有我们的形参,都是自动对象。
局部静态对象(只被定义初始化一次,可以一直用它)
有些时候,有必要让局部变量不销毁一直在,例如,下面的函数统计它自己被调用了多少次:
补充一句,如果静态变量没有显式的初始值,它将执行默认初始化。int count() { static int cnt = 0; //这个就是局部静态对象,这句话只在第一次调用时执行, //而且调用结束后,这个值仍然有效,是不是很厉害啊 return ++cnt; } int main() { for(int i = 0; i<10; ++i) { cout << count() << endl; } return 0; }
函数声明和分离式编译
函数和变量一样,名字必须在使用前声明,定义一次,声明多次,即制造一次,使用多次。 函数的声明和函数的定义非常类似,唯一的区别就是函数声明无须函数体,用一个分号代替:
说函数声明是啥目的呢?就是我们C++要支持分离式编译,在源文件中定义了一个函数,然后我们其他文件想去使用它(偷懒,自己不定义),所以我们要声明一下,你这个函数借我用一下,声明也同时告诉我们这个函数怎么用。 Plus: 定义函数的源文件还要把含有函数声明的头文件包含进来,目的是:编译器来验证函数的定义和声明是否匹配。int fact(int val); //函数三要素(返回类型,函数名,形参类型)描述了函数接口 //也就是说明了调用该函数所需的全部信息