【c++】【基础】【primer_plus】【第七章】函数

定义及声明

函数是语句执行的空间,通常一个c++程度会由许多函数组成,c语言更是如此。通过调用函数执行函数中的代码,使程序按照一定的流程进行。由此可见一个函数可以被多次使用,简化了重复的过程的代码量,所以说函数就是功能的实现。

函数的一般格式如下。

1
2
3
4
5
// 返回值类型 函数名 参数列表
type_name function_name (parament_list) {
statements;
return value; // value的类型为type_name
}

如下示例代码,分别包含了函数的声明、定义和调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <fstream>
#include <cassert>
using namespace std;

int sum(int a, int b); // 函数声明

int main() {
cout << sum(1, 2) << endl; // 函数调用
return 0;

}

int sum(int a, int b) { // 函数定义
return a + b;
}

函数可在声明处直接定义,但不可以在main函数之后声明,否则识别不出。函数的返回值类型可为整型、浮点型、指针、字符、结构体、对象等。当函数返回值类型为void时不需要有return语句,但可在必要的地方使用return语句来直接跳出函数体。

函数返回值不可为数组,但可以将数组作为结构体或对象的组成部分来返回。

函数原型声明时的参数列表里可不包括变量名,也不必与定义时的变量名一致。

函数参数

函数的参数相当于在函数中声明的局部变量。将参量赋值给参数的过程相当于给函数的局部变量赋值的过程。

一个函数可以有多个参数,使用逗号隔开。

函数与数组

1
2
3
4
5
int sum_arr(int arr[], int n) {
int res = 0;
for(int i = 0; i < n; ++i) res += arr[i];
return res
}

方括号为空表示可以将任意长度的数组传递给此函数。arr实际上不是一个数组,而是一个指针,所以才可以传任意长度。调用时将数组名传入此函数列表作为指针。

在函数中可以像使用数组一样使用指针参数。其真正正确的写法应该是int sum(int* arr, int n);,但是在函数原型中,int* arrint arr[]含义相同。

将数组传入函数时,函数里修改的并非数组的副本,而是数组本身,这也是因为传进来的是真实的指针地址。

arr使用sizeof()并非获取整个数组的长度,而是int*指针的长度(可能是4字节)。

有时候不想修改原数组的数据,可对函数的数组参数使用const关键字。

1
2
3
void show_arr(const int arr[], int n) {
for(int i = 0; i < n; ++i) cout << arr[i] << endl;
}

数组区间

1
2
3
4
5
6
7
int sum_arr(const int* begin, const int* end) {
int tot = 0;
for(const int *p = begin; p != end; ++p) tot += (*p);
return tot;
}
int a[5] = {1, 2, 3, 4, 5};
cout << sum_arr(a+1, a+3) << endl;

如上代码所示,数组区间指两个指针,一个指向数组的开始,一个指向数组的末尾。数组区间是我们之后要接触到的迭代器的雏形。

指针与const

让指针指向一个常量对象。

1
2
int a = 5;
const int* p = &a;

p指向一个const int类型,即不能使用p来修改其指向的值(但可能会以其他方式修改) 即(*p)的值为const类型,不可修改。

p的值是可以修改的,如p++。即p可以指向不同的对象,但其指向的对象不能通过p修改。

注意,不可将const的地址赋给非const指针,这样会使const无意义。如

1
2
const int a = 5;
int* p = &a;

在上述代码中,因为(*p)非const的,所以可以通过(*p)修改a的值,那么aconst属性就无用了。

除此之外,在只有一级间接关系的情况下将非const指针赋给const指针是安全的。

将指针本身声明为常量

1
2
int a = 5;
int* const p = &a;

pconst类型,指向一个int。即p只能指向a,不能再指向其他的地址。即p的值为const,不可修改。

但可以用p来修改a的值。即(*p)的值为非const的,可以修改。

指向const对象的const指针

1
2
double b = 0.5;
const double* const p = &b;

此时p(*p)都是const,都不能用来修改b的值。