首页 > 其他分享 >理解C语言中的void类型的指针

理解C语言中的void类型的指针

时间:2023-09-22 23:23:35浏览次数:53  
标签:int void C语言 printf 类型 ptr 指针

1.void类型指针简介

  • void类型的指针又被称为泛型指针,通用型指针
  • void类型的指针:指针指向的内存地址中的数据的类型未知
  • 其他所有类型的指针都可以转换为void类型的指针,而且不需要强制类型转换(编译器会隐式/自动类型转换)
  • void类型的指针也可以转换为任意类型的指针,需要强制类型转换(实际上不需要,但是强制类型转换会增加代码的可读性,比如使用malloc函数的时候)
  • void类型的指针不可以直接解引用(dereference),强制类型转换之后才可以正常访问void指针指向的内存单元
int main() {
  int a = 10;
  // 指针p指向变量a, 但是p的类型仍然是void
  void* p = &a;
  printf("%d\n", *p);  // 错误,因为p是void类型的,编译器无法判断p可以访问几个字节
  printf("%d\n", *(int*)p);  // 正确,将p强制转换为int类型的指针,编译器就指导p指向的数据占用四个字节
  return 0;
}

2.探讨void类型指针为什么具有通用性?

2.1 以以下代码为例,通过void类型的指针p,可以正常访问不同类型的变量,因此,void类型的指针被成为泛型指针/通用型指针

2.2 除了void类型的指针之外,其他类型的指针不可以实现这种特性

#include <stdio.h>

int main(int argc, char* argv[]) {
  char a = 'H';
  int b = 10;
  float c = 2.8;
  double d = 9.7;
  void* p;
  
  // p saves the address of variable a
  p = &a;
  printf("a = %c\n", *(char*)p);
  
  // p saves the address of variable b
  p = &b;
  printf("b = %d\n", *(int*)p);
  
  // p saves the address of variable c
  p = &c;
  printf("c = %f\n", *(float*)p);
  
  // p saves the address of variable d
  p = &d;
  printf("d = %lf\n", *(double*)p);
  return 0;
}

3.void指针的应用:使用一个泛型指针可以遍历不同类型的数组!

#include <stdio.h>
enum type {
 CHAR,
 INT,
 DOUBLE
};

void generic_function(enum type t, void* ptr);

int main(int argc, char* argv[]) {
  // void type pointer / generic pointer / general-purpose pointer
  char ch_arr[] = "Hello";
  int int_arr[] = {3, 1, 2};
  double db_arr[] = {3.14, 2.7, 1.58, 20.4};
  
  // print the first element for each different type array
  generic_function(CHAR, ch_arr);
  generic_function(INT, int_arr);
  generic_function(DOUBLE, db_arr);
  
  return 0;
}

void generic_function(enum type t, void* ptr) {
  // t的类型指导泛型指针ptr如何访问数组(强制类型转换不同)
  switch(t) {
    case CHAR:
      printf("The first element is: %c\n", ((char*)ptr)[0]);
      break;
    case INT:
      printf("The first element is: %d\n", ((int*)ptr)[0]);
      break;
    case DOUBLE:
      printf("The first element is: %lf\n", ((double*)ptr)[0]);
      break;
    default:
      printf("No type matched!\n");
  }  
  
}

标签:int,void,C语言,printf,类型,ptr,指针
From: https://www.cnblogs.com/gjsun/p/17723570.html

相关文章

  • C语言中的函数指针以及模拟面向对象
    函数指针的概念顾名思义,函数指针就是指向函数的指针,该指针的值是函数的入口。下面的代码时函数指针的一个基本实例。#include<stdio.h>intmax_(inta,intb);intmax1_(int(*func_p)(int,int),inta,intb);intmain(){inta=10,b=20;//定义一个函......
  • C中指针之间的类型转换
    也许一个不兼容的指针可以访问变量#include<stdio.h>#include<stdlib.h>typedefstructfather{ intage; char*name;}father;typedefstructstudent{ intage; doubleheight; charsex;}student;intmain(){//initiatetwostuctvariablesstude......
  • 七天学会C语言-第七天(结构体)
    1.定义结构体例1:把一个学生的信息(包括学号、姓名、性别、住址等4项信息)放在一个结构体变量中,然后输出这个学生的信息。#include<stdio.h>structStudent{intstudent_id;charname[30];chargender;charaddress[60];};intmain(){struc......
  • C语言学习-- ~ 按二进制取位 前置后置++ 关系操作符 逻辑操作符
    #include<stdio.h>//~按二进制取位intmain(){inta=10;intb=~a;/*~按二进制取位如101--~=010*/printf("%d\n%d\n",a,b);/*运行a=10b=-11在二进制里的最高位表示符号位,0为正1为负(3=000…………011)源码......
  • C语言学习-- ~ 按二进制取位 前置后置++ 关系操作符 逻辑操作符
    #include<stdio.h>//~按二进制取位intmain(){inta=10;intb=~a;/*~按二进制取位如101--~=010*/printf("%d\n%d\n",a,b);/*运行a=10b=-11在二进制里的最高位表示符号位,0为正1为负(3=000…………011)源码......
  • 【三子棋】——玩家VS电脑(C语言实现)
    (文章目录)前言三子棋是黑白棋的一种。三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉、一条龙、井字棋等。将正方形对角线连起来,相对两边依次摆上三个双方棋子,只要将自己的三个棋子走成一条线,对方就算输了。但是,有很多时候会出现和棋的情况。:pig:好了话不多说,现在我就带大家......
  • 关于指针:
    1.voidp:p可以接受任意类型的地址。void类型的指针不能进行解引用操作。2.指针数组:intp[5];是一个数组,每个元素是int 数组指针:int(*p)[5]:是一个指针,指向一个5个元素类型是int的数组。函数指针:void(*p)(int,int):指向一个void类型参数是(int,int)的函数。3.voidadd(int......
  • c语言双指针法--原地删除数组中的元素
     27.移除元素-力扣(LeetCode) intremoveElement(int*nums,intnumsSize,intval){intleft=0;intright=0;while(right<numsSize){if(nums[right]!=val){nums[left]=nums[right];left++;}......
  • c语言-关键字static
    局部变量:运行周期=函数的运行周期全局变量:运行周期=整个程序的运行周期(程序可以是多个.c文件组成)static可以修饰:1、局部变量(函数内定义的)2、全局变量(函数外定义的) 3、函数1.修饰局部变量->静态局部变量:开辟存储空间。在编译的过程中,会在数据区为该变量开辟空间,并对其进行......
  • 快指针慢指针
    快指针和慢指针主要解决将某一目标值覆盖或抛到数组最后且不改变原数组剩下元素的顺序的问题快指针每次循环都会往后移动,慢指针只有快指针没有遇到目标值的时候才会往后移动,在慢指针移动之前还要对目标值进行覆盖或则交换操作。将目标值抛到最后https://leetcode.cn/problems/m......