有没有办法找到参考地址?
使其更具体:变量本身的地址,而不是它初始化的变量的地址。
答案 0 :(得分:57)
引用没有自己的地址。虽然引用可以实现为指针,但是不需要或保证这一点。
The C++ FAQ说得最好:
与指针不同,一旦引用就是 绑定到一个对象,它不可能 “重新安置”到另一个对象。该 引用本身不是一个对象(它 没有身份;以地址为 引用为您提供地址 指称;记住:参考 是它的指示物。)
请在此处查看我的回答comprehensive list of how references differ from pointers。
引用是它的指示
答案 1 :(得分:34)
否即可。无法获取参考地址。
这是因为引用不是对象,它是别名(这意味着它是对象的另一个名称)。
int x = 5;
int& y = x;
std::cout << &x << " : " << &y << "\n";
这将打印出相同的地址 这是因为'y'只是对象'x'的另一个名称(别名)。
答案 2 :(得分:20)
ISO标准说得最好:
不应引用引用,不引用引用数组,也不引用引用指针。
我不喜欢很多人在这里使用的逻辑,你不能这样做,因为引用不是“保证在任何地方只是一个指针”。正如int x
可能只是一个没有地址的处理器寄存器,但在使用& x
时神奇地成为一个内存位置,编译器仍然可以允许你想要的东西。
过去,许多编译器确实允许您提出的要求,例如
int x, y;
int &r = x;
&r = &y; // use address as an lvalue; assign a new referent
我刚检查过,GCC会编译它,但是警告措辞强烈,结果程序坏了。
答案 3 :(得分:12)
没有
正如Bjarne Stroustrup在TC ++ PL中所说,引用可以被认为是现有实体(对象或函数)的另一个名称。虽然这并不总是对实现引用的底层低级机制的最精确描述,但它是对引用在语言级别实现的概念的非常好的描述。毫不奇怪,该语言无法获得引用本身的地址。
在语言级别,参考不能保证占用存储空间,因此一般情况下它没有地址。
答案 4 :(得分:9)
来自同一问题的另一个例子:$ 8.3.2 / 3 - “未指明引用是否需要存储(3.7)。”。
因此,C ++标准允许编译器/运行时实现者选择引用是否位于单独的内存位置。但请注意,如果它确实存在于单独的内存位置,则无法以符合标准的方式找到其地址。所以不要这样做。
如果您根据C ++标准的定义获取引用的地址,您将获得它所引用的地址,而不是引用的地址,如果事实上该引用甚至作为单独的实体存在于运行环境与否。
答案 5 :(得分:7)
只需使用'&amp;'运营商。 例如:
int x = 3;
int &y = x;
cout<<&y<<endl;
这将返回x的地址,因为y只不过是x的地址。
答案 6 :(得分:4)
不可靠,因为引用不必在可寻址存储器中具有唯一的位置。
答案 7 :(得分:2)
不是单独的。如果你想要它的“地址”,就把它推到一个结构或类中。即使这样,也不一定能保证让你在你想要做的事情附近使用指针。如果需要校样,则引用的sizeof等于引用类型。尝试使用char&amp;并看到。
答案 8 :(得分:1)
有可能,但不严格使用C ++。由于引用作为函数的参数传递,因此其值将存储在堆栈或寄存器中。 这取决于硬件架构。访问这些值将需要内联汇编。请参阅您正在使用的处理器的参考手册,以确定堆栈行为和寄存器地址。 损坏堆栈或寄存器很容易导致BSOD,数据丢失甚至永久性损坏您的系统。 请务必小心谨慎。
答案 9 :(得分:0)
如果将引用实现为结构的成员,则可以获取其地址:
struct TestRef{
int& r;
int i;
TestRef(int& ref): r(ref){
}
};
引用确实是一个指针(在我的情况下使用Xcode编译器),您可以更新其值以将引用重新分配给新变量。 为此,我们需要找出引用的地址并将其值欺骗到其他变量的地址
现在,引用TestRef.r的地址是TestRef对象的地址。因为r是TestRef的第一个成员。
您可以通过更新TestRef.r内存中的值存储来重新分配引用。
下面的代码显示,您可以获得引用地址,并且可以将引用重新分配给差异变量。注意:我的操作系统是X64操作系统(我使用Xcode MacBook Pro 2015,MacOs 10.15.1)。
#include <iostream>
using namespace std;
struct TestRef{
int& r;
int i;
TestRef(int& ref): r(ref){}
};
int main(int argc, const char * argv[]) {
int i = 10;
int j = 11;
TestRef r(i); // r.r is reference to i
cout << r.r << " " << i << " " << j << endl; // Output: 10 10 11
int64_t* p = (int64_t*)&r; // int32_t in 32 bit OS;
// Note:
// p is the address of TestRef r and also the address of the reference r.r
// *p is the address of i variable
//
// Difficult to understand? r.r indeed a pointer to i variable
// *p will return the address inside the memory of r.r
// that is the address of i variable
// this statement is true: *p == &i
// ------>
// now we change the value of *p to the address of j
// then r.r will be the reference of j instead the reference of i
*p = (int64_t)&j; // int32_t in 32 bit OS;
cout << r.r << " " << i << " " << j << endl; // Output: 11 10 11
return 0;
}
实际上,您可以变通重新分配参考,例如黑客。
答案 10 :(得分:-2)
//YES reference varies
//but a little trick in the compiler
int i = 333;
int j = 444;
int &ref = i; //ref=i value
int* p = nullptr;
printf("ref=%d\n", ref); //333 i value
*(&p + 3) = &j; //&ref=j
printf("ref=%d\n", ref); //444 j value