“如何使用long long数据类型而不是指针数据类型来修改其他变量?”

时间:2019-07-11 15:50:41

标签: c++

我正在学习c ++,发现 POINTER INTEGER 类似,所以我很好奇我是否可以从实施 POINTER LONG LONG ,虽然我知道这不是一个好主意,但这样做很有趣。在这里,我的想法是将pointer转换为int之类的数据类型(例如xpointer),然后在可能的情况下使用xpointer访问和修改其包含的地址内容!

因此,为了做到这一点,我尝试将 POINTER 存储为 LONG LONG 类型,但是它溢出了,因此出现了一个错误。

#include <iostream>
using namespace std;
int main()
{
    int x = 1923;
    long long xpointer;
    xpointer = (int)&x;
    cout << xpointer << endl;
    return 0;
}

我知道 POINTER 太大,无法存储在 LONG LONG 中,所以这里出现错误,您能建议我一种实现目标的方法吗?

以下是错误消息,仅供参考。

error: cast from pointer to smaller type 'int' loses information
xpointer = (int)&x;
               ^~~~~~~
1 error generated.

PS:在这里,我犯了一个错误,将x强制转换为int而不是long long,所以除了它之外,我如何使用xpointer来修改或检索数据,就像我们尽可能使用指针变量一样?

3 个答案:

答案 0 :(得分:4)

问题的本质在于,您的代码旨在将您的脚掌开枪,而您误认为脚部受伤是自然原因。

例如,在您要编译的环境中,long long实际上足够大以存储指针†,因此没有理由您不能编写这样的代码:

int x = 1923;
long long xpointer;
xpointer = reinterpret_cast<long long>(&x); //Valid on a 64-bit x86 CPU compiled with GCC
cout << xpointer << endl; 
return 0;

但是您的代码却等效于xpointer = reinterpret_cast<int>(&x);,在您的环境中无效。 intlong long†的大小不同,如果要强制转换为后者,则需要对该类型进行快速转换。而不是中间类型(int)会隐式扩展为适当的类型(long long),而这会引起警告或错误。

将来,如果您确实打算将指针存储为整数,则应该改用std::intptr_t,因为[如果为您的环境定义了该类型,则可以保证它足够大以存储一个指针。指针作为整数。

int x = 1923;
intptr_t xpointer = reinterpret_cast<intptr_t>(&x); //Guaranteed to be valid if intptr_t is defined
cout << xpointer << endl; 
return 0;

†请注意,并非所有环境都具有与64位x86环境中的GCC相同的整数大小(包括intlong long)。在您的情况下,分别是32位和64位,但是如果您是针对其他环境进行编译,则这些数字(尤其是前者)可能会有所不同。


如果您随后打算实际使用xpointer中存储的指针来修改其指向的数据,则需要将指针回退。您不能在不指示编译器将其视为指针的情况下操作xpointer所指向的数据。

int x = 1923;
intptr_t xpointer = reinterpret_cast<intptr_t>(&x);
cout << xpointer << endl; 
int* ptr = reinterpret_cast<int*>(xpointer); //Legal If-and-only-If xpointer has not been changed
*ptr = 2019;
cout << x << endl; //Should print "2019"
cout << *ptr << endl; //Should print "2019"
return 0;

请注意,如果您尝试对指针本身执行任何类型的算术运算,则会迅速转向“未定义行为”领域,并且无法保证程序的行为:

int x = 1923;
intptr_t xpointer = reinterpret_cast<intptr_t>(&x);
cout << xpointer << endl; 
int* ptr = reinterpret_cast<int*>(xpointer); //Legal If-and-only-If xpointer has not been changed
*ptr = 2019;
cout << x << endl; //Should print "2019"
xpointer++;//Legal, but...
int* ptr2 = reinterpret_cast<int*>(xpointer); 
*ptr2 = 2020; //This is now undefined behavior
cout << x << endl; //Legal on its own, but because of preceeding undefined behavior,
//this may not do what you expect.
return 0;

答案 1 :(得分:-1)

int是32位(在现代编译器中)。指针是32或64位。您的编译可能使用64位编译器,因此在intint*之间出错。

除此之外,C ++是一种强类型化的语言,或者我们可以简单地以汇编形式编写它而忽略类型。

int与指针不同,long long与指针不同。您将需要难看的C样式强制转换。

建议,请阅读good book

答案 2 :(得分:-1)

在标准C ++中,intptr_t是整数类型,可以保证足够大以容纳指针。如果要将地址存储为整数,请使用该地址。