void* vs. char* 指针算法

lx0bsm1f  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(125)

我在看我的教科书,我对里面的一些代码有点困惑。在一部分中,它们以以下方式执行指针算术:

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个字节。还是事实并非如此?

svmlkihl

svmlkihl1#

这是一个失误。void *上的算术没有被标准定义,但是一些编译器提供了它作为一个扩展,其行为与char *的算术相同。第二个是形式上无效的C,但可能是出于(坏)习惯而被漏掉的。

von4xj4u

von4xj4u2#

公认的答案是一个很好的总结,我想更清楚地说明为什么要使用一个或另一个。;)
虽然(void *)和(char *)都可以等价地转换为任何其他指针类型,但**如果您想遵守标准C,则仅对(char )而不是(void )执行指针算术是法律的。
为什么两者都用作指针?大多数与(void *)之间的指针转换都可以在不进行强制转换的情况下完成,但(char *)的使用是对旧时代的回忆。
GCC不会对(void *)上的指针运算发出警告,因为它不是一个旨在与标准C兼容的编译器,而是一个用于GNU C的编译器。要符合标准C,您可以使用以下标志:

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

我的底线是:

  • 如果你想让**执行指针运算:use(char *
  • 如果你想让**获取指针地址,以便稍后将其转换为另一种类型:use(void *

相关问题