提问人:user21247827 提问时间:2/20/2023 最后编辑:user21247827 更新时间:2/20/2023 访问量:82
我们如何在函数(C++)中正确使用指针和对整数的引用?
How do we properly use pointers and references to integers in a function (C++)?
问:
在尝试手动解决时,我无法理解如何获取以下 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。
最糟糕的是,如果我第二次调用函数时使用相同的逻辑,我的值不正确,但我的总数是正确的......我迷路了。
答:
最终计数为 a = 7、b = 4(未更改)和 c = 8。 这些值是正确的,但函数的返回部分不正确 使用以下值:
让你绊倒的是 , , 和 在 ur 中与 , 和 在 中不同。这a
b
c
main
a
b
c
f()
return a+b+(*c);
使用 f()
知道的 a
、b
和 c
。这是 的一部分。的变量是这个语句唯一知道的东西,它对 中的任何变量都一无所知。因此,要知道这些变量是什么,您只需要重新阅读自己编写的内容:f()
f()
return
main
a += 1 现在给了我 a = 5;
b += 3 现在给我 c = 8,因为 b 是一个参考
但是这个,就在这里是非常精确的,与表达式中的相同。b
b
return
*c += 4 现在将存储在 &a 中的值初始化为 3 并加 4,因此 a 的新值为 7;
但这是表达式的。所以c
return a+b+(*c);
计算或 ,如您所观察到的。5+8+7
20
第二个表达式的工作方式相同。
你会被这样一个事实所绊倒,即 的变量使用与 中的变量相同的名称。来自一个的指针和引用引用另一个中的变量也无济于事。f()
main()
重命名以下变量可能会有所帮助:f()
int f(int x, int & y,int *z){
x += 1;
y += 3;
*z += 4;
return x+y+(*z);
}
这在逻辑上应该等同于原始函数,但混淆较少。
这是最容易用图片完成的,所以我会尝试制作一些 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
评论
int &b = 5;