13

鉴于此代码:

int *p, *q;

p = (int *) 1000;
q = (int *) 2000;

什么是q - p以及如何?

4

5 回答 5

34

根据标准,它实际上是未定义的。指针算法不能保证工作,除非指针都指向同一个数组中的一个元素,或者刚好超出同一个数组。

该标准的相关部分是 6.5.6:9(c1x 的 n1362 草案,但自 c99 以来没有改变),其中指出:

当两个指针相减时,都应指向同一个数组对象的元素,或者指向数组对象的最后一个元素;结果是两个数组元素的下标之差。

如果您的int数据类型是 4 个字节,您很可能会得到 250,但不能保证。未定义的行为(与实现定义的行为不同)意味着未定义。任何事情都可能发生,甚至包括大部分时空的彻底破坏。

进修课程:

  • 定义的行为是标准规定的。实现必须这样做才能符合要求。
  • 实现定义的行为留给实现,但它必须清楚地记录该行为。如果您不太关心可移植性,请使用它。
  • 未定义的行为意味着任何事情都可能发生。永远不要那样做!
于 2010-01-22T13:37:51.613 回答
8

q - p 为 250。

2000 - 1000 = 1000
1000 / sizeof(int) = 250

指针运算,假设 sizeof(int) 为 4。


编辑:好的,澄清一下。在 C 中,当两个指针属于同一类型时,它们之间的差异定义为它们之间指向类型的事物的数量。例如,

struct foo { int ar[1000]; } big[10];
char small[10];

struct foo *fs, *fe;
char *ss, *se;

fs = &big[0]; fe = &big[9];
ss = &small[0]; se = &small[9];

fe - fs == se - ss;

也就是说,这种情况下两个指针之间的差异是它们之间的数组元素个数。在这种情况下,它是 0、1、... 8 或 9 个元素。

于 2010-01-22T13:37:50.697 回答
2

q-p应该返回从p到应该执行的增量步数q。等于250。1000 / sizeof(int)记住q++实际上会转到 int 类型的下一个元素,而不是在它的中间,所以它应该在指针的实际值上加 4。因此结果。

于 2010-01-22T13:40:43.447 回答
2

答案: qp 将是 250,假设你在一个 anint是 4 字节的机器上。

计算如下:

q - p = 1000 1000 / 4(整数大小)= 250

它背后的想法

指针算法背后的想法是,如果你有一个int指向 1000 的指针和一个int指向 2000 的指针,并要求两者之间的差异,那么你并不是在问 2000-1000 是多少。您要问的是,我可以在两者之间容纳多少个。int

这对于各种操作都非常方便,例如:

int *i = 100;
i++; // This is **not** 101, it is 104, cause you actually want the next place an int could fit in memory.

这在处理数组时特别有用。整数数组(已定义int arr[10])基本上被视为指针。当您编写arr[5]时,编译器将其转换为*(arr + 5),即,将 5 加到int称为 的指针arr上,并获取该地址处的值。

之所以可行,是因为这并不arr + 5意味着“将 5 的值加到 arr ”,它的意思是“将任何必要的值加到 arr 的值以前进 5秒”,或者更准确地说,“将 5 * 添加到arr 值"intsizeof(int)

于 2010-01-22T13:45:20.120 回答
-7

因为 p 指向一个 int,所以 q,qp 将是 1000。

于 2010-01-22T13:37:34.997 回答