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

指针(五)后半

1、 qsort 函数

1.1、qsort 函数排列结构体

在这里,我们创建结构体类型的数组,用于 qsort 函数的传参。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>struct Stu//创建结构体变量
{char name[30];int age;
};struct Stu arr[] = { { "zhangsan", 18 }, { "lisi", 20 }, { "wangwu", 38 } };void Print(struct Stu* p, int sz)//打印函数
{for (int i = 0; i < sz; i++){printf("%s: %d\n", p->name, p->age);p++;}
}cmp_str_by_age(const void* p1, const void* p2)//排年龄函数
{return (((struct Stu*)p1)->age - ((struct Stu*)p2)->age);
}test1()//按年龄大小
{int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), cmp_str_by_age);Print(arr, sz);
}cmp_str_by_name(const void* p1, const void* p2)//排姓名函数
{return strcmp(((struct Stu*)p1)->name, ((struct Stu*)p2)->name);
}test2()//按姓名
{int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), cmp_str_by_name);Print(arr, sz);
}int main()
{test1();printf("-------------------------\n");test2();return 0;
}

这里讲两点:

1、结构成员访问操作符: ->

使用方法为:结构体指针 -> 成员变量。上面代码中, ((struct Stu*)p1)->age 也可以换为 *(struct Stu*)p1.age 。

2、 strcmp 函数

使用方法为,向函数中传入两个字符串类型的数据,比较对应位置字符的 ASCII 码值的大小。以顺序为例,若前一个字符串对应位置字符的 ASCII 码值应大于后一个,返回大于0的值;相等返回0,小于返回小于0的值。

1.2、 qsort 函数的模拟实现

既然要实现 qsort 函数,那么向其中传入的参数,也应该是:首元素地址、元素个数、元素大小、比较函数。

#include<stdio.h>int int_cmp(const void* p1, const void* p2)
{return *(int*)p1 - *(int*)p2;
}void Bubble_qsort(void* base, int count, int size, int (*cmp)(void*, void*))}void test1()
{int arr[] = { 4,5,2,7,9,12,34,101 };int count = sizeof(arr) / sizeof(arr[0]);Bubble_qsort(arr, count, sizeof(arr[0]), int_cmp);
}int main()
{test1();//实现整型值的排序return 0;
}

将这个函数的名字取为 Bubble_qsort ,是因为我们将用冒泡排列的方式来模拟实现 qsort 函数。

所以,我们要交代趟数,也要交代每趟交换数据的次数。

而交换操作中,我们可以将每两个数(的地址)传入 int_cmp 函数中,观察返回的值。若返回正数值,则再创建一个交换函数。

但是, void* 类型的指针不能进行任何操作。也许会用强制类型转换,转换成什么? int* ?但这可是在模拟 qsort 函数,这个函数原来是可以排列任意类型的数据的。

所以,我们不妨将 void* 类型,强制转换成 char* 类型

#include<stdio.h>int int_cmp(const void* p1, const void* p2)
{return *(int*)p1 - *(int*)p2;
}void Swap(char* buf1, char* buf2)
{}void Bubble_qsort(void* base, int count, int size, int (*cmp)(void*, void*))
{for (int i = 0; i < count - 1; i++){for (int j = 0; j < count - i - 1; j++){if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0){Swap((char*)base + j * size, (char*)base + (j + 1) * size, size);}}}
}void test1()
{int arr[] = { 4,5,2,7,9,12,34,101 };int count = sizeof(arr) / sizeof(arr[0]);Bubble_qsort(arr, count, sizeof(arr[0]), int_cmp);
}int main()
{test1();//实现整型值的排序return 0;
}

而在交换函数中,既然地址已被强制转换成 char* ,那么我们就不能一次性交换干净,而是一点一点交换。交换的次数,自然是元素的大小。

#include<stdio.h>void Print(int arr[], int count)//打印函数
{for (int i = 0; i < count; i++){printf("%d ", arr[i]);}printf("\n");
}int int_cmp(const void* p1, const void* p2)//比较函数
{return *(int*)p1 - *(int*)p2;
}void Swap(char* buf1, char* buf2, int size)//交换函数
{for (int i = 0; i < size; i++){char tmp = *(buf1 + i);*(buf1 + i) = *(buf2 + i);*(buf2 + i) = tmp;}
}void Bubble_qsort(void* base, int count, int size, int (*cmp)(void*, void*))
{                                                   //模拟 qsort 的函数for (int i = 0; i < count - 1; i++){for (int j = 0; j < count - i - 1; j++){if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0){Swap((char*)base + j * size, (char*)base + (j + 1) * size, size);}}}
}void test1()
{int arr[] = { 4,5,2,7,9,12,34,101 };int count = sizeof(arr) / sizeof(arr[0]);Print(arr, count);Bubble_qsort(arr, count, sizeof(arr[0]), int_cmp);Print(arr, count);
}int main()
{test1();//实现整型值的排序return 0;
}

这样一来,这个函数连结构体都能排列。但是要加一点比较函数代码:

