将指针分配给整数

5
我可以把指针赋值给整型变量吗?就像下面这样。
int *pointer;
int array1[25];
int addressOfArray;

pointer = &array1[0];

addressOfArray = pointer;

“是否可以这样做?”

你已经尝试过了吗? - user845279
1
你希望这样的任务能够实现什么?告诉我们你想解决的实际问题,我们可以帮忙解决。 - Keith Thompson
3
除非你有充分的理由,否则不要这样做。如果你确实要这样做,请勿使用int,因为在所有系统上,int并不足够大以容纳指针(例如常见的LP64和LLP64模型)。而是应该使用intptr_t - Adam Rosenfield
6个回答

4

如果没有显式的强制类型转换,即不行。

addressOfArray = (int) pointer;

还有一个注意事项:

6.3.2.3指针
...
6 任何指针类型都可以转换为整数类型。除非先前已经指定,否则结果是实现定义的。如果结果不能用整数类型表示,则行为未定义。结果不需要在任何整数类型的值范围内。

因此,结果并不能保证是有意义的整数值。


谢谢您添加警告,我在一个Lua实现中发现了(并且感到困惑的)这样的代码。 - hauptmech
1
回答正确,但您可以包括为什么需要强制转换的原因(@ouah提到的赋值运算符的约束)。 - Peter - Reinstate Monica
3
最好使用类型uintptr_t而不是int,因为它具有更少的实现定义行为。 - Lundin

4
不,将指针赋值给整数是无效的。这是赋值运算符(C99,6.5.16.1p1)的限制违规。编译器有权拒绝翻译带有指针到整数的赋值操作的程序。

1
你可以进行强制类型转换,但我不建议这样做。 - Richard J. Ross III

1

不行。

您试图将“指向int的指针”值分配给“int”变量。您肯定会得到编译器警告。您可以这样做:

int *pointer;
int array1[25];
int *addressOfArray;

pointer = &array1[0];
//The following commented lines are equivalent to the pointer assignment above and are also valid
//pointer = array
//pointer = &array[0]

addressOfArray = pointer;

这被称为浅复制。如果您还不熟悉这个概念,我强烈建议您阅读一下(谷歌“深复制与浅复制”)。

1

在嵌入式编程中,这是经常使用的一种方法,但需要注意以下几点:

  • 该操作(很可能)需要进行强制类型转换
  • 通常意味着您要在没有操作系统或非常接近RTOS(即驱动程序级别开发)的情况下工作

我的ARM bsp在启动过程中进行了一些魔法操作:“size = (unsigned)&__romend - (unsigned)&__romstart;” 我经常在裸机应用程序中看到这种情况。 - Throwback1986
当然,有不止一种方法可以除去猫咪的毛。另一个例子:我的GreenHills RTOS允许使用缓冲区进行消息传递(他们的缓冲区并不是简单的内存缓冲区)。要设置缓冲区,需要执行如下操作: bufferControl.BufferType = DataBuffer | LastBuffer; bufferControl.TheAddress = (Address)&msgControl; bufferControl.Length = MAX_VAS_MESSAGE_SIZE; bufferControl.Transferred = 0; 由于Address只是unsigned long int的typedef,类似于OP的问题被提出。 - Throwback1986
是的,那是另一种情况下你需要这样做的时候,就是当你使用糟糕编写的库时。但老实说(相信我,我是一名软件工程师),你不需要这样做。除非你正在实现print_pointer函数。如果你曾经写过一个类型转换,请至少问自己三次是否有必要这样做,然后再向其他三个人咨询。只有在经过这样的思考之后,才可以考虑它可能是最佳的解决方法。 - ctrl-alt-delor
有趣的观点。在编写低级驱动程序时很难避免类型转换,比如RGB565液晶驱动程序。在SPI和I2C接口中也很有帮助(特别是在将多字节数据从单字节事务中组装时)。总的来说,在开发符合MISRA-C 2004标准、成功通过静态代码分析(例如Coverity、CodeSonar等)并满足编码标准要求的代码时,很难避免强制类型转换。 - Throwback1986
我编写驱动程序、调度程序、任务调度程序、MMU配置器等。我使用pc-lint对我的代码进行静态分析,以满足MISRA标准。我有些员工告诉我,在没有强制类型转换的情况下,无法完成某些任务。因此,我会向他们展示如何更好地完成任务,而不需要强制类型转换。例如,使用uint16_t assemble(int8_t lower, int8_t higher){return (higher<<8) | lower;},避免misra 11.3问题。 - ctrl-alt-delor
显示剩余3条评论

0
你可以这样做:
memcpy(&addressOfArray, &pointer, sizeof(int));

这将直接复制底层字节并替换转换运算符,但我绝对不建议这样做,除非您确定在您的系统上sizeof(int) == sizeof(int *)


0

正如其他人所评论的那样,可以通过强制类型转换将指针转换为int。虽然不建议这样做,但是可能会有坏处。

但是,除了int之外,还有更多的整数类型。例如,我们有intptr_tuintptr_t,专门用于此目的。

因此,您可以这样做,而且是100%安全的。

uintptr_t addressOfArray;
addressOfArray = (uintptr_t) pointer;

然后,如果你真的真的想要这样做(看不出为什么),你可以这样做:

int myInt;
if(addressOfArray <= INT_MAX) {
    myInt = addressOfArray;
} else {

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接