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

时间:2016-03-11 12:28:05

标签: c pointers type-conversion

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

  int num = 0;

  int *realPointer = #
  int fakePointer = #

5 个答案:

答案 0 :(得分:24)

int fakePointer = #

这是无效的C,它违反了简单赋值的规则,不会编译。

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

  

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

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

答案 1 :(得分:6)

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

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

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

答案 2 :(得分:4)

int num = 0;
int *realPointer = #
int fakePointer = #
  

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

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

 error: initialization makes integer from pointer without a cast

虽然您的realPointer确实指向变量num,但您可以取消引用它。您可以使用fakePointer执行此类操作,而实际上fakePointer本身的分配无效。

答案 3 :(得分:1)

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

来到你的上一个问题:

它们是否都提供相同的功能?

回答:不,他们没有。

推理它们的类型不同。

你的第一个问题:

realPointer和fakePointer之间的任何真正差异。

差异很大,最基本的区别是:

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

答案 4 :(得分:1)

除此之外

 int fakePointer = #

可能导致以下一个或多个

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

以下差异适用:

  • * - /解除引用操作符无法应用于int键入的fakePointer
  • 执行fakePointer++很可能会导致与realPointer++不同的事情。这适用于添加和减去任何值的所有其他方式(但0)。有关详细信息,请阅读"pointer arithmetic"与“算术”。
  • 无法将[] - / indexing-operator应用于int已键入的fakePointer