函数
I. 函数的声明与调用
1.函数调用
- 主调(客户)函数与被调(服务器)函数
- 客户函数和被调函数会传递一些信息:函数调用时的参数与返回值
- 例一:
Swap(a,b);
- a, b 是传入的参数值, Swap函数把a, b 值互换, 所以没有返回值,返回值为空 - 例二:
n = Add(a, b)
- a, b 是传入的参数, 此函数会带回来一个结果 即 加法和,这里就会返回一个返回值
2.函数原型
- 函数的实现与调用格式说明: 作为函数接口, 一般出现在头文件中
- 格式:
函数返回值类型 函数名称(形式参数列表)
- 例一:
int Add(int x, int y);
- 例二:
void Swap(int x, int y);
- 例三:
void Compute();
II. 函数定义
不仅可以使用标准库中的函数,还可以自己定义函数
1.函数实现
- 函数定义, 需要使用编程语言给出函数的执行步骤
- 函数返回值 - 函数完成后带回来的结果 - 主调函数可以使用
- 谓词函数 - 返回bool类型值的函数 - 表达某项任务是否完成或者某个条件是否满足
Add 函数
//编写函数Add, 求两个整数的和
int Add(int x, int y)
{
int t;
t = x + y;
return t;
}
Compare 函数
// 编写函数Compare, 比较两个整型数据 x, y 的大小。
// 若 x 等于 y, 返回0
// 若 x 大于 y, 返回1
// 若 x 小于 y, 返回-1
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语句后面的代码,往往不能够得到执行,除非这些return语句在不同的分支上
int Compare(int x, int y)
{
if(x == y)
return 0;
else if(x > y)
return 1;
else
return -1;
}
Swap函数
// 编写函数Swap, 互换两个整型数据的x、y值
void Swap(int x, int y)
{
int t;
t = x;
x = y;
y = t;
return; //因为函数没有返回值, 只需写出return语句
}
思考不用临时变量,进行 两个量的互换
谓词函数
//编写函数IsLeap, 判断某个给定的年份是否为润年
bool IsLeap(int year)
{
return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
}
谓词函数的作用一般拿来当作判断的条件表达式
2.函数重载
- 定义同名的但参数不完全相同的函数
- 示例
-
int Max(int x, int y);
-char Max(char x, char y);
-bool Max(bool x, bool y);
这样可以定义重名的函数,编译器编译的时候,会根据参数类型,自动匹配对应的函数
3.函数使用代码示例
#include <iostream>
using namespace std;
int Add(int x, int y);
// 因为c/c++是一趟编译的语言
// 所以如果被调用的函数不写在调用函数之前
// 编译器是无法找到调用的函数
// 所以可以先写函数的声明, 或者写完整的函数
// 但是从维护代码的角度, 应该先写main函数
// main函数之前,只写函数的原型
int main(int argc, char const* argv[])
{
int a, b, sum;
cout << "This program is to calculate the sum of two integers\n";
cout << "The first integer:";
cin >> a;
cout << "The second integer:";
cin >> b
sum = Add(a, b);
cout << "The sum is " << sum << endl;
return 0;
}
int Add(int x, int y){
return x + y;
}
如果把程序组织成一个库的模式,则函数的组织方式,就不和main组织在一起了,函数的原型都会放在头文件里,而函数的实现则会放进源文件里。
III. 函数调用规范
1.函数调用示例
//编写程序,将用户输出的两个整数相加,要求尽可能使用函数将程序中的操作独立出来
#include <iostream>
using namespace std;
void Welcome();
int GetInteger(int idx);
int Add(int x, int y);
int main()
{
int a, b, sum;
// 程序的最初,应该给出程序的功能性的简单说明
Welcome();
a = GetInteger(1);
b = GetInteger(2);
sum = Add(a, b);
cout << "The sum is " << sum << "." << endl;
return 0;
}
void Welcome()
{
cout << " The program gets two integers, and prints their sum." << endl;
}
int GetInteger(int idx)
{
int t;
cout << " No. " << idx << ":";
cin >> t;
return t;
}
int Add(int x, int y)
{
int t;
t = x + y;
return t;
}
2.参数传递机制
值传递机制
- 形式参数在函数调用时,才分配存储空间,并接受实际参数的值, 若没有调用,形式参数是没有存储空间的
- 形式参数,可以是复杂的表达式, 无论表达式多复杂,编译器都会在函数调用前,完成表达式的计算
- 形式参数和实际参数可以同名,也可以不同名
- 参数很多时, 实际参数值逐一赋值,它们必须保持数目、类型、顺序的一致
- 值的复制过程(实际参数向形式参数赋值)是(一次性)单向不可逆的,函数内部对形式参数值的修改不会反映到实际参数中去。
- 函数参数一般为函数输入集(函数从外部接收的信息的集合)的一部分,函数输出集(函数向外部输出的集合)一般使用返回值表示,只有使用特殊的手段才可以将函数参数作为函数输出集的一部分
代码说明
//编写程序,将用户输出的两个整数互换(错误示例)
#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 << "a: " << a << "b: " << b << endl;
Swap(a, b);
cout << "a: " << a << "b: " << b << endl;
//这里我们会发现,a和b的值并没有发生改变
//原因是,a和b将值传递到Swap(int x, int y)之后, x 和 y发生的变化跟 a 和 b是没有任何关系的
//执行Swap()函数的时候,Swap()函数的栈框架,已经覆盖了main()的函数栈框架
// 后续可以使用指针和引用来解决
return 0;
}
void Welcome()
{
cout << " The program gets two integers, and swap them." << endl;
}
int GetInteger(int idx)
{
int t;
cout << " No. " << idx << ":";
cin >> t;
return t;
}
void Swap(int x, int y)
{
int t;
t = x;
x = y;
y = t;
return;
}
不过我们可以使用全局变量来改变上面的代码,使上面的代码可以正确运行
//编写程序,使用全局变量 将用户输出的两个整数互换(正确示例)
#include <iostream>
using namespace std;
int a, b;
//在这里定义的变量是全局变量,即从这里开始,到代码结束,所有的地方都可以使用的变量
// 也就是说,下面所有的函数包括main函数,都可以使用 a, b
// 因为这两个量被所有函数共享,所以Swap()连参数都不用传
// 所以Swap函数的形式参数列表就空了
// 但是Swap函数的实现也要全部换成 a 和 b
void Welcome();
int GetInteger(int idx);
void Swap();
int main()
{
Welcome();
a = GetInteger(1);
b = GetInteger(2);
cout << "a: " << a << "b: " << b << endl;
Swap();
cout << "a: " << a << "b: " << b << endl;
//这里我们会发现,a和b的值并没有发生改变
//原因是,a和b将值传递到Swap(int x, int y)之后, x 和 y发生的变化跟 a 和 b是没有任何关系的
//执行Swap()函数的时候,Swap()函数的栈框架,已经覆盖了main()的函数栈框架
// 后续可以使用指针和引用来解决
return 0;
}
void Welcome()
{
cout << " The program gets two integers, and swap them." << endl;
}
int GetInteger(int idx)
{
int t;
cout << " No. " << idx << ":";
cin >> t;
return t;
}
void Swap()
{
int t;
t = a;
a = b;
b = t;
return;
}
虽然问题解决了,但是处理办法并不好,所以不推荐如此处理
引用传递
在指针和引用部分讨论
3.函数调用栈框架
画图表示函数的栈框架
Share this on