题目
请仔细阅读以下程序,完成以下任务:
1)此程序中使用了函数重载、指向函数的指针,请写出程序的输出结果;
2)分析说明变量声明时 int, int*, int& 的作用;分析说明函数形式参数中使用 int, int*, int& 的区别与联系。
#include <iostream>
using namespace std;
int funOne(int num)
{
num = num + 1;
return num;
}
int funTwo(int& num)
{
num = num + 1;
return num;
}
int funThree(int* num)
{
*num = *num + 1;
return *num;
}
void func(int (*f)(int), int& v, string f_n, string v_n) {
cout << "Run function " << f_n << " for var " << v_n << "\t:\t";
cout << v << "\t" << f(v) << "\t" << v << endl;
};
void func(int (*f)(int&), int& v, string f_n, string v_n) {
cout << "Run function " << f_n << " for var " << v_n << "\t:\t";
cout << v << "\t" << f(v) << "\t" << v << endl;
};
void func(int (*f)(int*), int* v, string f_n, string v_n) {
cout << "Run function " << f_n << " for var " << v_n << "\t:\t";
cout << *v << "\t" << f(v) << "\t" << *v << endl;
};
int main() {
int a = 1, * p = &a, & r = a;
func(funOne, *p, "funOne", "*p");
func(funOne, r, "funOne", "r");
func(funTwo, a, "funTwo", "a");
func(funTwo, *p, "funTwo", "*p");
func(funThree, &a, "funThree", "a");
func(funThree, &r, "funThree", "r");
cin.ignore();
}
解答
任务1:程序输出结果
让我们逐行分析程序,特别关注函数调用和指针的使用。
int main() {
int a = 1, * p = &a, & r = a;
func(funOne, *p, "funOne", "*p"); // func(int (*f)(int), int& v, string f_n, string v_n)
func(funOne, r, "funOne", "r"); // func(int (*f)(int), int& v, string f_n, string v_n)
func(funTwo, a, "funTwo", "a"); // func(int (*f)(int&), int& v, string f_n, string v_n)
func(funTwo, *p, "funTwo", "*p"); // func(int (*f)(int&), int& v, string f_n, string v_n)
func(funThree, &a, "funThree", "a"); // func(int (*f)(int*), int* v, string f_n, string v_n)
func(funThree, &r, "funThree", "r"); // func(int (*f)(int*), int* v, string f_n, string v_n)
cin.ignore();
}
第一次调用
func(funOne, *p, "funOne", "*p"); // *p = a = 1
f = funOne
v = *p
即v = 1
- 输出:
Run function funOne for var *p : 1 2 1
- 因为
funOne
传值调用,不改变原始值。
第二次调用
func(funOne, r, "funOne", "r"); // r = a = 1
f = funOne
v = r
即v = a = 1
- 输出:
Run function funOne for var r : 1 2 1
- 因为
funOne
传值调用,不改变原始值。
第三次调用
func(funTwo, a, "funTwo", "a"); // a = 1
f = funTwo
v = a
- 输出:
Run function funTwo for var a : 1 2 2
- 因为
funTwo
传引用调用,会改变a
的值为2
。
第四次调用
func(funTwo, *p, "funTwo", "*p"); // *p = a = 2
f = funTwo
v = *p
即v = 2
- 输出:
Run function funTwo for var *p : 2 3 3
- 因为
funTwo
传引用调用,会改变a
的值为3
。
第五次调用
func(funThree, &a, "funThree", "a"); // &a = 指针指向 a = 3
f = funThree
v = &a
- 输出:
Run function funThree for var a : 3 4 4
- 因为
funThree
传指针调用,会改变a
的值为4
。
第六次调用
func(funThree, &r, "funThree", "r"); // &r = &a, 指针指向 a = 4
f = funThree
v = &r
即v = &a
- 输出:
Run function funThree for var r : 4 5 5
- 因为
funThree
传指针调用,会改变a
的值为5
。
任务2:分析 int, int*, int& 的作用
变量声明时 int, int*, int& 的作用
-
int
:声明一个普通的整数变量。int a = 1; // 普通整数变量
-
int*
:声明一个指向整数的指针变量。int *p = &a; // 指针变量,存储变量 a 的地址
-
int&
:声明一个整数的引用,引用必须初始化,并且一旦绑定一个变量后,不能改变绑定。int &r = a; // 引用,r 是 a 的别名
函数形式参数中 int, int*, int& 的区别与联系
-
int
:传值调用,函数接收变量的一个副本,函数内对该副本的修改不影响原变量。int funOne(int num); // 传值调用
-
int*
:传指针调用,函数接收变量的地址,通过指针可以修改原变量。int funThree(int* num); // 传指针调用
-
int&
:传引用调用,函数接收变量的引用,函数内对引用的修改直接影响原变量。int funTwo(int& num); // 传引用调用
总结
- 传值调用(
int
):函数内对参数的修改不影响外部变量。 - 传指针调用(
int*
):函数内通过指针修改变量,影响外部变量。 - 传引用调用(
int&
):函数内通过引用直接修改变量,影响外部变量。
完整的输出结果
Run function funOne for var *p : 1 2 1
Run function funOne for var r : 1 2 1
Run function funTwo for var a : 1 2 2
Run function funTwo for var *p : 2 3 3
Run function funThree for var a : 3 4 4
Run function funThree for var r : 4 5 5