C指针算术

鉴于此代码:

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

什么是q - p以及如何?

根据标准,它实际上是未定义的。 除非指针指向同一个数组中的元素或者指向同一个数组之外的元素,否则不能保证指针算法有效。

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

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

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

进修课程:

  • 定义的行为是标准规定的行为。 实现必须这样做才能符合要求。
  • 实现定义的行为由实现决定,但必须清楚地记录该行为。 如果您不太关心可移植性,请使用此选项。
  • 未定义的行为意味着任何事情都会发生。 不要那样做!

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个元素。

qp应该返回从pq应该做的增量步数。 这是1000 / sizeof(int)并且等于250.记住q++实际上将转到int类型的下一个元素,而不是在它的中间,所以它应该将4添加到指针的实际值。 因此结果。

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

计算如下:

q – p = 1000 1000/4(int的大小)= 250

它背后的想法

指针算法背后的想法是,如果你有一个指向1000的int指针和一个指向2000的int指针,并询问差异,你不会问什么是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数组(定义为int arr[10] )基本上被视为指针。 当您编写arr[5] ,编译器将其转换为*(arr + 5) ,即将5添加到名为arrint指针,并获取该地址的值。

这样做的原因是因为arr + 5并不意味着“将arr的值加5”,这意味着“将任何东西添加到arr的值中以向前推进5 int s”,或者更准确地说,“添加” 5 * sizeof(int)到arr的值“

由于p指向int,因此q,qp将为1000。