我们如何在函数(C++)中正确使用指针和对整数的引用?

How do we properly use pointers and references to integers in a function (C++)?

提问人:user21247827 提问时间:2/20/2023 最后编辑:user21247827 更新时间:2/20/2023 访问量:82

问:

在尝试手动解决时,我无法理解如何获取以下 C++ 代码输出的正确值。

#include <iostream>
using namespace std;

int f(int a, int & b,int *c){
    a += 1;
    b += 3;
    *c += 4;
    return a+b+(*c);
}
int main() {
    int a = 3, b = 4,c = 5;
    cout << "total: " << f(b,c,&a) << endl;
    cout << "a= " << a << " b= " << b << " c= " << c << endl;
    
    a = 3, b = 4,c = 5;
    cout << "total: " << f(a,a,&a) << endl;
    cout << "a= " << a << " b= " << b << " c= " << c << endl;
    return 0;
}

我知道结果应该是:

total: 20
a= 7 b= 4 c= 8
total: 24
a= 10 b= 4 c= 5

但是每次我尝试手动解决此代码(尝试在一张纸上写出步骤和赋值)时,我似乎都无法获得正确的总数或值。谁能帮助我理解函数内部发生的事情,包括 a、b 和 c(也许是分步解释?一定有一些我不理解的引用/取消引用或指针导致我的逻辑错误。甚至 ChatGPT 在尝试执行代码后也吐出了错误的答案......

例如,如果我尝试函数内的第一组输入,以下是我的理解:

  • int a = 4;
  • int &b = 5;由于 c = 5
  • int *c = &a;&a = 3

然后我开始执行函数的主体:

  • a += 1 现在给了我 a = 5;
  • b += 3 现在给我 c = 8,因为 b 是对 c 的引用,所以实际上只有 c 发生了变化;
  • *c += 4 现在将存储在 &a 中的值初始化为 3 并加 4,因此 a 的新值为 7;

最终计数为 a = 7、b = 4(未更改)和 c = 8。这些值是正确的,但函数的返回部分不适用于以下值:

a+b+(*c) 应该是 7+4+(7),但结果是 18,而正确答案是 20。

最糟糕的是,如果我第二次调用函数时使用相同的逻辑,我的值不正确,但我的总数是正确的......我迷路了。

C++ 函数 指针 逐个引用

评论

1赞 user12002570 2/20/2023
我们无法为您调试您的程序。使用调试器。什么是调试器,它如何帮助我诊断问题?
2赞 user12002570 2/20/2023
顺便说一句,在 c++ 中无效。您可以/应该使用调试器,而不是手动执行。int &b = 5;
1赞 Drew Dormann 2/20/2023
程序员通常理解使他们感到困惑的程序行为@user21247827方法是使用调试器。调试器将准确显示程序运行时发生的情况。
1赞 Sam Varshavchik 2/20/2023
好吧,我们不能告诉你你写的“一张纸上的步骤和作业”有什么问题,除非你确切地展示这些步骤和作业是什么。你能编辑你的问题并包括你认为正在发生的事情吗,我相信有人会指出确切的错误。如果你想让某人“解释”并帮助你“理解正在发生的事情”,那么你需要展示你认为“正在发生的事情”,以便其他人可以帮助你“理解”。
2赞 Nicol Bolas 2/20/2023
@user21247827:“我不是在要求某人调试我的代码,而是在要求某人解释结果” 这就是“调试”当你的代码产生的结果与你预期的结果不一致时,你要做的事情。

答:

2赞 Sam Varshavchik 2/20/2023 #1

最终计数为 a = 7、b = 4(未更改)和 c = 8。 这些值是正确的,但函数的返回部分不正确 使用以下值:

让你绊倒的是 , , 和 在 ur 中与 , 和 在 中不同。这abcmainabcf()

return a+b+(*c);

使用 f() 知道的 abc。这是 的一部分。的变量是这个语句唯一知道的东西,它对 中的任何变量都一无所知。因此,要知道这些变量是什么,您只需要重新阅读自己编写的内容:f()f()returnmain

a += 1 现在给了我 a = 5;

b += 3 现在给我 c = 8,因为 b 是一个参考

但是这个,就在这里是非常精确的,与表达式中的相同。bbreturn

*c += 4 现在将存储在 &a 中的值初始化为 3 并加 4,因此 a 的新值为 7;

但这是表达式的。所以c

return a+b+(*c);

计算或 ,如您所观察到的。5+8+720

第二个表达式的工作方式相同。

你会被这样一个事实所绊倒,即 的变量使用与 中的变量相同的名称。来自一个的指针和引用引用另一个中的变量也无济于事。f()main()

重命名以下变量可能会有所帮助:f()

int f(int x, int & y,int *z){
    x += 1;
    y += 3;
    *z += 4;
    return x+y+(*z);
}

这在逻辑上应该等同于原始函数,但混淆较少。

1赞 Chris Dodd 2/20/2023 #2

这是最容易用图片完成的,所以我会尝试制作一些 ascii 艺术来展示正在发生的事情。

这是第一个调用进入 f 后的情况:

main   a:3   b:4   c:5
         ^           ^
         |       /---/
         |      /
 f     c:*   b:*   a:4

这里的 'main' 和 'f' 各自有自己的 'a'、'b' 和 'c';而“F”中的“B”和“C”指向/指代 Main 堆栈帧中的事物。我颠倒了“f”中的 c/b/a 顺序,以免出现交叉线。

在 f 中加上 3 之后,我们有

main   a:7   b:4   c:8
         ^           ^
         |       /---/
         |      /
 f     c:*   b:*   a:5

在对 f 的第二次调用中,内容如下所示:

main   a:3   b:4   c:5
         ^
         |\--\
         |    \
 f     c:*   b:*   a:3

并在添加后:

main   a:10   b:4   c:5
         ^
         |\--\
         |    \
 f     c:*   b:*   a:4