当指向特定类型(例如int, char, float, ..)的指针增加时,其值将按该数据类型的大小增加。如果指向大小为x的数据的空指针被增加,它如何提前x字节指向?编译器如何知道将x添加到指针的值?


当前回答

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*指针进行指针算术运算。

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;
}

可能是其他编译器产生错误。

将其转换为char型指针,使指针向前增加x字节。

编译器通过类型转换知道。给定一个void *x:

X +1向X增加一个字节,指针指向字节X +1 (int*)x+1添加sizeof(int)字节,指针指向字节x+ sizeof(int) (float*)x+1地址sizeof(float)字节, 等。

尽管第一项是不可移植的,并且反对C/ c++的Galateo,但它仍然是C语言正确的,这意味着它将在大多数编译器上编译成可能需要适当标志的东西(如-Wpointer-arith)

Void指针可以指向任何内存块。因此,当我们尝试对空指针进行指针算术时,编译器不知道要增加/减少多少字节。因此,必须首先将void指针类型转换为已知类型,然后才能将它们涉及到任何指针算术。

void *p = malloc(sizeof(char)*10);
p++; //compiler does how many where to pint the pointer after this increment operation

char * c = (char *)p;
c++;  // compiler will increment the c by 1, since size of char is 1 byte.