目录
1 函数基础
1.1 函数定义
基础,略。
1.2 函数调用
基础,略。需要注意的是,return语句的作用除了给主调函数传递被调函数的返回值,另一层意义在于将程序的控制权交还给主调函数。
1.3 形参与实参
- 实参是形参的初始值,其值用来初始化形参对象。
- 实参与形参按对应进行初始化,第一个实参初始化第一个形参,第二个实参初始化第二个形参。
- 并不规定实参的求值顺序,编译器可以按照任意可行的顺序对实参求值。
- 实参的类型必须与对应的形参类型匹配,除非可以完成(隐式的)类型转换。
范例:
// 定义一个名为fact的函数,其参数列表接收一个int类型对象,用来计算val的阶乘,并将结果以一个int类型返回
int fact(int val) {
int ret = 1; //局部变量,生命周期为函数体内,用于保存阶乘计算结果
while (val > 1) {
ret += val--; //把ret和val的乘积赋给ret,然后将val减1
}
return ret; //将ret的值作为结果返回给主调
}
int main() {
fact("hello"); //❌,实参类型不正确且不能完成隐式类型转换
fact(3.14); //正确,该实参能隐式转换为int类型,执行调用时,隐式地截取小数部分转成int类型,调用等价于fact(3);
}
形参列表:
- 显示定义空参列表的方式:在参数列表内写void,如int func(void) {…}
- 形参可以仅指定类型而不给名字,但未命名的形参无法被使用,这种未命名的形参代表在函数体内不会使用它
- 形参是否命名不影响调用时提供的实参数量,即使某个形参未命名,调用时也必须为它提供一个实参。
1.4 返回类型
- void返回类型,代表函数不返回任何值,结束调用时仅交还控制权限。有返回值的函数通常用于计算某个值,无返回值的函数通常用来执行某些动作。
- 函数的返回类型不能是数组类型或函数类型,但可以是指向数组或函数的指针。
1.5 局部对象
在C++中,名字(程序文本中的命名符号)有作用域,对象(内存中真实的存储实体)有生命周期。
函数的形参和函数体内部定义的变量统称为局部变量。
- 从名字的角度上来说:它们对于函数来说是“局部的”。它们的名字仅在函数的作用域内可见,并且在函数内部,它们会隐藏外层作用域中同名的名字。
- 从对象的角度上来说:局部变量(对象)的生命周期取决于其定义的方式(分为自动对象和局部静态对象)。与之相对的是,在所有函数体(包括main函数)之外定义的对象,存在与程序的整个执行过程中,这种对象在程序启动时被创建,直到程序结束才会被销毁。
1.5.1 自动对象
自动对象是只存在于函数块执行期间的对象。也就是普通局部变量所对应的对象,当函数执行路径经过函数块内的变量定义语句时创建该对象,到达定义所在的块末尾时销毁它。当块执行结束后,块中创建的自动对象的值为未定义。形参也是一种自动对象。
1.5.2 局部静态对象
局部静态对象的作用是:绕开【函数外定义对象,并通过函数改变其值】的方法,使得函数内定义的对象可以在函数执行完调用后仍能在函数外使用。通过将局部变量定义前加static修饰符获得这样的局部静态对象,其生命周期贯穿函数调用及调用之后。局部静态对象在程序的执行路径第一次经过其对象定义语句时初始化,直到整个程序终止才销毁。
范例:
int val = 10; //这里的val是定义在所有函数外的(此程序中的)全局量,在整个程序结束后才会销毁
int func() {
int val = 0; //该函数中定义了一个名为val的局部变量,val这个名字仅在函数内可见,对于函数func来说,其内部使用到的所有val代表的都是这里定义的这个val,而不是在func以外定义的那个val
return ++val;
}
int count1 = 0; //count1是定义在所有函数外的(此程序中的)全局量
int count_call1(int count) {
return ++count;
}
int count_call2