「2」指针进阶——详解
🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀
目录
🐰指向函数指针数组的指针(很少用,了解)
🐰回调函数(通过函数指针调用函数)
🐰快速排序
🌸冒泡排序
🌸qsort()
🐰用冒泡排序类似实现qsort
🐰指向函数指针数组的指针(很少用,了解)
#include<stdio.h> void Add(int ,int) {printf("%d\n",1+1); } void Sub(int ,int) {printf("%d\n",1-1); } int main() {int (*pf)(int,int)=Add;//函数指针int (*pfArr[4])(int,int)={Add,Sub};//函数指针数组int (*(*ppfArr)[4])(int,int)=&pfArr;//ppfArr就是指向函数的指针数组的指针return 0; }
🐰回调函数(通过函数指针调用函数)
通过回调函数实现 两个操作数的加减乘除:#include<stdio.h> void Calc(int(*pf)(int,int)) {int x=0,y=0;printf("请输入两个操作数\n");scanf("%d %d",&x,&y);int ret=pf(x,y);printf("%d\n",ret); } int Add(int x,int y) {return x+y; } int Sub(int x,int y) {return x-y; } int Mul(int x,int y) {return x*y; } int Div(int x,int y) {return x/y; } void menu(void) {printf("**** 两位数的计算器 ****\n");printf("**** 1.Add 2.Sub ****\n");printf("**** 3.Mul 4.Div ****\n");printf("**** 0.exit ****\n"); } int main() {int input=0;do{menu();printf("请选择\n");scanf("%d",&input);switch(input){case 1:Calc(Add);break;case 2:Calc(Sub);break;case 3:Calc(Mul);break;case 4:Calc(Div);break;case 0:printf("exit\n");break;default:printf("输入错误\n");}}while(input); }
🐰快速排序
qsort是一个库函数,是用来排序(使用的快速排序的方法)1.库函数里的,可以直接使用 2.可以排序任意类型的数据
🌸冒泡排序
#include<stdio.h>void Bubble(int arr[],int len) {int i=0,j=0;for(i=0;i<len-1;i++){for(j=0;j<len-1-i;j++){if(arr[i]>arr[j+1]){int temp=arr[j];arr[j]=arr[j+1];arr[j+1]=temp;}}} } void Print(int arr[],int len) {for(int i=0;i<len;i++){printf("%d ",arr[i]);}printf("\n"); } int main() {int arr[]={3,2,1,5,7,8,9,0};int len=sizeof(arr)/sizeof(arr[0]);Bubble(arr,len);Print(arr,len); }
🌸qsort()
qsort的原型:void qsort (void* base, size_t num, size_t size,int (*compar)(const void*,const void*));
void qsort (void* base//指向了待排序数组的第一个元素的地址, size_t num(无符号整形)//待排序的元素个数, size_t size(无符号整形)//每个元素的大小,单位是字节,int (*compar)(const void*,const void*)//这里是一个函数指针,指向一个函数,这个函数可以比较2个元素的大小);
比较函数:就是函数指针campar指向的函数,因为使用qsort时,要自己定义比较函数,以下是常见的比较函数比较整形变量时 int cmp_int(const void* e1, const void* e2) {return *(int*)e1 - *(int*)e2; }
比较浮点型变量时 int cmp_float(const void* e1, const void* e2) {return (int)(*(float*)e1 - *(float*)e2); }
比较字符串变量时 int cmp_str_size(const void* e1, const void* e2) {return strcmp((char*)e1,(char*)e2); }
比较字符串长度时 int cmp_str_len(const void* e1, const void* e2) {return strlen((char*)e1)-strlen((char*)e2); }
比较结构体变量时 int cmp_by_age(const void*e1, const void*e2) {return (int)((stu*)e1)->weight - ((stu*)e2)->weight)); }
cmp函数的返回值:返回值<0(不进行置换),>0(进行置换),0(不进行置换)。记得返回的结果一定是整形的,如果不是需要强制转为整形的
‼️注:void*的指针不能解引用,也不能算术运算下面是使用qsort排序整形变量和结构体变量的原码:#include<stdio.h> #include<stdlib.h> #include<string.h> int cmp_int(const void* e1,const void* e2)//对整形比较 {return *(int*)e1-*(int*)e2; }void test_1() {int arr[]={2,3,4,5,6,7,1};int sz=sizeof(arr)/sizeof(arr[0]);//计算出数组下标,就不用手动去数有多少个元素了//这里需要提供一个比较函数,这个比较函数能够比较2个整数的大小//qsort默认为升序qsort(arr,sz,sizeof(arr[0]),cmp_int);for(int i=0;i<sz;i++){printf("%d ",arr[i]);} } struct stu//定义了一个包含字符类型,整形,浮点型的结构体 {char name[20];int age;float weight; }; int sort_by_name(const void* e1,const void* e2)//对字符串的比较 {return strcmp(((struct stu*)e1)->name,((struct stu*)e2)->name); }int sort_by_age(const void* e1,const void* e2)//对整形的比较 {return ((struct stu*)e1)->age-((struct stu*)e2)->age; }int sort_by_weight(const void* e1,const void* e2)//对浮点型比较 {return ((struct stu*)e1)->weight-((struct stu*)e2)->weight; } void test_2()//对结构体进行排序 {struct stu s[3]={{"zhangsan",23,65.5},{"lisi",27,56.5},{"wangwu",24,64}};int sz=sizeof(s)/sizeof(s[0]);qsort(s, sz, sizeof(s[0]), sort_by_name);//对名字排序for(int i=0;i<sz;i++)//输出排序后的结果{printf("%s ",s[i].name);}printf("\n");qsort(s, sz, sizeof(s[0]), sort_by_age);//对年龄排序for(int i=0;i<sz;i++){printf("%d ",s[i].age);}printf("\n");qsort(s, sz, sizeof(s[0]), sort_by_weight);//对体重排序for(int i=0;i<sz;i++){printf("%.2f ",s[i].weight);}printf("\n"); } int main() {test_1();test_2();return 0; }
🐰用冒泡排序类似实现qsort
#include<stdio.h> void swap(char* buf1,char*buf2,int width) //为什么不直接进行交换,而是交换每个字节的内容?这是因为这交换的不只是整形变量,这里还可以交换其它类型的变量{for(int i=0;i<width;i++){char temp=*buf1;*buf1=*buf2;*buf2=temp;buf1++;buf2++;} } void buble_sort(void* base,int sz,int width,int (*cmp)(const void*e1,const void*e2))//这里的函数指针可以方便调用各种类型比较,不同类型的变量比较,可以调用不同类型的比较函数 {int i=0,j=0;//sz个元素就有sz-1趟for(i=0;i<sz-1;i++){for(j=0;j<sz-1-i;i++){//两个元素的比较//arr[j] arr[j+1]if(cmp((char*)base+j*width,(char*)base+(j+1)*width)>0)//为什么将base强制转化为(char*)呢?假如比较的是整形变量,我们将base转化为(char*),加上width(就是这里的整形变量的大小,4字节)就可以找到下个元素的地址,{//交换swap((char*)base+j*width,(char*)base+(j+1)*width,width);//然后把这个变量的地址传给交换函数}}} } int cmp_int(const void* e1,const void* e2)//对整形比较 {return *(int*)e1-*(int*)e2; } int main() {int arr[10]={2,3,4,5,6,7,1,9,13,10};int sz=sizeof(arr)/sizeof(arr[0]);buble_sort(arr,sz,sizeof(arr[0]),cmp_int);for(int i=0;i<sz;i++){printf("%d ",arr[i]);}return 0; }
🌸🌸🌸如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 🌸🌸🌸
相关文章:

