C语言中void的高级应用
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
终于写完了,麻了!!!!!!!!!!!!