14

我正在浏览我的教科书,我对其中的一些代码有点困惑。一方面,他们以下列方式执行指针运算:

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 个字节......或者不是这样吗?谢谢你。

4

2 回答 2

18

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

于 2012-04-07T20:48:30.710 回答
3

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

尽管 (void *) 和 (char *) 都可以等效地转换为任何其他指针类型,但如果您想遵守标准 C,则仅对 (char *) 执行指针运算而不是 (void *) 是合法的.

为什么两者都用作指针?大多数与 (void *) 的指针转换都可以在没有强制转换的情况下完成,但 (char *) 的使用是对旧时代的回忆。

GCC 不会就 (void *) 上的指针运算发出警告,因为它不是一个旨在符合标准 C 而是适用于 GNU C 的编译器。要符合标准 C,您可以使用以下标志:

gcc -ansi -pedantic -Wall -Wextra -Werror <more args...>

我的底线:

  • 如果要执行指针运算:使用 (char *)
  • 如果您想获取指针地址以便稍后将其转换为另一种类型:使用 (void *)
于 2018-10-08T09:33:33.077 回答