这是我在C ++中为学习目的而创建的代码片段,我目前正在尝试自学。我的问题是:
为什么*ptr = 30
会改变我主要的两个最后一个cout语句的输出值? (输出为30,30,30)。因此,int y = 30;
和ptr = &y;
为什么不改变main中的输出,并保持函数的本地? (如果我注释掉* ptr = 30,而不是前两个语句,则输出为30,5,5)
如果我将功能输入更改为void printPointer(int *&fptr)
- 并注释仅 *ptr = 30
- 那么我的主程序中的*ptr
将被修改,但不会X。我理解这一点,因为引用传递是修改指针,而不是我的第一个语句如何修改我的主中的* ptr和x。
#include <iostream>
using namespace std;
void printPointer(int *fptr);
int main()
{
int x = 5;
int *ptr = &x;
printPointer(ptr);
cout << *ptr << endl;
cout << x << endl;
return 0;
}
void printPointer(int *fptr)
{
// int y = 30; // this does not change the output of the last two couts in main, output = 30, 5, 5
// fptr = &y;
*fptr = 30; // uncommenting this and commenting out the former two statements: output = 30, 30, 30
cout << *fptr << endl;
}
答案 0 :(得分:3)
*ptr = 30
更改指向的值。在您的情况下,您已将ptr
设置为指向x
(当您执行ptr = &x
时,然后将其作为参数传递给printPointer()
)。因此x
的值已更改。
当您执行int y = 30; fptr = &y;
时,您所做的只是将fptr
更改为指向不同的变量。而已。你没有改变指向的值(即x
的值)。并且您不会影响ptr
,因为fptr
是一个单独的本地变量。因此ptr
仍然指向x
,而x
仍为5。
当您修改函数以通过引用获取指针时,将fptr
更改为指向y
也会更改ptr
,因为它们是相同的变量
答案 1 :(得分:0)
*fptr = 30
将取消引用存储在fptr
中的地址,并在内存中的位置写入30。这个地址在你用printPointer(ptr)
赋予函数的内存中。在这种情况下,ptr
是x的地址,您使用ptr = &x
分配给ptr。
int y= y
声明函数的局部变量。
fptr = &y
将y的地址分配给fptr(并覆盖ptr中的值)。所以这种情况下的最后一行会改变局部变量y而不是x。
答案 2 :(得分:0)
如果我理解正确,你会问两段代码。第一个是您发布的内容:
#include <iostream>
using std::cout;
void f(int* fptr) {
*fptr = 30; // 11
cout << "*fptr = " << *fptr << '\n'; // 12
}
int main() {
int x = 5; // 1
int* ptr = &x; // 2
f(ptr); // 21
cout << "*ptr = " << *ptr << '\n'; // 22
cout << "x = " << x << '\n'; // 23
}
在这种情况下,指针始终指向x,并且在函数中,您仍然会更改x的值,因为这是fptr指向的值。如果它有帮助,这里是每行末尾变量值的演示:NE表示当前不存在变量。
1. x = 5, ptr = NE, fptr = NE
2. x = 5, ptr = &x, fptr = NE
11. x = 30, ptr = &x, fptr = &x
12. x = 30, ptr = &x, fptr = &x
21. x = 30, ptr = &x, fptr = NE
之后,值不会改变,并且所有三个语句都将打印30。
第二个是:
#include <iostream>
using std::cout;
void f(int*& fptr) {
int y = 30; // 11
fptr = &y; // 12
cout << "*fptr = " << *fptr << '\n'; // 13
}
int main() {
int x = 5; // 1
int* ptr = &x; // 2
f(ptr); // 21
cout << "*ptr = " << *ptr << '\n'; // 22
cout << "x = " << x << '\n'; // 23
}
在第一种情况下,指针通过引用传递,并指向y。事实上,在这种情况下,第21行涉及未定义的行为,因为y不再存在。再次,逐行分析:
1. x = 5, y = NE, ptr = NE, fptr == NE
2. x = 5, y = NE, ptr = &x, fptr == NE
11. x = 5, y = 30, ptr = &x, fptr == ptr
12. x = 5, y = 30, ptr = &y, fptr == ptr
13. x = 5, y = 30, ptr = &y, fptr == ptr
21. x = 5, y = NE, ptr = &y, fptr == NE
此后值再次不会更改:但是,在第22行,您尝试获取ptr
的地址。如您所见,*ptr = y = NE
,因此行为未定义。输出可以是任何东西。
(另一个注意事项是,您应该避免使用using namespace std;
,因为它可能导致名称冲突;请使用using std::cout;
和类似内容,如上面的代码所示。)