我正在浏览我的教科书,我对其中的一些代码有点困惑。一方面,他们通过以下方式执行指针算术:
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个字节......
或者事实并非如此?
这是一个失误。标准未定义
void *
上的算术,但某些编译器将其作为扩展提供,其行为与算术中的 char *
相同。第二个在形式上是无效的 C,但大概是出于(坏)习惯而漏掉的。
接受的答案是一个很好的总结,我想更清楚地说明为什么要使用其中之一。 ;)
虽然 (void *) 和 (char *) 都可以等效地转换为任何其他指针类型,但 只有在 (char *) 上执行指针算术才合法,而不是 (void *) 如果您想遵守标准C.
为什么两者都用作指针?大多数与 (void *) 之间的指针转换都可以在不进行强制转换的情况下完成,但 (char *) 的使用让人回想起旧时代。
GCC 不会对 (void *) 上的指针算术发出警告,因为它不是一个旨在兼容标准 C 而是 GNU C 的编译器。要遵循标准 C,您可以使用以下标志:
gcc -ansi -pedantic -Wall -Wextra -Werror <more args...>
我的底线: