2011-11-18 54 views
3

是什么这两个涉及指针算术的语句有什么区别?

char cur_byte=*((char *)(buf+i)); 

char *b=(char *)(buf); 
char cur_byte=*(b+i); 

之间的差假设: BUF是作废//指针无效* buf中;和 我被用作for循环中的迭代器 我在一个生成rabin指纹的c源代码中发现了这段代码(第一行),并且由于VC2010 express将它报告为错误,我不得不用第二行代替它。我不确定它是否能达到预期目的。另外,如果任何人都可以给我一个提示,说明如何获得一个可用于C++源代码的内容定义分块和指纹生成,我将不胜感激。

+0

不会在第一行给出运行时异常吗? – Ankit

+0

VC2010表示这是一个错误 – John

回答

5

在您的第一条语句中,您将一个整数(i是一个整数类型,对吗?)添加到void*,之后再铸造为char*。由于编译器无法知道应该增加指针多少,所以C标准没有定义带空指针的指针算术。但是,一些编译器定义了sizeof(void) == 1。在这种情况下,你的两个片段是相同的,这就解释了为什么这个代码可能与另一个编译器(感谢Steve Jessop指出这个)

你在你的第一个片段中的含义可能是 char cur_byte=*(((char *) buf) + i);,该字符指向的地址位于i之后的字符。

在以下架构中,将为i==4cur_byte分配值r

Memory: |a| |w|o|r|d 
     ^ ^
     buf  buf+i 

在你的第二个声明:

char *b=(char *)(buf); 
char cur_byte=*(b+i); 

首先要将bufb,再b + i内容分配给cur_bytebchar*类型,所以加入i会给后的地址i个字符。

Memory: |a| |w|o|r|d| 
     ^ ^
     buf   
     b  b+i 

最后这两条语句是等价的(除了赋值b)。

+0

但你能告诉我为什么第一个选项是错误的VC2010 – John

+0

我刚刚编辑我的帖子,以反映你的编辑。 – Antoine

+2

“带空指针的指针算术不是由C标准定义的” - 但是GCC允许它作为非迂回模式的扩展,这可能是为什么首先写出引发错误的代码的原因。 GCC的扩展实际上表示,仅用于指针运算的目的是“sizeof(void)== 1”。因此,所有这些代码片段在GCC中都是相同的。 –

1

区别在于表达式(buf + i)(b + i)

bchar*的类型,因此(b + i)将指向b + sizeof(char) * i

buf可能是不同的类型,所以(buf + i)将指向buf + sizeof(BUFS_TYPE) * i

+0

正确(+1)。现在,在John给出'buf'类型之后,你应该扩展你的答案。 –