void * vs. char *指针算术

时间:2012-04-07 20:45:51

标签: c math pointers

我正在查看我的教科书,我对那里的一些代码感到有些困惑。在一个部分中,它们以下列方式执行指针运算:

void* bp;
...
bp = (void*)((char*)(bp)+16);
...

但稍后,他们会执行以下操作:

void* bp;
...
bp = bp+16;
...

我觉得它们应该是两个不同的东西,但它们就像对待它一样。 我觉得这样,因为,例如,如果您要进行数组访问(例如,对于整数数组),您将执行以下操作

int* a = malloc(n*sizeof(int));
...
q = *(a+1);
...

在这种情况下,我不是访问整数数组中的下4个字节而不是下一个字节吗? 同样,我觉得如果我有void * a,那么*(a + 1)应该是接下来的4个字节...... 或者不是这样吗? 谢谢。

2 个答案:

答案 0 :(得分:13)

这是一个漏洞。 void *上的算术不是由标准定义的,但是一些编译器将其作为扩展提供,与算术char *的行为相同。第二个是正式无效的C,但可能是出于(坏)习惯。

答案 1 :(得分:0)

可接受的答案是一个很好的总结,我想更清楚地说明为什么使用一个或另一个。 ;)

虽然(void *)和(char *)都可以等效地转换为任何其他指针类型,但仅对(char *)进行指针算术运算是合法的,如果使用(void *)则不能想要符合标准C。

为什么两者都用作指针?大部分与(void *)之间的指针转换都可以在不进行强制转换的情况下完成,但是(char *)的使用让人回想起过去。

Gcc不会警告(void *)上的指针运算,因为它不是旨在与标准C兼容的编译器,而是针对GNU C的。要符合标准C的行为,您可以使用以下代码:

ansi -pedantic -Wall -Wextra -Werror

我的底线:

  • 如果要执行指针算术:请使用(char *)
  • 如果您要获取指针地址以便稍后使用时将其转换为其他类型(无效*)