C++一道综合考察函数重载、值传递/地址传递/引用传递区别、指针的题目

题目

请仔细阅读以下程序,完成以下任务:
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 = *pv = 1
  • 输出:Run function funOne for var *p : 1 2 1
  • 因为 funOne 传值调用,不改变原始值。
第二次调用
func(funOne, r, "funOne", "r"); // r = a = 1
  • f = funOne
  • v = rv = 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 = *pv = 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 = &rv = &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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值