在尝试理解指针时,我有以下问题

问题描述 投票:10回答:5

在最后两个陈述中,realPointerfakePointer之间存在任何真正的差异。他们都会提供相同的功能吗?

  int num = 0;

  int *realPointer = #
  int fakePointer = #
c pointers type-conversion
5个回答
24
投票
int fakePointer = #

这不是有效的C,它打破了简单赋值的规则而不会编译。

但是,如果你完成了int fakePointer = (int)#,那么唯一的区别就是无法保证你可以可靠地使用fakePointer,从指针到整数的转换是实现定义的,并且可能还会导致未定义的行为(6.3.2.3):

任何指针类型都可以转换为整数类型。除了之前指定的以外,结果是实现定义的。如果结果无法以整数类型表示,则行为未定义。结果不必在任何整数类型的值范围内。

要在指针和整数之间进行安全且可移植的转换,不应使用int,而应使用stdint.h中的uintptr_t类型。


6
投票

声明为指针的变量在语义上与未声明为指针的变量不同。编译器(和语言)将允许您使用非指针无法执行的指针执行操作。当然,情况正好相反。

最大的不同是你可以取消引用一个指针,但你不能这样做非指针。

例如,使用代码中的变量,然后我们可以执行*realPointer = 5以使num被赋值为5,但是不允许执行*fakePointer = 5并且没有意义,因为fakePointer实际上不是指针。


4
投票
int num = 0;
int *realPointer = #
int fakePointer = #

在最后两个语句中,realPointer和fakePointer之间存在任何真正的区别。

你的fakePointer不是指针。它是一个整数,其值为变量num的地址。使用默认选项编译时,您可能会离开。但正如Lundin指出的那样,这确实是一个无效的代码。使用gccCFLAGS="-g -Wall -std=c99 -O3 -pedantic-errors"标志,你会收到这个错误:

 error: initialization makes integer from pointer without a cast

虽然你的realPointer确实指向变量num,你可以取消引用它。你可以用你的fakePointer做任何事情 - 事实上,fakePointer本身的任务无效。


1
投票

如果你考虑这两个变量所保持的文字值(即实际值),它们是相同的(即变量num的地址),但只有值相同。但正如其他人所说,它们在语义上是两个不同的变量,不能互换使用。

来到你的上一个问题:

Will they both provide the same functionality?

Answer: No, they do not.

Reasoning they are not of the same type.

Your first question:

any real difference between the realPointer and fakePointer.

There are so many differences, and the most basic differences are:
  1. realPointer保存num的地址并且是一个指针,所以如果你改变num的值(通过改变使用num变量或* realPointer)它会反映在两个地方,但不是伪造的。
  2. 您可以将realPointer传递给函数,并且在函数调用中进行的任何更改都将反映回被调用函数。

1
投票

除此之外

 int fakePointer = #

可能导致以下一种或多种情况

  • 通过打破C语言的“规则”(这反过来可能导致“任何事情发生”)的未定义行为
  • 转换期间失去有效数字
  • 根本无法编译

以下差异适用:

  • *- / dereferencing-operator不能应用于int类型的fakePointer
  • fakePointer++很可能会产生与realPointer++不同的东西。这适用于添加和减去任何值的所有其他方式(但0)。请阅读"pointer arithmetic"与“算术”的详细信息。
  • 不可能将[]- / indexing-operator应用于int类型的fakePointer
© www.soinside.com 2019 - 2024. All rights reserved.