到目前为止,我们已经研究了分配给指针的地址应该与指针声明中指定的类型相同。例如,如果我们声明一个int指针,则此int指针不能指向float变量或某种其他类型的变量,即它只能指向int类型的变量。为了克服这个问题,我们使用了指向void的指针。指向void的指针表示可以指向任何数据类型的通用指针。我们可以将任何数据类型的地址分配给void指针,并且可以将void指针分配给任何类型的指针,而无需执行任何显式的类型转换。
空指针的语法
void *pointer name;
下面给出了void指针的声明:
void *ptr;
在上面的声明中,void是指针的类型,而’ ptr’ 是指针的名称。
让我们考虑一些示例:
int i = 9; //整数变量初始化。
int * p; //整数指针声明。
浮动* fp; //浮动指针声明。
无效* ptr; // void指针声明。
p = fp; //不正确。
fp =
PTR = P; //正确
ptr = fp; //正确
PTR =
C语言中void指针的大小
C中的void指针的大小与字符类型的指针的大小相同。根据C感知,指向void的指针的表示形式与字符类型的指针相同。指针的大小将根据所使用的平台而有所不同。
让我们看下面的例子:
#include <
stdio.h>
int main()
{
void *ptr = NULL;
//void pointer
int *p= NULL;
// integer pointer
char *cp = NULL;
//character pointer
float *fp = NULL;
//float pointer
//size of void pointer
printf("size of void pointer = %d\n\n", sizeof(ptr));
//size of integer pointer
printf("size of integer pointer = %d\n\n", sizeof(p));
//size of character pointer
printf("size of character pointer = %d\n\n", sizeof(cp));
//size of float pointer
printf("size of float pointer = %d\n\n", sizeof(fp));
return 0;
}
输出量
文章图片
无效指针的优点
以下是void指针的优点:
- malloc()和calloc()函数返回void指针,因此这些函数可用于分配任何数据类型的内存。
#include <
stdio.h>
#include<
malloc.h>
int main()
{
int a=90;
int *x = (int*)malloc(sizeof(int)) ;
x=&a;
printf("Value which is pointed by x pointer : %d", *x);
return 0;
}
输出量
文章图片
- C中的void指针也可以用于实现C中的泛型函数。
- 取消引用C中的void指针
#include <
stdio.h>
int main()
{
int a=90;
void *ptr;
ptr=&a;
printf("Value which is pointed by ptr pointer : %d", *ptr);
return 0;
}
在上面的代码中,* ptr是一个空指针,它指向整数变量“ a”。我们已经知道不能取消引用void指针,因此上面的代码将给出编译时错误,因为我们直接打印指针ptr指向的变量的值。
输出量
文章图片
现在,我们重写上面的代码以消除错误。
#include <
stdio.h>
int main()
{
int a=90;
void *ptr;
ptr=&a;
printf("Value which is pointed by ptr pointer : %d", *(int*)ptr);
return 0;
}
在上面的代码中,我们使用下面给出的语句将void指针转换为整数指针:
(中间体*)的ptr;
然后,使用下面给出的语句,打印由空指针“ ptr”指向的变量的值:
*(中间体*)的ptr;
输出量
文章图片
- 空指针的算术运算
让我们看下面的例子:
#include<
stdio.h>
int main()
{
float a[4]={6.1, 2.3, 7.8, 9.0};
void *ptr;
ptr=a;
for(int i=0;
i<
4;
i++)
{
printf("%f, ", *ptr);
ptr=ptr+1;
// Incorrect.}}
上面的代码显示了“无效使用void表达式”的编译时错误,因为我们不能直接对void指针应用算术运算,即ptr = ptr 1。
让我们重写上面的代码以消除错误。
#include<
stdio.h>
int main()
{
float a[4]={6.1, 2.3, 7.8, 9.0};
void *ptr;
ptr=a;
for(int i=0;
i<
4;
i++)
{
printf("%f, ", *((float*)ptr+i));
}}
上面的代码成功运行,因为我们对void指针即(float *)ptr应用了正确的转换,然后对*((float *)ptr i)应用了算术运算。
输出量
文章图片
为什么我们使用空指针?
由于其可重用性,我们使用空指针。空指针可以存储任何类型的对象,并且我们可以通过使用带有适当类型转换的间接操作符来检索任何类型的对象。
让我们通过一个例子来理解。
#include<
stdio.h>
int main()
{
int a=56;
// initialization of a integer variable 'a'.
float b=4.5;
// initialization of a float variable 'b'.
char c='k';
// initialization of a char variable 'c'.
void *ptr;
// declaration of void pointer.
// assigning the address of variable 'a'.
ptr=&a;
printf("value of 'a' is : %d", *((int*)ptr));
// assigning the address of variable 'b'.
ptr=&b;
printf("\nvalue of 'b' is : %f", *((float*)ptr));
// assigning the address of variable 'c'.
ptr=&c;
printf("\nvalue of 'c' is : %c", *((char*)ptr));
return 0;
}
【c中的空指针】输出量
文章图片