03.函数
函数声明与调用
最好应把函数的声明写在主函数前面,函数的具体实现写在主函数后面。C/C++是一趟编译的语言,要想使用一个函数,必须在使用函数前有该函数的声明,否则无法使用。
函数调用
主调(客户)函数与被调(服务器)函数
函数调用时的参数与返回值
函数原型
函数的实现与调用格式说明:作为函数接口
一般出现在头文件中
格式:函数返回值类型 函数名称(形式参数列表);
例一:
int Add(int x, int y);
例二:
void Swap(int x, int y);
函数定义
int Add(int x, int y)
{
int t;
t = x + y;
return t;
}
void Swap(int x, int y)
{
int t;
t = x;
x = y;
y = t;
return; //因函数没有返回值,只需直接列出return语句。return在函数末尾时也可以省略。
}
函数实现
函数定义,使用编程语言给出函数的执行步骤
函数返回值
函数完成后带回来的结果
主调函数可以使用
int Compare(int x, int y)
{
int t;
if(x == y)
t = 0;
else if(x > y)
t = 1;
else
t = -1;
return t;
}
//允许函数中包含多个return语句
//函数在执行到第一条return语句后终止
int Compare(int x, int y)
{
if(x == y)
return 0;
else if(x > y)
return 1;
else
return -1;
}
谓词函数
返回bool类型值的函数
表达某项任务是否完成或某个条件是否满足
bool IsLeap(int year)
{
return year % 4 == 0 && year & 100 != 0 || year % 400 == 0;
}
函数重载
定义同名但参数不完全相同的函数(参数个数、参数类型、参数的顺序可以不相同)
实例:
int Max(int x, int y);
char Max(char x, char y);
bool Max(bool x, bool y);
函数调用规范
函数调用示例
编写程序讲用户输入的两个整数相加,要求尽可能使用函数将程序中的操作独立出来。
#include<iostream>
using namespace std;
void Welcome();
int GetInteger(int idx);
int Add(int x, int y);
void Print(int x, int y);
int main()
{
int a, b;
Welcome();
a = GetInteger(1);
b = GetInteger(2);
Print(a, b);
return 0;
}
void Welcome()
{
cout<<"The program gets two integers, and prints their sum."<<endl;
return;
}
int GetInteger(int idx)
{
int t;
cout<<"No."<<idx<<" ";
cin>>t;
return t;
}
int Add(int x, int y)
{
return x + y;
}
void Print(int x, int y)
{
cout<<x<<" + "<<y<<" = "<<Add(x, y)<<endl;
return;
}
参数传递机制:值传递与引用传递
值传递机制
- 形式参数在函数调用时才分配存储空间,并接受实际参数的值
- 实际参数可以为复杂的表达式,在函数调用前获得计算
- 形式参数与实际参数可同名,也可不同名
- 参数较多时,实际参数值逐一赋值,它们必须保持数目、类型、顺序的一致
- 值的赋值过程是单向不可逆的,函数内部对形式参数值的修改不会反映到实际参数中去
- 函数参数一般为函数输入集的一部分,函数输出集一般使用返回值表示,只有使用特殊的手段才可以将函数参数作为函数输出级的一部分。
函数调用栈框架
示例:
#include<iostream>
using namespace std;
void Welcome();
int GetInteger(int idx);
void Swap(int x, int y);
int main()
{
int a, b;
Welcome();
a = GetInteger(1);
b = GetInteger(2);
cout<<"In main(): a: "<<a<<"; b: "<<b<<endl;
Swap(a,b);
cout<<"In main(): a: "<<a<<"; b: "<<b<<endl;
return 0;
}
void Welcome()
{
cout<<"The program swap the two integer's value."<<endl;
}
int GetInteger(int idx)
{
int t;
cout<<"No."<<idx<<" ";
cin>>t;
return t;
}
void Swap(int x, int y)
{
cout<<"In Swap(): x: "<<x<<"; y: "<<y<<endl;
int t;
t = x;
x = y;
y = t;
cout<<"In Swap(): x: "<<x<<"; y: "<<y<<endl;
}
程序运行结果:
The program swap the two integer's value.
No.1 3
No.2 4
In main(): a: 3; b: 4
In Swap(): x: 3; y: 4
In Swap(): x: 4; y: 3
In main(): a: 3; b: 4
程序实际未能将a、b互换,因为值的赋值过程是单向不可逆的,函数内部对形式参数值的修改不会反映到实际参数中去.
要真正互换a、b的值需将a、b定义为全局变量,写在所有函数声明的前面,a、b可以被所有的函数使用。程序变为:
#include<iostream>
using namespace std;
int a, b; //全局数据对象声明,以保证所有函数都可以访问这两个数据对象
void Welcome();
int GetInteger(int idx);
void Swap(); //不再需要函数参数
int main()
{
int a, b;
Welcome();
a = GetInteger(1);
b = GetInteger(2);
cout<<"In main(): a: "<<a<<"; b: "<<b<<endl;
Swap();
cout<<"After Swap,In main(): a: "<<a<<"; b: "<<b<<endl;
return 0;
}
void Welcome()
{
cout<<"The program swap the two integer's value."<<endl;
}
int GetInteger(int idx)
{
int t;
cout<<"No."<<idx<<" ";
cin>>t;
return t;
}
void Swap() //可以直接访问a、b
{
int t;
t = a;
a = b;
b = t;
}
程序运行结果:
The program swap the two integer's value.
No.1 1
No.2 2
In main(): a: 1; b: 2
After Swap, in main(): a: 1; b: 2
虽然这样可以交换a、b的值,但却因此定义了不必要的全局变量,本无需访问a、b的Welcome()也可访问对a、b。应尽量避免这类做法,换而使用引用传递的方法。