当指向特定类型(例如int, char, float, ..)的指针增加时,其值将按该数据类型的大小增加。如果指向大小为x的数据的空指针被增加,它如何提前x字节指向?编译器如何知道将x添加到指针的值?
当前回答
[从后面一个重复问题的评论中抄来的答案]
允许对空指针进行算术运算是一个有争议的、非标准的扩展。如果你在汇编语言中思考,指针只是地址,空指针的算术是有意义的,加1只是加1。但如果你用C语言来思考,使用C语言的指针算术模型,给任何指针p加1实际上是在地址上加sizeof(*p),这就是你想要的指针算术,但由于sizeof(void)为0,它对于void指针就失效了。
如果你用C语言思考,你不介意它被打破,你不介意插入显式类型转换到(char *),如果这是你想要的算术。但如果你在汇编程序中思考,你希望它只是工作,这就是为什么扩展(尽管偏离了C中指针算术的正确定义)在某些领域是可取的,并且由一些编译器提供。
其他回答
在进行指针算术之前,必须将它强制转换为另一种类型的指针。
你不能在void *类型上做指针算术,正是因为这个原因!
[从后面一个重复问题的评论中抄来的答案]
允许对空指针进行算术运算是一个有争议的、非标准的扩展。如果你在汇编语言中思考,指针只是地址,空指针的算术是有意义的,加1只是加1。但如果你用C语言来思考,使用C语言的指针算术模型,给任何指针p加1实际上是在地址上加sizeof(*p),这就是你想要的指针算术,但由于sizeof(void)为0,它对于void指针就失效了。
如果你用C语言思考,你不介意它被打破,你不介意插入显式类型转换到(char *),如果这是你想要的算术。但如果你在汇编程序中思考,你希望它只是工作,这就是为什么扩展(尽管偏离了C中指针算术的正确定义)在某些领域是可取的,并且由一些编译器提供。
C标准不允许空指针运算。然而,考虑到void的大小为1,GNU C是允许的。
C11标准§6.2.5
第19段
void类型由一组空值组成;这是一个不完整的 无法完成的对象类型。
以下程序在GCC编译器中工作良好。
#include<stdio.h>
int main()
{
int arr[2] = {1, 2};
void *ptr = &arr;
ptr = ptr + sizeof(int);
printf("%d\n", *(int *)ptr);
return 0;
}
可能是其他编译器产生错误。
在void指针中不允许进行指针算术运算。
原因:指针算术与普通算术不同,因为它是相对于基址发生的。
解决方案:在进行算术时使用类型强制转换操作符,这将使执行指针算术的表达式的基本数据类型已知。 例如:point是空指针
*point=*point +1; //Not valid
*(int *)point= *(int *)point +1; //valid