我无法理解deference运算符接受什么类型的值作为其参数。通过 value ,我的意思是左值或右值?
请考虑以下代码段:
int i = 1, *p = &i;
cout << *p++; // Prints 1, so far so good.
现在,因为postfix ++
从上面的代码返回未增加的值(不同于它返回增量对象的前缀对应项)p
似乎一元*
接受右值作为其唯一的操作数。但是,
cout << *i; // error: invalid type argument of unary ‘*’ (have ‘int’)
好吧,也许i
的值不代表有效的内存地址。现在要确认一元*
可以在代表有效内存位置的右值上工作,我尝试过这样的事情:
unsigned long add = p; // error: invalid conversion from ‘int*’ to ‘long unsigned int’ [-fpermissive]
cout << *add; // error: invalid type argument of unary ‘*’ (have ‘int’)
这也让我想到了下一个问题。假设unsigned long
的大小是64位(对于我正在处理的系统来说恰好是这样),为什么不能复制{{1}中存储的值 }(恰好是64位内存地址)到p
?或者换句话说,有没有办法将存储器地址存储在非指针类型的变量中(如果不可能,我会感到惊讶,因为内存地址毕竟也是一个值)?
由于
答案 0 :(得分:3)
内置解除引用运算符采用prvalue,必须是指针类型。如果操作数是一个glvalue,它将在取消引用之前进行左值到右值的转换。
如果要在数据指针类型和等效大小的整数类型之间进行转换,您可以,但必须说这是您希望使用reinterpret_cast
进行的操作。这是为了防止错误,例如忘记取消引用指向int的指针。
答案 1 :(得分:0)
如果没有显式强制转换(reinterpret_cast
或C样式转换),则无法将指针类型转换为非指针类型。或者类应该有隐式转换运算符。假设int
或long
适合指针类型是错误的和冒险的假设。如果你冒这个风险,是的,你可以将指针存储到非指针类型:
int main()
{
int a, b;
a = 10;
b = (int)&a;
a = 40;
cout << *(int*)b << endl;
*(reinterpret_cast<int*>(b)) = 160;
cout << a << endl;
}