void是什么意思(void 指针的背后藏着什么?)
1 不能动的“地址”之 void指针
文章插图
1.1 void指针初探void *表示一个“不知道类型”的指针 , 也就不知道从这个指针地址开始多少字节为一个数据 。 和用int表示指针异曲同工 , 只是更明确是“指针” 。
因此void *只能表示一个地址 , 不能用来&取值 , 也不能++和--移动指针 , 因此不知道多少字节是一个数据单位 。
int nums[] = {3,5,6,7,9}; void* ptr1 = nums; //int i = *ptr1; // 对于void指针没法直接取值 int* ptr2 = (int*)nums; printf("%d,%d/n",ptr1,ptr2); int i = *ptr2; printf("%d/n",i);从输出结果可以看出 , 无论是无类型的void指针还是int类型指针 , 指向的地址都是一样的:
文章插图
PS:void *就是一个不能动的“地址” , 在进行&、移动指针之前必须转型为类型指针 。1.2 void指针的用途
文章插图
这里我们看一下我们之前了解的memset函数 , 其第一个参数就是一个void指针 , 它可以帮我们屏蔽各种不同类型指针的差异 。
如下面代码所示 , 我们既可以传入一个int类型数组的指针 , 也可以传入一个char类型数组的指针:
int nums[20]; memset(nums,0,sizeof(nums)); char chs[2]; memset(chs,0,sizeof(chs));那么 , 我们也可以试着自己动手模拟一下这个memset函数 , 暂且命名为mymemset吧:
void mymemset(void *data,int num,int byteSize){ // char就是一个字节 , 而计算机中是以字节为单位存储的 char *ptr = (char*)data; int i; for(i=0;i<byteSize;i++) { *ptr=num; ptr++; }}int main(int argc, char *argv[]){ int nums[20]; mymemset(nums,0,sizeof(nums)); int i,len=sizeof(nums)/sizeof(int); for(i=0;i<len;i++) { printf("%d ",nums[i]); } printf("/n"); return 0;}在这个mymemset函数中 , 我们利用void指针接收不同类型的指针 , 利用char类型(一个字节)逐个字节读取内存中的每一个字节 , 最后依次填充指定的数字 。
由于char类型是一个具体类型 , 所以可以使用++或者--进行指针的移动 。
对于结构体类型 , 也可以使用我们的mymemset函数:
typedef struct _Person{ char *name; int age;} Person;Person p1;mymemset(&p1,0,sizeof(Person));printf("p1.Age:%d/n",p1.age);最终的运行结果如下图所示:
文章插图
void *的用途:在只知道内存 , 但是不知道是什么类型的时候 。2 函数指针2.1 指向函数的指针我们可以在C中轻松地定义一个函数指针:
typedef void (*intFunc)(int i);这里我们定义了一个无返回值的 , 只有一个int类型参数的函数指针intFunc 。
我们可以在main函数中使用这个函数指针来指向一个具体的函数(这个具体的函数定义需要和函数指针的定义一致):
void test1(int age){ printf("test1:%d/n",age);}int main(void){ // 声明一个intFunc类型的函数指针 intFunc f1 = test1; // 执行f1函数指针所指向的代码区 f1(8); return 0;}
推荐阅读
- 群晖ddns外部访问设置 群晖ddns设置教程
- 什么是耐心 耐心的意思
- 收入证明的模板 收入证明申请书
- 去旅行的粘土小刺猬玩偶做法
- 睡觉中的宝宝简笔画
- 富态的粘土小招财猫玩偶做法
- 水中的大鹅简笔画
- 哭泣的阿狸简笔画
- 偷吃苹果的小老鼠简笔画
- 萌萌的小老虎简笔画