C语言中void的高级应用
C语言中的void关键字,void 表示为“无”、“空”、“没有”的意思。所以void是不能用来定义变量的,因为变量是需要固定的空间的
//定时时,编译不通过
void ch = 'a';
void a = 10;
一、void的常用场景
1.1 函数的参数
void 最常使用就是用在函数里面,第一个就是函数的参数。
int function(void);
int function();
这两个函数表示的意义是一样的,都是无参数、返回值为 int 类型的函数。
1.2函数的返回类型
void 的另一个作用,就是在函数的返回类型上面。
有时候,我们只需要函数运行的过程,而不是为了获取最后的结果。此时就可以使用 void 类型,表示该函数没有返回值。
void function(int a, int b);
以上void的常用场景,就不多细讲解了。
二、void的高级应用
*void 的高级应用其实就void 指针。
void指针一般被称为通用指针或叫泛指针。它是C语言关于纯粹地址的一种约定。当某个指针是void型指针时,所指向的对象不属于任何类型。 因为void指针不属于任何类型,则不可以对其进行算术运算,比如自增,编译器不知道其自增需要增加多少。比如char *型指针,自增一定是指针指向的地址加1,short *型指针自增,则偏移2。
当使用关键字void声明指针变量时,它将成为通用指针变量。任何数据类型(char,int,float等)的任何变量的地址都可以赋值给void指针变量。
对指针变量的解引用,使用间接运算符*达到目的。但是在使用空指针的情况下,需要转换指针变量以解引用。这是因为空指针没有与之关联的数据类型。编译器无法知道void指针指向的数据类型。因此,要获取由void指针指向的数据,需要使用在void指针位置内保存的正确类型的数据进行类型转换。
来看下linux下的函数,它就是就是使用了void指针。
*void 做为形参
#include <pthread.h>
//线程创建 void *arg
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
*void 做为函数返回值
#include <sys/mman.h>
//IO映射 void * 函数返回void *
void *mmap(void *addr, size_t len, int prot, int flags,int fildes, off_t off);
2.1 void *做为形参
void *做为形参,实参可以是变量、数组、结构体指针。下面分别分三个案例分析,如果使用void *
2.1.1 void *做为形参,实参是变量
#include <stdio.h>//函数声明
int int_fum(void *a, void *b);int main(void)
{//变量可以是char short int long float double类型int i = 100, j = 200, num;//调用时,必须要强制转成指针类型 int *num = int_fum((int *)&i, (int *)&j);printf("num:%d\n", num);return 0;
}int int_fum(void *a, void *b)
{int num;//在使用时,必须强制说明是什么类型指针 且强制转的类型要与调用时是一致的。num = (*(int *)a) + (*(int *)b);return num;
}
输出结果
num:300
2.1.2 void *做为形参,实参是数组
#include <stdio.h>//函数声明
void arr_fun(void *arr, int len);int main(void)
{//数组可以是char short int long float double类型int arr[10] = {1,2,3,4,5,6,7,8,9,0};arr_fun((int *)arr, 10);return 0;
}void arr_fun(void *arr, int len)
{int i;for(i=0; i<len; i++){//在使用时,必须强制说明是什么类型指针 且强制转的类型要与调用时是一致的。printf("%d\t", *((int *)arr+i));}}
输出
1 2 3 4 5 6 7 8 9 0
2.1.2 void *做为形参,实参是结构体指针
#include <stdio.h>
#include <stdlib.h>struct info
{int age;int high;
};//函数声明
void struct_fun(void *stuinfo);int main(void)
{struct info *stu;//开辟内存空间stu = malloc(sizeof(struct info));//函数调用struct_fun((struct info *)stu);//打印结果printf("stu->age:%d\n", stu->age);printf("stu->high:%d\n", stu->high);//释放空间free(stu);return 0;
}void struct_fun(void *stuinfo)
{//强制转换指针类型为struct info *struct info *p = (struct info *)stuinfo;//成员赋值p->age = 10;p->high = 170;
}
结果
stu->age:10
stu->high:170
2.2 void *做为函数返回的指针
2.2.1 返回整型指针
//返回的指针,那么函数必须要给指针开辟相关的空间
#include <stdio.h>
#include <stdlib.h>//函数声明
void *int_fun(int len);int main(void)
{int *p;//调用时,开辟的空间强制转化为指向整型的指针 (int *)p = (int *)int_fun(4);//对开辟的空间进行赋值*p = 100;printf("*p:%d\n", *p);//释放空间free(p);return 0;
}void *int_fun(int len)
{//必须定义为void *的指针。void *p;//开辟空间p = malloc(len);//返回void *指针,与函数要求返回类型一致。return p;
}
输出结果
*p:100
2.2.2 返回数组指针
#include <stdio.h>
#include <stdlib.h>//函数声明
void *arr_fun(int len);int main(void)
{int i;//定义数组int arr[10];int *parr = arr;//调用时,开辟的空间强制转化为指向整型的指针 (int *) parr = (int *)arr_fun(sizeof(arr));//对数组进行赋值for(i=0; i<10; i++){*(parr+i) = i*i;}//对数组进行打印for(i=0; i<10; i++){printf("%d\t", *(parr+i) );}//释放空间free(parr);return 0;
}void *arr_fun(int len)
{//必须定义为void *的指针。void *p;//开辟空间p = malloc(len);//返回void *指针,与函数要求返回类型一致。return p;
}
输出
0 1 4 9 16 25 36 49 64 81
2.2.2 返回结构体指针
#include <stdio.h>
#include <stdlib.h>struct info
{int age;int high;
};//函数声明
void *struct_fun(int len);int main(void)
{int i;struct info *stu;//调用时,开辟的空间强制转化为指向整型的指针 (struct info *) stu = (struct info *)struct_fun(sizeof(struct info));//对结构体进行赋值stu->age = 10;stu->high = 170;//打印结果printf("stu->age:%d\n", stu->age);printf("stu->high:%d\n", stu->high);//释放空间free(stu);return 0;
}void *struct_fun(int len)
{//必须定义为void *的指针。void *p;//开辟空间p = malloc(len);//返回void *指针,与函数要求返回类型一致。return p;
}
输出结果
stu->age:10
stu->high:170
终于写完了,麻了!!!!!!!!!!!!