「2」指针进阶——详解
🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀 目录 🐰指向函数指针数组的指针(很少用,了解) 🐰回调函数&…...
计网笔记 网络层(端到端的服务)
第三章 网络层(端到端的服务) **TCP/IP体系中网络层向上只提供简单灵活的、无连接的、尽最大努力交付的数据报服务。**网路层不提供服务质量的承诺,不保证分组交付的时限,所传送的分组可能出错、丢失、重复和失序。进程之间通信的…...
[蓝桥杯 2018 省 B] 日志统计——双指针算法
题目描述小明维护着一个程序员论坛。现在他收集了一份“点赞”日志,日志共有 N 行。其中每一行的格式是 ts id,表示在 ts 时刻编号 id 的帖子收到一个“赞”。现在小明想统计有哪些帖子曾经是“热帖”。如果一个帖子曾在任意一个长度为 DD 的时间段内收到…...

SpringMVC请求转发和重定向
请求转发:forward:重定向:redirect转发:由服务器的页面进行跳转,不需要客户端重新发送请求:特点如下:1、地址栏的请求不会发生变化,显示的还是第一次请求的地址2、请求的次数,有且仅…...

如何建立项目标准化评价体系?【锦狸】
PMO团队面临着管理多个项目,甚至是多个项目集,多个产品集的问题,那么如何对项目们进行标准化评价体系的建设,就是PMO需要首先思考的问题。 首先我们要关注项目的背景,了解了项目背景之后,我们才可以明确项…...

Vue基础入门讲义(二)-语法基础
文章目录1.vue入门案例1.1.HTML模板1.2.vue渲染1.3.双向绑定1.4.事件处理2.Vue实例2.1.创建Vue实例2.2.模板或元素2.3.数据2.4.方法3.生命周期钩子3.1.生命周期3.2.钩子函数3.3.this1.vue入门案例 1.1.HTML模板 在项目目录新建一个HTML文件 01-demo.html 1.2.vue渲染 01-d…...
应广单片机用8位乘法器实现16位乘法运算
应广单片机例如pms150,pms152这种是没有带乘法器的,如果需要进行乘法运算,可以用ide里面“程序产生器”菜单里面 产生乘法函数,把数据填入对应的参数,然后调用函数就可以实现乘法运算了。除此之外,应广还有…...

