编写函数
独立函数
三大好处:
- 以一连串函数调用操作取代重复编写相同的程序代码,使程序更易读懂;
- 可以在不同的程序中使用这些函数;
- 可以更容易地将工作分配给协作开发团队。
函数四部分
- 返回类型;
- 函数名;
- 参数列表;(类型及名称)
- 函数体。
先声明,后调用
- 声明:让编译器检查后续出现的使用方式是否正确——是否有足够的参数、参数类型是否正确等,不必提供函数体,必须指明返回类型、函数名、参数列表(此即所谓的函数原型);
- 定义:函数原型及函数体。
return语句
- 函数中的每条return语句都被用来表示该处就是函数的退出点;
- 最后一条语句不为return时,即为隐式退出点。
注意:
函数的返回类型即使是void,也应加上 “ return; ”,能显示退出,就不隐式退出。
举例
//2.1 fibonacci数列(斐波那契数列)
#include <iostream>
using namespace std; //指定运行空间
bool fibon_elem_2(int, int &);
//此处为函数的前置声明 (forward declaration)
//需包含:函数返回值类型bool,函数名称fibon_elem
//输入参数类型 (int, int&)整型和指针
int main()
{
int pos;
cout << "Please input the position: \n";
cin >> pos;
int elem;
if (fibon_elem_2(pos, elem)) {
cout << "The element in the position is: " << elem;
}
else{
cout << "The position info was wrong: \n" ;
}
return 0;
}
bool fibon_elem_2(int pos, int &elem)
{
if (pos <= 0 || pos > 1024) {
elem = 0; return false;
}
if (pos == 1 || pos == 2) {
elem = 1; return true;
}
elem = 1;
int n_2 = 1, n_1 = 1;
for (int ix = 3; ix <= pos; ++ix) {
elem = n_2 + n_1;
n_2 = n_1;
n_1 = elem;
}
return true;
}
参考:https://blog.youkuaiyun.com/weixin_42503785/article/details/108179030
调用函数
参数的传递
传值
将对象传入参数,默认情况下其值会被复制一份,成为参数的局部性定义,即传值。
传址
令参数和传入的实际对象产生关联,即传址。
最简单的做法:将参数声明为一个reference。
&:传址
- 直接对传入的对象进行修改;
- 降低复制大型对象的额外负担。
*:传址
提领前先检查其值是否非0
(指针可能不指向实际对象,而引用必定代表某个对象)
int ival = 1024; // 对象,类型为int
int* pi = &ival; // 指针,指向一个int对象
int& rval = ival; // 引用,代表一个int对象
冒泡排序法
#include <iostream>
#include <vector>
using namespace std;
void display(vector<int> &vec);
void swap(int &val1, int &val2);
void bubble_sort(vector<int> &vec);
int main() {
int a[8] = {8, 34, 3, 13, 1, 21, 5, 2};
vector<int> vec(a, a+8);
cout << "vector before sort: ";
display(vec);
cout << "vector after sort: ";
bubble_sort(vec);
display(vec);
return 0;
}
void bubble_sort(vector<int> &vec) {
for(int i = 0; i < vec.size(); i++)
for(int j = i + 1; j < vec.size(); j++)
if(vec[j] < vec[i])
swap(vec[i], vec[j]);
}
void swap(int &val1, int &val2) {
// pass by reference, 参数必须为引用类型,否则不能改变原对象的值
int tmp = val1;
val1 = val2;
val2 = tmp;
}
void display(vector<int> &vec) {
for(int i = 0; i < vec.size(); i++)
cout << vec[i] << ' ';
cout << endl;
}
作用域及范围
生存空间分为:
- 局部生存空间(局部变量)(local scope)
仅在函数体有效,需要初始化赋值。- 与全局生存空间(全局变量)(file scope)
在程序内有效,在函数体外赋值,未赋值时,自动赋值为0。
动态内存管理
- 无论是local scope还是file scope,系统都会自动进行内存分配;
- 但第三种储存期形式称为:
动态范围(dynamic extent),也被称为堆内存(heap memory), 必须由程序员管理:
使用new表达式完成分配,使用delete表达式完成释放;
不及时delete,会出现内存泄漏 (memory leak)。
//动态范围
new Type (initial_value);
//例如
pi= new int (1024); //创建一个初始值为1024的变量pi
delete pi; //释放