【问题标题】:What's the difference between these two statements involving pointers arithmetic?这两个涉及指针算术的语句有什么区别?
【发布时间】:2012-01-01 01:31:35
【问题描述】:

有什么区别

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

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

假设: buf 是指向 void// void *buf 的指针;和 i 在 for 循环中用作迭代器 我在生成 rabin 指纹的 c 源代码中找到了这段代码(第一行),因为 VC2010 express 将其报告为错误,我不得不用后两行替换它。而且我不确定它是否可以达到预期的目的。另外,如果有人能给我一个提示,我将不胜感激在哪里可以获得用于内容定义的分块和指纹生成的工作 C++ 源代码。

【问题讨论】:

  • 第一行不会给出运行时异常吗?

标签: c pointers void


【解决方案1】:

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

bchar* 类型,所以(b + i) 将指向b + sizeof(char) * i

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

【讨论】:

  • 完全正确 (+1)。现在在约翰给出buf 的类型之后,你应该扩展你的答案。
【解决方案2】:

在您的第一个语句中,您将一个整数(i 是整数类型,对吗?)添加到 void*,然后转换为 char*。带有 void 指针的指针运算C 标准没有定义,因为编译器无法知道它应该增加多少指针。然而,一些编译器定义了sizeof(void) == 1。在这种情况下,您的两个 sn-ps 是等效的,这就解释了为什么这段代码可能与另一个编译器一起工作(感谢 Steve Jessop 指出这一点)

您在第一个 sn-p 中的意思可能是 char cur_byte=*(((char *) buf) + i);,地址指向的字符位于buf后面i个字符。

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

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

在你的第二个陈述中:

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

你先把buf赋值给b,再把b + i的内容赋值给cur_byteb 具有 char* 类型,因此添加 i 将在 b 之后给出地址 i 字符。

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

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

【讨论】:

  • 但是你能告诉我为什么第一个选项是 VC2010 中的错误
  • “C 标准没有定义带有 void 指针的指针算法” - 但 GCC 允许它作为非迂腐模式的扩展,这可能是第一次编写引发错误的代码的原因地方。 GCC 的扩展实际上表明,仅出于指针算术的目的,sizeof(void) == 1。所以所有这些代码 sn-ps 在 GCC 中都是等价的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-16
  • 2022-01-02
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
  • 2016-08-01
相关资源
最近更新 更多