首页 > 编程笔记

C语言void指针的使用

在C语言中,可以声明指向 void 类型的指针,指向 void 类型的指针称为 void 指针。void 在C语言中表示“无类型”,void 指针则为无类型指针,void 指针可以指向任何类型的数据。

C语言中引入 void 指针的目的在于两个方面,一是对函数返回的限定,二是对函数参数的限定。

此外,一般来说,只能用指向相同类型的指针给另一个指针赋值,而在不同类型的指针之间进行赋值是错误的。比如:

int a,b;
int *p1=&a,*p2=p1;        /* 正确 */

int a;
int *p1=&a;
double *p2=p1;           /* 错误 */

上述语句中的两个指针 p1、p2 指向的类型不同,因此,除非进行强制类型转换,否则它们之间不能相互赋值。

如果在C语言中编译如上类型不同的指针赋值,编译器将给出“Suspicious pointer conversion”的错误,void 指针对于上述出现的错误而言是一个特例,C语言允许使用 void 指针,任何类型的指针都可以赋值给它,即不指定指针指向一个固定的类型。

C语言中 void 指针的定义格式为:

void *p;

上述定义表示指针变量 p 不指向一个确定的类型数据,其作用仅仅是用来存放一个地址。

void 指针可以指向任何类型的数据。也就是说,可以用任何类型的指针直接给 void 指针赋值。例如,下面语句在C语言中是合法的:

int *p1;
void *p2;
p2=p1;


需要注意的是,void 类型指针可以接受其他数据类型指针的赋值,但如果需要将 void 指针的值赋给其他类型的指针,则还是需要进行强制类型转换。例如,下面语句也是合法的:

int *p1,p3; 
void *p2;
p2=p1;
p3=(int *)p2;

上述语句将 void 类型的指针 p2 赋值给 int 指针 p3 时就用了强制类型转换,如果不加 “(int*)” 进行类型转换,上述语句就是错误的。

这就是说,任何类型的指针都可以直接给 void 指针赋值,但 void 指针并不能直接给任何类型的指针赋值。

【示例1】定义 void 指针,实现指针强制类型转换。代码如下:
#include <stdio.h>
int main()
{
    int a=10;
    int *p1=&a;  /* 定义整型指针p1并初始化 */
    void *p2=p1;   /* 定义void指针p2并赋初值 */
    int *p3;
    p3=(int *)p2;    /* 强制类型转换 */
    printf ("*p1= %d\n",*p1);     /* 输出这些指针各自指向的值 */
    printf ("p2=  %d\n",p2);
    printf ("*p3=  %d\n",*p3);
}
运行结果:

*p1= 10
p2=  6487556
*p3=  10

上述代码中定义了整型指针 p1 和 p3,此外还定义了 void 指针 p2,将 p1 和 p3 指向的值输出,将 p2 的地址输出。在用 void 指针 p2 对整型指针 p3 进行初始化时,使用了强制类型转换来实现。

一般来说,void 关键字在C语言程序中使用较多,功能比较丰富,除了可以声明 void 指针外,还可以作为函数返回值等。

在C语言中使用 void 关键字,需要注意如下事项。

1) 如果函数没有返回值,应声明为 void 类型。在C语言中,凡不加返回值类型限定的函数就会被编译器作为返回整型值处理。例如,有些示例的主函数没有限定返回值,而直接写 main(),这样就相当于 int main(),而不是 void main()。

2) 如果函数不接受参数,应指明参数为 void。在C语言中,可以给无参数的函数传送任意类型的参数,如果该函数不接受参数,指明其参数为 void 后,该函数将不能接受参数。例如,声明函数 fun(void) 后,其不能再接受参数及其传递。

3) 不能对 void 指针进行算术运算。ANSI C 标准规定不能对 void 指针进行算术运算,因此声明 void 指针 p 后,p++,p-- 等都是不合法的。

4) 如果函数的参数可以是任意类型指针,那么应声明其参数为 void*,即 void 指针型。void 不能代表一个真实的变量。在C语言中定义 void 变量是不合法的,例如,语句 void a;就是错误的。

注意:void 指针不等同于空指针,void 指针是指没有指向任何数据的指针,即其指向的是一块空的内存区域,而空指针是指向 NULL 的指针,其指向的是具体的区域。

优秀文章