6.4 函数调用
在前面的代码中,读者已经知道了如何调用一个函数,函数定义和函数声明的目的都是为了函数调用,只有函数调用才能利用函数实现某个功能,函数调用的基本形式如下所示。
函数名(实参列表);对于无参函数,其调用形式如下所示。 函数名();
函数调用由函数名和函数调用运算符()组成,()内有0个或多个逗号分隔的参数(称为实参)。每一个参数是一个表达式,且参数的个数与参数的类型要与被调函数定义的参数(称为形参)个数和类型匹配,首先计算参数表达式的值,并将此值传递给形参。如果函数调用后有返回值,调用表达式可以用在表达式中,如代码6.1中的“int numTotal=add(num1,num2);”,而无参函数的调用必须是一个单独的语句,如“print();”。
函数调用的主要作用有以下3个。
❑用实参向形参传递数据;
❑为获得数据的参数和函数中声明的变量分配临时存储空间;
❑中断当前正在运行的上级调用函数,将程序流程转到被调用函数的入口处。
6.4.1 形参和实参
形参和实参,类似于剧本角色和演员的关系,同一个角色可以由不同的演员来扮演,只有在演员扮演的过程中,角色才是鲜活、有意义的。前面的章节已经提到,在函数定义时,并不会为参数列表中的参数分配内存空间,只有在函数调用时,才为形参分配内存空间,并用实参的值为其赋值,在执行到函数结束时,程序会撤销调用过程中为参数和中间变量分配的内存空间。
代码6.4 演示了形参和实参的关系。
代码6.4 形参和实参ParameterAndArgument
<————————————-文件名:example604.cpp——————————————-> 01 #include<iostream> 02 using namespace std; 03 int main() 04 { 05 int n=2; 06 cout<<"地址:"<<&n<<endl;//输出实参变量n的地址 07 cout<<"数值:"<<n<<endl; 08 void print(int);//函数声明 09 print(n);//函数调用 10 return 0; 11 } 12 void print(int n)//函数定义 13 { 14 cout<<"地址:"<<&n<<endl;//输出形参n的地址 15 cout<<"数值:"<<n<<endl; 16 }
输出结果如下所示。
地址:0013FF7C 数值:2 地址:0013FF2C 数值:2
【代码解析】main()函数中的变量n和代码第9行print()函数中的参数n占据不同的内存地址,这说明在调用print()函数时,编译器为形参n分配了内存空间,并将main()函数中变量n的值赋给这块内存区域,在结束后这块内存区域将被释放。
main()函数中的变量n和print()函数中的形参n(甚至是在print()函数内部声明的变量)是完全不同、毫无关系的。在函数内声明的变量是该函数私有的,外部不可见的,因此,对函数中变量n的操作不会影响main()函数中n的数据,因为形参只是实参的复制,而不是原来的数据。