当前位置: 首页 > news >正文

C语言指针5

1.void*概述

void称为无类型,void*称为无类型指针,void不可以单独定义变量,却可以定义无类型的指针,而且所定义的指针称为泛型指针,所谓泛型指针,其含义是void*类型的指针可以接收一切类型变量的地址

struct Test {int x;char ch;
};void fun() {printf("this is a fun.\n");
}int main() {void* pv;char ch = 'A';pv = &ch;int a = 10;pv = &a;double d = 12.34;pv = &d;struct Test t;pv = &t;int ar[10] = { 1,2,3,4,5,6,7,8,9,10 };pv = &ar;pv = &fun;return 0;
}

 注:如果需要使用void*指针,需要重新强转为具体类型才可以使用,不可直接针对void*进行使用,如:

void* pv;char ch = 'A';
pv = &ch;
printf("%c\n", *(char*)pv);

malloc函数原型为:void* malloc(size_t size)

返回值为泛型指针,所以在使用malloc时需要对返回结果进行类型强转

struct Test t = (struct Test*)malloc(sizeof(struct Test));
pv = &t;

2.void*指针应用---通用函数

void* memcpy(void* dest, const void* src, size_t count)

//memcpy简易实现版,不考虑内存重叠问题
void* memcpy(void* dest, const void* src, size_t count) {assert(dest != NULL && src != NULL);char* pDest = (char*)dest;const char* pSrc = (const char*)src;while (count--)*pDest++ = *pSrc++;return dest;
}

内存泄漏检测工具:vld

strcpy和memcpy

char* str = (char*)"Hello String";
//char space[] = ""; //内存空间不足
char space[20] = ""
//strcpy(space, str);
memcpy(space,str,strlen(str)+1);

 注:

1.char space[20];

memcpy(space,str,strlen(str))会出现乱码

输出:Hello String烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫?j(?

2.strlen不会将末尾的\0计入长度,而sizeof会将末尾的\0计入长度

memcpy是一个类型无关的函数,接受的参数为泛型,上面实现的memcpy函数当源字符串和目的字符串出现内存重叠时会发生错误

 

void* my_memcpy(void* dest, const void* src, size_t count) {assert(dest != NULL && src != NULL);char* pDest = (char*)dest;const char* pSrc = (const char*)src;//判断内存是否重叠if (pSrc >= pDest || pDest >= (pSrc + count)) {while (count != 0) {//没有重叠,正向拷贝*pDest++ = *pSrc++;count--;}}else {//存在内存重叠,反向拷贝pSrc = pSrc + count - 1;pDest = pDest + count - 1;while (count != 0) {*pDest-- = *pSrc--;count--;}}return dest;
}

用冒泡排序模拟快排

cmp_函数可根据具体需求编写

int cmp_int(const void* e1, const void* e2) {return *(int*)e1 - *(int*)e2;
}int cmp_char(const void* e1, const void* e2) {return *(char*)e1 - *(char*)e2;
}int cmp_str(const void* e1, const void* e2) {return strcmp(*(char**)e1, *(char**)e2);
}void my_qsort(void* base, size_t num, size_t width,int (*compare)(const void* elem1, const void* elem2)) {for (int i = 0; i < num - 1; i++) {for (int j = 0; j < num - 1 - i; j++) {//默认升序if (compare((char*)base + j * width, (char*)base + (j + 1) * width) > 0) {Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);}}}
}

 测试

int main() {int ar[] = { 6,3,7,9,8,2,1,4,5 };int n = sizeof(ar) / sizeof(ar[0]);my_qsort(ar, n, sizeof(int), cmp_int);return 0;
}

http://www.xdnf.cn/news/137107.html

相关文章:

  • Swift中Class和Struct的深度对比分析
  • VS Code搭建C/C++开发环境
  • CAD版本之——DwgVersion 与 AutoCAD 版本的对应关系
  • UOJ 228 基础数据结构练习题 Solution
  • 【Java学习笔记】冒泡排序
  • 【网工第6版】第5章 网络互联⑪
  • Python 3.14:探索新版本的魅力与革新
  • 同样机身尺寸下伺服电机比无刷电机扭矩更大的原因
  • Mybatis-Plus,IDEA2024版本
  • top 命令里面可以看到进程哪些状态?
  • 浏览器常用快捷键
  • MDF标准
  • 高效使用DeepSeek对“情境+ 对象 +问题“型课题进行开题!
  • 关于开源大模型(如 LLaMA、InternLM、Baichuan、DeepSeek、Qwen 等)二次开发或训练经验的关键点和概述
  • Java基础第四章、面向对象
  • 从零开始用Turtle绘制分形树,数学与编程的完美结合!
  • 声音分离人声和配乐base,vocals,drums -从头设计数字生命第6课, demucs——仙盟创梦IDE
  • element-ui tabs 组件源码分享
  • 前端技术Ajax原理
  • 32.768kHz晶振详解:作用、特性及与其他晶振的区别
  • 什么是电容?
  • IDEA搭建环境的五种方式
  • 红黑树——如何靠控制色彩实现平衡的?
  • 第3讲:ggplot2完美入门与美化细节打磨——从基础绘制到专业级润色
  • OpenHarmony之电源管理子系统公共事件定义
  • Qt知识点1『16进制数值与文本互相转换』
  • HTML基础笔记
  • 【k8s】sidecar边车容器
  • 大型工程里 AI 编码困境重重,未来如何破局?
  • LeetCode -- Flora -- edit 2025-04-25