我在看我的教科书,我对里面的一些代码有点困惑。在一部分中,它们以以下方式执行指针算术:
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条答案
按热度按时间svmlkihl1#
这是一个失误。
void *
上的算术没有被标准定义,但是一些编译器提供了它作为一个扩展,其行为与char *
的算术相同。第二个是形式上无效的C,但可能是出于(坏)习惯而被漏掉的。von4xj4u2#
公认的答案是一个很好的总结,我想更清楚地说明为什么要使用一个或另一个。;)
虽然(void *)和(char *)都可以等价地转换为任何其他指针类型,但**如果您想遵守标准C,则仅对(char )而不是(void )执行指针算术是法律的。
为什么两者都用作指针?大多数与(void *)之间的指针转换都可以在不进行强制转换的情况下完成,但(char *)的使用是对旧时代的回忆。
GCC不会对(void *)上的指针运算发出警告,因为它不是一个旨在与标准C兼容的编译器,而是一个用于GNU C的编译器。要符合标准C,您可以使用以下标志:
我的底线是: