2010-01-22 93 views
13

鉴于此代码:的C指针运算

int *p, *q; 

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

什么是q - p又如何呢?

+0

需要功能标签? – 2010-01-29 11:08:02

+1

@保罗我对此表示怀疑。 – 2011-06-25 07:07:28

回答

32

它实际上未定义,根据标准。除非指针都指向同一个数组中的一个元素,否则指针算术不能保证工作。

该标准的相关部是6.5.6:9(C1X的n1362草案但这因为C99没有改变),其规定:

当两个指针相减,既应指向元件相同的数组对象, 或一个过去的数组对象的最后一个元素;结果是两个数组元素的 下标的差异。

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

进修课程:

  • 定义的行为是什么是标准的规定。实现必须做到这一点是一致的。
  • 实现定义的行为留给实现,但它必须清楚地记录该行为。如果你不关心可移植性,请使用它。
  • 未定义的行为意味着任何事情都可能发生。永远不要这样做!
+4

这是正确的答案,但我想每个人都希望相信答案无论如何都是1000/sizeof(int)。好吧! – 2010-01-22 22:55:20

-7

为P指向一个int等Q,Q-p将为1000

+1

除以sizeof(int) – 2010-01-22 13:39:16

+1

对不起,但这是错误的。 – 2010-01-22 13:44:44

+0

@Pascal为什么我们需要将它除以sizeof(int)? – NLV 2010-01-22 13:45:35

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

+0

这就是我一直在寻找的东西。我不打扰我的问题-1。你为什么分1000/sizeof(int)? – NLV 2010-01-22 13:40:49

+0

你最好说“如果sizeof(int)是4”。这是因为sizeof(char)*总是* 1. – paxdiablo 2010-01-22 13:47:54

+0

@paxdiablo:对。脑冻结。 – 2010-01-22 13:48:33

2

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

2

答案: Q-P将是250,假设你是一台机器,其中一int为4个字节。

的计算公式是:

q - p值= 1000 1000/4(int的大小)= 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数组(定义为int arr[10])基本上就像一个指针一样对待。当您编写arr[5]时,编译器将其翻译为*(arr + 5),即将5添加到名为arrint指针中,并获取该地址的值。

这部作品的原因,是因为arr + 5意味着“加5 arr中的价值”,它的意思是“添加任何是neceassary arr中的价值前进5米int的”,或者更确切地说,“添加5 * sizeof(int)到ARR的值”