Fork me on GitHub

函数

参数传递

值传递、引用参数和const形参

值传递就是实参的值被拷贝给形参,此时实参和形参是两个相互独立的对象。

而传引用参数时,实参和形参是同一个对象。

1
2
3
4
5
6
7
8
void test(int *a){
*a = 1; //a所指向的int对象的值变为了1
a = 0; // 但是a的值没有变,即a所指向的地址没有变
}
void test(int *&a){
*a = 1; //此时a和*a的值都被改变
a = 0;
}

使用引用可以避免拷贝,当拷贝大的类类型或容器对象时比较低效,当函数无需修改引用参数的值时,最好使用常量引用。

把不会改变的形参定义为常量引用有很多好处。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void test(int &a){
a = 1;
}


int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
test(42); //编译错误,不能把字面值传递给普通引用形参。
const int a = 42;
test(a); //编译错误,不能把const对象传递给普通引用。

}

数组形参

由于不能拷贝数组,而且为函数传递一个数组时,实际上传递的是指向数组首元素的地址。

1
2
3
4
//等价定义
void test(int *a);
void test(int a[]);
void test(int a[10]); //这里的10并不是指数组有10个元素

传递多维数组

多维数组其实就是数组的数组的。。。。。,所以首元素是一个数组,所以指向首元素的指针其实就是一个指向数组的指针。

1
2
3
4
5
6
7
8
9
//括号不能丢
int (*a)[10]; //定义了一个指针,a是指针,指向含有10个整数的数组
int *a[10]; //定义了一个含有10个指针构成的数组

//二维数组的定义
void test(int (*a)[10]); //a指向二维数组的首元素,首元素是一个由10个整数构成的数组
void test(int a[][10]); //等价定义
void test(int a[][10][10]); //三维数组
void test(int (*a)[10][10]);

可变形参的函数

如果函数的参数的数量未知,但是参数的类型一样时,可以使用initializer_list类型的形参。注意的是:initializer_list对象中的元素是常量值,无法改变元素的值。

需要可变参数的时候,为什么不用vector代替initializer_list?参考https://www.jianshu.com/p/3d69ff89a0c9

返回值和return语句

列表初始化返回值

函数可以返回{}包围的值的列表

1
2
3
vector<string> test(){
return {"lzc" , "lzc"};
}

函数指针

函数指针值向函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int sum(int a , int b){
return a + b;
}

int (*pf)(int , int); //pf指向一个函数,该函数的形参是两个int,返回值是int类型。

int ssum(int a , int b , int (*pf)(int , int)){ //函数指针用于形参,形参名任意取
return a + b + pf(1 , 2);
}

int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
//test(42);
pf = sum;
int a = pf(1 , 2);
a = (*pf)(1 , 2); //等价定义
a = sum(1 , 2);
cout<<a<<endl;
a = ssum(2 , 3 , sum); //函数名转化为指针
cout<<a;
}

可以使用类型别名简化函数指针的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int sum(int a , int b){
return a + b;
}

typedef int func(int , int); //func和func1是函数类型
typedef decltype(sum) func1;

typedef int (*func2)(int , int); //func2和func3是函数指针类型
typedef decltype(sum) * func3;

int ssum(int a , int b , func1 f){ //上面四个都可以用在这里,编译器会把func和func1所表示的函数类型转为指针
return a + b + f(1 , 2);
}

int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
//test(42);
int a = ssum(1 , 2 , sum);
cout<<a;
}