#include<stdio.h>struct Stu//创建结构体
{char name[30];int age;
};void Print(int arr[], int count)//打印函数
{for (int i = 0; i < count; i++){printf("%d ", arr[i]);}printf("\n");
}void Print1(struct Stu* p, int sz)//打印结构体
{for (int i = 0; i < sz; i++){printf("%s: %d\n", p->name, p->age);p++;}
}int int_cmp(const void* p1, const void* p2)//比较函数
{return *(int*)p1 - *(int*)p2;
}int cmp_str_by_name(const void* p1, const void* p2)//比较字符串
{if (strcmp(((struct Stu*)p1)->name, ((struct Stu*)p2)->name) > 0)return 1;else if (strcmp(((struct Stu*)p1)->name, ((struct Stu*)p2)->name) < 0)return -1;elsereturn 0;
}void Swap(char* buf1, char* buf2, int size)//交换函数
{for (int i = 0; i < size; i++){char tmp = *(buf1 + i);*(buf1 + i) = *(buf2 + i);*(buf2 + i) = tmp;}
}void Bubble_qsort(void* base, int count, int size, int (*cmp)(void*, void*))
{                                                   //模拟 qsort 的函数for (int i = 0; i < count - 1; i++){for (int j = 0; j < count - i - 1; j++){if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0){Swap((char*)base + j * size, (char*)base + (j + 1) * size, size);}}}
}void test1()
{int arr[] = { 4,5,2,7,9,12,34,101 };int count = sizeof(arr) / sizeof(arr[0]);Print(arr, count);Bubble_qsort(arr, count, sizeof(arr[0]), int_cmp);Print(arr, count);
}void test2()
{struct Stu arr[] = { { "zhangsan", 18 }, { "lisi", 20 }, { "wangwu", 38 } };int count = sizeof(arr) / sizeof(arr[0]);Print1(arr, count);printf("-------------------------\n");Bubble_qsort(arr, count, sizeof(arr[0]), cmp_str_by_name);Print1(arr, count);
}int main()
{//test1();//实现整型值的排序test2();//实现结构体的排列return 0;
}


文章转载自:

http://06JPNQK6.jgcrr.cn
http://VEIrl5As.jgcrr.cn
http://zHCLSiNL.jgcrr.cn
http://9sw4X5F5.jgcrr.cn
http://81Uc2R0x.jgcrr.cn
http://ToDiTlz4.jgcrr.cn
http://f6KAHLqr.jgcrr.cn
http://ip6YEHWW.jgcrr.cn
http://yW4Wq15I.jgcrr.cn
http://eLTKAugY.jgcrr.cn
http://BKlluQXr.jgcrr.cn
http://cCQ1ox2E.jgcrr.cn
http://qvSYxWnO.jgcrr.cn
http://9XPsoxPN.jgcrr.cn
http://bXCptaxG.jgcrr.cn
http://jP2e8oY3.jgcrr.cn
http://w5u6vRwj.jgcrr.cn
http://vunNmUgw.jgcrr.cn
http://RvQa5yQS.jgcrr.cn
http://Off0vhqb.jgcrr.cn
http://nTU77ao7.jgcrr.cn
http://81axApNt.jgcrr.cn
http://D1MBcMUx.jgcrr.cn
http://fxnOrcD8.jgcrr.cn
http://JZPhebsw.jgcrr.cn
http://wRcBB6nk.jgcrr.cn
http://ahQXHeOE.jgcrr.cn
http://oMXIOGxM.jgcrr.cn
http://QwBvgjjR.jgcrr.cn
http://hmMHyO5U.jgcrr.cn
http://www.dtcms.com/a/381740.html

相关文章:

  • 贪心算法在GNN邻域采样问题中的深度解析
  • MongoDB简介
  • ego(4)---检测B样条轨迹的障碍物进入点与退出点
  • mysql 与 MongoDB 的分片
  • 大语言模型基石:Transformer
  • 【Flink】窗口
  • 2.3单链表
  • [RK3566][Android13] Android->屏蔽锁屏界面的时钟和日期显示
  • jetson orin super nano(arm linux系统)上读取大恒图像工业相机(型号MER-050-560U3C)教程
  • 关于Gateway configration studio软件配置网关
  • xtuoj 随机数
  • [硬件电路-186]:二极管的伏安特性看男女关系2:二极管的正向导通电流与动态电阻成反比关系
  • 网络安全渗透测试第一步信息收集
  • 界面规范11-对话框
  • 基于QCharView类封装绘制各种图表的示例(支持自画图形)
  • IoC / DI 实操
  • 一、Python开发准备
  • 《IDEA 突然“三无”?三秒找回消失的绿色启动键、主菜单和项目树!》
  • 解释 ICT, Web2.0, Web3.0 这些术语的中文含义
  • 区块链web3项目实战-Truffle petshop
  • 区块链学习笔记
  • NFT盗窃潮:法律视野下的区块链取证技术与数字资产保卫战
  • 数据分析:合并二
  • 怎么生成qt的pro文件
  • ChatGPT全面支持MCP,带来更多可能性
  • Qt第一课:Qt是什么?相对于其他框架的优劣势是什么
  • OPENGLPG第九版学习 - 细分着色器
  • 【官网开发】Docusaurus 建站初探-TypeScript 版-1
  • 征程 6 灰度图部署链路介绍
  • 爱图表:镝数科技推出的智能数据可视化平台