函数
函数就是把一段具有某种特定的功能的代码封装起来。
一个C++程序无论包含多少个函数,必须有一个主要的函数,叫做main()函数,作为执行整个程序的入口。你可以在main()函数中去调用其他函数,同样的,其它函数之间也可以互相调用。
- 声明
函数声明时,我们需要把函数名、参数和返回值类型都定义好,声明的形式一般如下:
返回值类型 函数名(参数1类型 参数1, 参数2类型 参数2, …, 参数n类型 参数n);
- 有些函数执行所需的操作而不返回任何值,此时的返回值类型是void
- 定义
C++中定义函数时,需要在声明的基础上写好函数体,函数定义的一般形式如下:
返回值类型 函数名(参数1类型 参数1, 参数2类型 参数2, …, 参数n类型 参数n) {
函数体
- 调用
定义了函数之后,函数里面的代码是不会执行的。只有调用了这个函数,才会去执行函数中的代码。
函数名(实际参数1, 实际参数2, …, 实际参数n)
函数的参数传递是一个重点:
常用的是传值传递和引用传递。
传值传递
- 在这种方法中,把参数的实际值赋值给函数的形式参数。在这种情况下,修改函数内的形式参数对实际参数没有影响。
引用传递
- 该方法把参数的引用赋值给形式参数。在函数内,该引用用于访问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数。
如果我们把数组作为参数,传递的参数是数组名。我们知道数组名表示的是数组的地址,所以这时候我们传递的参数实际上是数组的地址,在函数中修改数组里的某一个值,会在内存中直接修改这个数组。
函数定义时,我们可以给函数的参数设置默认值,这样我们调用函数时,可以选择不传递参数,选择默认的参数。
// 定义函数,参数为数组a和长度len,默认len为1,
int MyMax(int a[], int len = 1) {
int max_num = 0;
for (int i=0; i<len; i++) {
if (a[i] > max_num)
max_num = a[i];
}
return max_num;
}
int main() {
int nums[10] = {3, 2, 1, 1, 2, 3, 3, 2, 1, 0};
int nums2[1] = {3};
// 调用函数
cout << MyMax(nums, 10) << endl;
// 调用函数,len使用默认值1
cout << MyMax(nums2) << endl;
return 0;
}
递归函数
函数的函数体中又调用了它自己,这就叫做“递归函数”。
递归函数的写法有两个基本要素:
- 递归关系
比如计算某个数字的阶乘,我们知道,递归的关系就是:数字n的阶乘 = 数字n * 数字n-1的阶乘 - 递归的终止条件
在计算阶乘这个例子中,递归终止的条件是计算到数字1的阶乘的时候,函数可以直接返回数字1的阶乘就是1
更严谨的,我们可以在n小于1的时候,输出错误操作。
#include <iostream>
using namespace std;
int factorial(int n) {
if (n < 1) {
cout << "错误操作" << endl;
return -1;
}
if (n == 1)
return 1;
else
return n * factorial(n-1);
}
int main() {
cout << factorial(4) << endl;
return 0;
}
结构体
由于数组只能存储一组同样数据类型的信息,我们可以使用结构体来将一组不同类型的数据聚合成一个整体,以便于去处理这些信息。
- 每个结构体除了有名称,还有有很多个不同类型的成员变量用于表示这个结构体的属性。结构体的定义方式如下:
struct 结构体名称 {
数据类型1 变量名1;
数据类型2 变量名2, 变量名3;
…
数据类型n 变量名m;
};
- 结构体变量声明
struct Student{
int number, birth_year;
string name;
};
// 声明三个学生
Student zhang_san, li_si, wang_mazi;
// 声明一个学生数组,数组长度为500,可以保存500个学生的信息
Student students[500];
- 初始化结构体
- 使用初始化列表或构造函数。
// 初始化一个学号为1,2000年出生,名叫 ZhangSan的学生
Student zhang_san = {1, 2000, "ZhangSan"};
// 在结构体里定义构造函数
// 在初始化时所有学生的出生年份都被设置为2000
// 可以传入两个参数,分别代表学号和姓名,如果不传入参数,默认学号为0,姓名为""
Student (int num=0, string n="") {
number = num;
birth_year = 2000;
name = n;
}
};
// 初始化时只用传递两个参数即可
Student li_si(2, "LiSi");
- 结构体成员访问
可以使用结构体变量名.结构体成员变量名
的方式访问:
cout << zhang_san.number << endl;
cout << zhang_san.name << endl;
cout << li_si.birth_year << endl;
练习:
#include <iostream>
using namespace std;
// 定义结构体 Employee,并声明长度为5的结构体数组 employees_info
struct Employee{
int number, working_hours;
string name;
// 构建函数
Employee (int num=0, string n="") {
number = num;
working_hours = 8;
name = n;
}
} employees_info[5];
// 展示某位员工信息的函数
void showEmployee(const Employee &employee_info) {
cout << "Employee Number : " << employee_info.number << endl;
cout << "Name : " << employee_info.name << endl;
cout << "Working Hours : " << employee_info.working_hours << endl;
}
int main() {
// 初始化5位员工
employees_info[0] = Employee(1, "XiaoYi");
employees_info[1] = Employee(2, "XiaoEr");
employees_info[2] = Employee(3, "XiaoLiu");
employees_info[3] = Employee(4, "XiaoSi");
employees_info[4] = Employee(5, "XiaoWu");
// 调用函数展示5位的信息
for(int i=0; i<5; i++) {
showEmployee(employees_info[i]);
}
return 0;
}