【问题标题】:How do I cast a pointer to an int如何将指针转换为 int
【发布时间】:2012-12-15 02:10:53
【问题描述】:

我正在尝试将地址的值存储在非指针 int 变量中,当我尝试对其进行转换时,我收到编译错误“从 'int*' 到 'int' 的无效转换”这是我的代码正在使用:

#include <cstdlib>
#include <iostream>
#include <vector>

using namespace std;

vector<int> test;

int main() {
    int *ip;
    int pointervalue = 50;
    int thatvalue = 1;

    ip = &pointervalue;
    thatvalue = ip;

    cout << ip << endl;

    test.push_back(thatvalue);

    cout << test[0] << endl;
    return 0;
}

【问题讨论】:

  • 从您拥有的代码中,存储指针向量并打印它们是一回事。
  • 你为什么要这样做?单独的转换不是很便携(并不是每个环境都有uintptr_t),您可能想要对结果进行的任何算术运算要么使用指针更容易,要么更不便携。
  • 如果您将指针值转换为整数类型,则很有可能您做错了什么。这是一个合法的转换,如果你做对了(如果机器有 some 整数类型,它大到足以保存结果而不会丢失信息),但 99% 的情况下你会过得更好只是将指针视为指针。如果您告诉我们您想对指针值做什么,而您认为最好使用整数,也许我们可以帮助您在不进行转换的情况下完成。

标签: c++ pointers casting


【解决方案1】:

int 可能不够大,无法存储指针。

您应该使用intptr_t。这是一个显式大到足以容纳任何指针的整数类型。

    intptr_t thatvalue = 1;

    // stuff

    thatvalue = reinterpret_cast<intptr_t>(ip);
                // Convert it as a bit pattern.
                // It is valid and converting it back to a pointer is also OK
                // But if you modify it all bets are off (you need to be very careful).

【讨论】:

  • 我不明白,int 不够大,无法容纳任何指针?但是 int 的大小正好是 4294967295,这就是十六进制的 FFFFFFFF 的等价物,并且指针不只是保存内存中介于 00000000 和 FFFFFFFF 之间的数字的地址吗?这是否意味着 int 足够大以容纳指针?这是我对它的工作原理的理解,请纠正我的错误。
  • @user1934608:它不能保证足够大。在某些系统上它会足够大,但不是在所有系统上。例如,一些 64 位系统将需要 64 位作为指针,但它们的整数可能只有 32 位(尽管有些系统将具有 64 位整数,这完全取决于)。但是intptr_t 总是足够大以容纳指针而不会丢失信息。注意:我使用的是 macbook,我将您的代码更改为使用 thatvalue = reinterpret_cast&lt;int&gt;(ip),但出现错误:error: cast from ‘int*’ to ‘int’ loses precision
  • @LokiAstari:区分int(一种特定类型)和“整数”(从charlong long int 的类型集合)很重要。例如,一个系统可能有一个 32 位 int 类型和一个 64 位 integer 类型(称为 longlong long)。
【解决方案2】:

你可以这样做:

int a_variable = 0;

int* ptr = &a_variable;

size_t ptrValue = reinterpret_cast<size_t>(ptr);

【讨论】:

  • 使用来自&lt;cstdint&gt;std::uintptr_t
  • @GManNickG...谢谢,我不知道。我使用了size_t,因为它适应了平台上的指针大小。
  • size_t 可能会起作用。但是intptr_t 被明确设计为一个可以保存指针值的整数(不会丢失信息)。
【解决方案3】:

你为什么要这样做,反正你只需要转换,对于 C 代码:

thatvalue = (int)ip;

如果你写C++代码,最好使用reinterpret_cast

【讨论】:

  • 我建议使用像 reinterpret_cast 这样的 C++ 样式转换,而不是旧式 C 转换。
  • reinterpret_cast 比 C 风格的 cast 好,原因:stackoverflow.com/questions/7831696/…
  • 我刚才试过了,我觉得它给出的输出和指针地址不一样。它打印:“2293616”和“0x22ff70”我所做的只是将thatvalue = ip; 替换为thatvalue = (int)ip;,我做错了什么吗?编辑:没关系,只是在谷歌上搜索了一个十六进制到 base10 转换器并找出我哪里出错了.. 哈哈
  • ...这是同一个数字:2293616 = 0x22ff70
  • 这也注定会失败。 int 可能不够大,无法存储指针,尤其是在 64 位系统上。
【解决方案4】:

我建议使用reinterpret_cast:

thatvalue = reinterpret_cast<intptr_t>(ip);

【讨论】:

  • 正确使用 reinterpret_cast。但不是 int。
  • 我假设在 OP 的机器上 int 足够大以存储指针,但我同意你的观点,一般来说最好使用 intptr_t 例如对于一些 64 位系统,所以我更新了我的答案。谢谢。
【解决方案5】:

我能够使用 C union 语句来实现您正在寻找的内容。它当然会依赖于编译器,但它对我来说就像你想象的那样工作(Linux,g++)。

union {
    int i;
    void *p;
} mix;

mix.p = ip;
cout << mix.i << endl;

在我的特定实例中,我的 int 是 32 位,指针是 48 位。分配指针时,整数值 i 将代表指针的最低 32 位。

【讨论】:

    【解决方案6】:

    由于int *ip; 是一个指向整数的指针,而int thatvalue = 1; 是一个整数,假设您希望将存储在地址指向的值分配给ipthatvalue,更改thatvalue = ip;thatvalue = *ip;(注意添加 dereference operator * 以访问一个值相当于指针地址处的值)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-12
      • 2012-03-02
      • 2014-05-02
      • 1970-01-01
      • 2013-11-18
      • 2019-10-07
      • 2018-06-08
      • 2017-07-25
      相关资源
      最近更新 更多