一、函数基础
一个函数(function)定义包括:返回类型、函数名字、0或若干个形参组成的列表以及函数体。
实参是形参的初始值,并且实参的类型必须与对应的形参类型匹配,函数的形参列表可以为空,但是不能省略,一般是书写一个空的形参列表,也可以使用关键字void表示函数没有形参
void f1(){/*...*/} //隐式地定义空形参列表
void f2(void){/*...*/} //显示地定义空形参列表
大多数类型都能作为函数的返回类型,void类型表示不返回任何值,函数的返回类型不能是数组类型或函数类型,但可以是指向数组或函数的指针。
1.2 局部对象
C++中,名字有作用域,即程序文本的一部分;对象有声明周期,是程序执行过程中该对象存在的一段时间。
形参和函数体内部定义的变量统称为局部变量(local variable),它们仅在函数的作用域内可见,并隐藏在外层作用域中同名的其他所有生命之中。
自动对象(automatic object)指只存在于执行期间的对象,即当函数控制路径经过变量定义语句时创建该对象,当达到定义所在块末尾时销毁它,这时自动对象的值就变成未定义的了,形参是一种自动对象。
有时候需要令局部变量的生命周期贯穿函数调用及之后的时间,这时可以将局部变量定义为static类型,即局部静态对象(local static object),其在程序执行路径第一次经过对象定义语句时初始化,并直到程序终止才被销毁。
1.2 函数声明
函数的名字必须在使用之前声明,与变量类似,函数只能定义一次,但可以声明多次,函数的声明与定义的唯一区别是函数声明无须函数体,用一个分好替代即可,函数声明也称作函数原型(function prototype)。
一般地,与变量相似,函数在头文件中声明,在源文件中定义,定义函数的源文件应该含有函数声明的头文件包含进来,编译器负责验证函数的定义和声明是否匹配。
1.3 分离式编译
随着程序越来越复杂,一般吧程序的各个部分分别存储在不同的文件中,为了允许编写程序时按照逻辑关系将其划分开来,C++语言支持分离式编译(separate compilation)。
二、参数传递
形参的类型决定了形参与实参交互的方式,如果形参是引用类型,它将绑定到对应的实参上,否则将实参的值拷贝后赋给形参。
当形参是引用类型时,称它对应的实参被引用传递,引用形参也是它绑定对象的别名,即形参是其对应实参的别名。当实参的值被拷贝给形参时,形参和实参是两个独立的对象,我们称实参被值传递。
2.1 传值参数
初始化一个非引用类型的变量时,初始值被拷贝给变量,此时对变量的改动不会影响初始值。
指针的行为和其他非引用类型一样,当执行指针拷贝操作时,拷贝的是指针的值,拷贝之后两个指针是不同的指针。
int n = 0,i = 42;
int *p = &n,*q = &i; //p指向n,q指向i
*p = 42; //n的值改变,p不变
p=q; //p指向i,但i和n的值都不变
指针形参的行为与上述相似:
void reset(int *ip)
{
*ip = 0; //改变指针ip所指对象的值
ip = 0; //只改变了ip的局部拷贝,实参未被改变
}
调用reset函数之后,实参所指的对象被置为0,但是实参本身并没有改变:
int i = 42;
reset(&i); //改变i的值而非i的地址
cout <<