Android中使用GRPC简明教程
引言 Android作为一个开发平台,本身是使用java进行封装的,因此java可以调用的库,在Android中同样可以进行调用,这样就使得Android设备具有丰富的功能,可以进行各种类型的开发。 这篇文章就介绍如何在Android设备中使…...

【Linux】使用U盘自动化安装Linux(VMware虚拟机)
文章目录前言一、准备二、新建虚拟机2.1 创建虚拟机2.2 新增硬盘2.3 系统启动项三、加电运行四、EFI方式五、总结前言 一、准备 基于之前的基础【Linux】Kickstart 配置U盘自动化安装Linux系统,现在我们可以在虚拟机中尝试自动化安装Linux系统。 二、新建虚拟机 …...
内网渗透(五十七)之域控安全和跨域攻击-基于服务账户的非约束委派攻击
系列文章第一章节之基础知识篇 内网渗透(一)之基础知识-内网渗透介绍和概述 内网渗透(二)之基础知识-工作组介绍 内网渗透(三)之基础知识-域环境的介绍和优点 内网渗透(四)之基础知识-搭建域环境 内网渗透(五)之基础知识-Active Directory活动目录介绍和使用 内网渗透(六)之基…...

gitlab 安装到项目上传一篇解决
文章目录1.安装1.1创建挂载目录1.2启动1.3 配置gitlab查看docker admin 账户初始密码注册普通用户2.1进入注册2.2创建后通过登录admin审批3.2 步骤13.2 步骤23.3步骤33.4 项目添加成员4 使用成员用户,上传到新建的项目中4.1 复制项目地址4.2使用 git here 克隆项目4.3进入下载目…...
Verilog 逻辑与()、按位与()、逻辑或(||)、按位或(|)、等于(==)、全等(===)的区别
逻辑与(&&)逻辑与是一个双目运算符,当符号两边为1时输出1,符号两边为0时输出0。真值表:&&01xz00000101xxx0xxxz0xxx两个4bit的数字相与;A4b0x1z;B4b01xx;C4b00xz&am…...
剑指 Offer 22. 链表中倒数第k个节点
剑指 Offer 22. 链表中倒数第k个节点 难度:easy\color{Green}{easy}easy 题目描述 输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。 例如,一个链…...

数据结构预算法之买卖股票的最好时机(三)动态规划
目录:一.题目知识点:动态规划二.动态规划数组思路确定1.dp数组以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历顺序5.举例推导dp数组一.题目知识点:动态规划动态规划算法的基本思想是:将待求解的问题分解成若干个相互联…...

【数通网络交换基础梳理2】三层设备、网关、ARP表、VLAN、路由表及跨网段路由下一跳转发原理
一、不同网段如何通讯 同网段可以依靠二层交换机通讯,网络中存在多个网段192.168.1.1/24 172.16.1.1/24 173.73.1.1/24情况下如何互相通讯?上节留一下的问题,这节继续讲解。 1、这里以Ping命令讲解,PC1 ping173.73.1.2…...

Java-排序链表问题
Java-排序链表问题题目题解方法:自顶向下归并排序算法题目 给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。 示例 1: 示例 2: 示例 3: 提示: *链表中节点的数目在范围 [0, 5 * 104]…...

c++之二叉树【进阶版】
前言 在c语言阶段的数据结构系列中已经学习过二叉树,但是这篇文章是二叉树的进阶版,因为首先就会讲到一种树形结构“二叉搜索树”,学习二叉搜索树的目标是为了更好的理解map和set的特性。二叉搜索树的特性就是左子树键值小于根,右…...

【数据库】 SQLServer
SQL Server 安装 配置 修改SQL Server默认的数据库文件保存路径_ 认识 master :是SQL Server中最重要的系统数据 库,存储SQL Server中的元数据。 Model:模板数据库,在创建新的数据库时,SQL Server 将会复制此数据…...
Linux 4.19 内核中 spinlock 概览
Linux内核中 spinlock相关数据结构和代码实现涉及的文件还是挺多的,这篇博客尝试从文件的角度来梳理一下 spinlock的相关数据结构和代码实现,适合想大概了解 Linux内核中 spinlock从上层 API到底层实现间的调用路径和传参变化,尤其适合了解 s…...
TensorFlow 1.x学习(系列二 :1):基本概念TensorFlow的基本介绍,图,会话,会话中的run(),placeholder(),常见的报错
目录1.基本介绍2.图的结构3.会话,会话的run方法4.placeholder5.返回值异常写在前边的话:之前发布过一个关于TensorFlow1.x的转载系列,自己将基本的TensorFlow操作敲了一遍,但是仍然有很多地方理解的不够深入。所以重开一个系列&am…...

Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...

使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...

Windows安装Miniconda
一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...
解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist
现象: android studio报错: [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决: 不要动CMakeLists.…...
Bean 作用域有哪些?如何答出技术深度?
导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答,…...
Leetcode33( 搜索旋转排序数组)
题目表述 整数数组 nums 按升序排列,数组中的值 互不相同 。 在传递给函数之前,nums 在预先未知的某个下标 k(0 < k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...