添加指针地址 - 合法性

时间:2014-08-15 13:12:22

标签: c pointers

由于将两个指针放在一起是非法的,这段代码片段有效吗?

struct key *low = &tab[0]; 
struct key *high = &tab[n]; 
struct key *mid; 

while (low < high) 
{ 
  mid = low + (high-low) / 2; //isn't this adding pointers?


//code continues...

while循环中的第一个语句似乎将两个地址加在一起,这是怎么合法的?

此代码来自K&amp; Rs C编程语言(第122页)

4 个答案:

答案 0 :(得分:6)

两个指针(high - low)的差异是一个整数(实际上是ptrdiff_t,这是一个有符号整数类型),所以你将整数添加到指针,这是完全合法的。这也解释了为什么将差值除以2是完全可以的,这不是你用指针做的事情。

答案 1 :(得分:4)

您可以减去两个指针(结果为ptrdiff_t ),并允许您向指针添加整数值。 draft C99 standard部分6.5.6 添加剂运算符 paragrph 2 中包含了这一点:

  

另外,两个操作数都应具有算术类型,或者一个操作数应为a   指向对象类型的指针,另一个指针应具有整数类型。 (递增是   相当于添加1。)

和段落 3

  

对于减法,以下之一应保留:

并包含以下项目符号:

  

两个操作数都是指向兼容对象的限定或非限定版本的指针   类型;或

一些重要的注意事项,当减去两个指针时,它们必须指向同一个数组,这将在段落 9 中说明:

  

当减去两个指针时,两个指针都应该指向   相同的数组对象,或者超过数组对象的最后一个元素; [...]

为了避免undefined behavior,添加的结果指针仍然必须指向同一个数组,或者指向数组末尾的指针,如果指向一个结尾,则不得取消引用它,这是在段落 8 中说:

  

[...]如果指针操作数和结果都指向元素   相同的数组对象,或者超过数组最后一个元素的数组   对象,评估不得产生溢出;否则,   行为未定义。如果结果指向最后一个元素   对于数组对象,它不应该用作一元*的操作数   被评估的运算符。

答案 2 :(得分:2)

两个指针high - low的差异是具有算术整数类型的值(如果需要存储,则可以由类型ptrdiff_t表示)。完全允许向指针添加整数值。

答案 3 :(得分:1)

如果你要减去指向同一个数组元素的两个指针,或者只是超过同一个数组的最后一个元素,那么减法就是它们之间的差异(在数组元素中)。返回值是有符号整数类型,ptrdiff_t来自stddef.h。

因此,high - low返回此有符号整数,然后将其添加到低位。因此,您不会添加指针,而是添加带有符号整数类型的指针。