谈谈函数调用

【导读】

本篇文章讲述的是函数调用时,如何使用参数、返回类型。

首先,给出三个经常被举出来的例子:

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 void testSwap_val();
 6 void testSwap_ptr();
 7 void testSwap_quote();
 8 
 9 void swap_val(int a, int b)            // 传值调用 
10 {
11     int temp = a;
12     a = b;
13     b = a;
14 }
15 
16 void swap_ptr(int *a, int *b)        // 传地址调用 
17 {
18     int temp = *a;
19     *a = *b;
20     *b = temp;
21 }
22 
23 void swap_quote(int &a, int &b)        // 直接绑定实参 
24 {
25     int temp = a;
26     a = b;
27     b = temp;
28 }
29 
30 
31 int main()
32 {
33     testSwap_val();
34     testSwap_ptr();
35     testSwap_quote();
36     return 0;
37 }
38 
39 void testSwap_val()
40 {
41     int m = 2, n = 5;
42     swap_val(m, n);
43     cout << m << " " << n << endl;
44 }
45 
46 void testSwap_ptr()
47 {
48     int m = 2, n = 5;
49     swap_ptr(&m, &n);
50     cout << m << " " << n << endl;
51 }
52 
53 void testSwap_quote()
54 {
55     int m = 2, n = 5;
56     swap_quote(m, n);
57     cout << m << " " << n << endl;
58 }
swap.cpp

不用运行程序,我们都知道结果如下:

我们通过分析这个例子,来探讨一下函数调用时的“实参——形参”的关系。

1. 调用函数时,如果被调用函数有参数,会用传入的实参对形参进行初始化。形参初始化的机理与变量初始化一样。

  • 传值时,创建形参对象,将实参的值拷贝后赋给形参。形参和实参是两个相互独立的对象。
  • 传地址时,行为与传值一样,也是创建一个指针形参,然后将实参的值拷贝后赋给形参。但由于传递的值是某个变量的地址,故可通过“*”达到修改变量的目的。
  • 传引用时,和其他引用机理一样,引用形参绑定初始化它的实参(不拷贝),即形参只是实参的别名,修改形参也就是修改实参。

2. 向函数传递一个数组

  由上面的讨论可知,除了引用类型的参数,其他参数都涉及拷贝。但我们的数组不允许拷贝,故我们无法将数组作为参数向函数传递一个数组。

  我们可以向函数传递指向数组首元素的指针,这样的实现类似于传地址

上面讨论了函数调用是有关于参数的部分,但是只是冰山一角,关于参数部分更多的东西可参考:推荐形参使用常量引用:void func(const T &);传递可变数量的实参等等。

函数三巨头:返回类型、函数名、参数列表,上面我们讨论了参数列表,下面谈谈返回类型。

1. 返回的值会用于初始化一个临时量,该临时量就是函数调用的结果。

	string ss;
	ss = func();
// 等价于
/*
	string ss;
	string temp = func();        // temp就是函数调用的结果
	ss = temp;
*/        

2. 可以以列表的形式返回值,而且如果函数返回的是内置类型,则花括号包围的列表最多包含一个值

vector<int> func()
{
	return {1, 2, 3, 4, 5};		// 返回类型为可包容多个值的vector<int> 
}

int main()
{
	vector<int> ivec;
	ivec = func();
	return 0;
}

3. 返回类型为引用时,如果不是常量引用,则该函数调用式可作为左值使用

#include <iostream>
 
using namespace std;
 
int& func(int &a)
{
    return a;           // 不能返回局部对象的引用
}
 
int main()
{
    int a = 10;
    func(a) = 100;          // 返回非常量引用的函数可以当作左值使用
    cout << a << endl;      // 输出100
    return 0;
}
原文地址:https://www.cnblogs.com/xzxl/p/8638464.html