int main() {
int x=10;
int *p=&x;
int &y =*p;
cout<< x << endl << &x <<endl;
cout<< *p << endl << p <<endl;
cout<< y << endl << &y <<endl;
p++;
*p = 20;
cout<< x << endl << &x <<endl;
cout<< *p << endl << p <<endl;
cout<< y <<endl<< &y <<endl;
return 0;
}
以上是最能解释我的问题的代码。通常,变量引用(&amp;)获取变量的地址并开始引用变量。我试过通过指针做同样的事情。我定义了一个变量,指针p指向x,引用变量y指向* p。这是否意味着y现在引用相同的变量x? 下一步,我停止指向x到* p,现在引用变量y会发生什么?它会持有什么。 在上面的代码中,cout&lt;
有人可以帮助解释这里的行为。
答案 0 :(得分:7)
[注意:这个答案只是关于C ++。在C中,您的代码不应该编译。]
是的,在您初始化y
后,它会引用x
。增加p
不会改变这一点 - y
仍然引用x
。
不幸的是,当您执行p++; *p=20;
时,您已修改p
,因此它不再引用任何已分配的存储空间。当您写入它时,您会得到未定义的行为。这意味着程序停止(或基本上做其他任何事情)是完全合理的。
但是,请注意,递增p
是完全允许的 - 在这方面,x
就像一个元素的数组,并且形成一个指向数组最后一个元素的指针是明确允许。只有当你写指向指针的地址时才会得到未定义的行为。 (即:p++;
没问题; *p=20;
不是。)
答案 1 :(得分:3)
int &y =*p;
在C ++中有效。但是在C中,它无效并且会给你编译时错误。
这是否意味着y现在引用相同的变量x?
在C ++中,是的。但是在递增p
时,它不再指向变量x
,而是指向某个未分配的内存位置。写入此位置会调用未定义的行为。现在一切都可能发生。
答案 2 :(得分:0)
C中没有引用类型。运算符的地址不一样在C ++中声明引用。
这不会在C:
中编译int main()
{
int j = 0;
int& i = j;
}
执行此操作时:
p++;
*p = 20; // undefined behavior
p
不再指向有效内存。您必须为指向指针的指针分配内存。
在C ++中,如果您修改y
,则会修改*p
。
#include <iostream>
int main()
{
int x=10;
int *p=&x;
int &y =*p; // y becomes a reference to x
y = 20;
std::cout << y << " " << *p << " " << x;
}
答案 3 :(得分:0)
这将为您提供您期望的行为
p = new int;
*p = 20;
y = *p;
引用被分配给一个int - x
。它不知道你指的是p指向的那个。它只知道您希望它在您分配给引用时引用指向的那一个。
答案 4 :(得分:0)
请记住,C ++中的引用只不过是伪装的指针。因此,您的代码
int x=10;
int *p=&x;
int &y =*p;
cout<< y <<endl<< &y <<endl;
p++;
*p = 20;
cout<< y <<endl<< &y <<endl;
完全等同于
int x=10;
int *p=&x;
int *y = &*p;
cout<< *y <<endl<< &*y <<endl;
p++;
*p = 20;
cout<< *y <<endl<< &*y <<endl;
现在,您希望打印此代码的内容是什么?你既没有修改y也没有修改它指向的值,因此两个print语句都会输出相同的内容。
请注意
我在转换后的代码中保留了&*y
组合,以明确我如何转换代码。当然,&*y
相当于y
,因此更易于阅读的同等版本将是:
int x=10;
int *p=&x;
int *y = p;
cout<< *y <<endl<< y <<endl;
p++;
*p = 20;
cout<< *y <<endl<< y <<endl;
除了
在C中,&*y
始终与y
相同,在C ++中不一定是这种情况。这是上面的例子。但是,如果y
属于重载operator *
的类型(智能指针执行此操作),则&*y
不等同于y
。在智能指针的情况下,&*y
将返回一个指向智能指针所指向的对象的裸指针。