C语言之指针详解(6)

news2024/11/25 18:24:53
目录
本章重点
1. 字符指针
2. 数组指针
3. 指针数组
4. 数组传参和指针传参
5. 函数指针
6. 函数指针数组
7. 指向函数指针数组的指针
8. 回调函数
9. 指针和数组面试题的解析
指向函数指针数组的指针
指向函数指针数组的指针是一个指针指针指向一个数组 ,数组的元素都是函数指针
我们看代码
根据定义
//int(*(*ppArr)[5])(int, int);

看这个代码,*先和ppArr结合说明ppArr是一个指针,然后再和【5】结合说明这是一个数组指针,我们把(*paArr)【5】去掉来看效果

 

//int(*)(int, int);
这个代码的意思是*先和()结合说明他是一个指针,再和(int,int)结合说明他是一个函数指针,并且这个函数的返回类型为Int型
接下来我们来看回调函数
那什么是回调函数呢?
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当 这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调 用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应
那我们来看下面代码
#include<stdio.h>
void bubble_sort(int arr[], int sz)
{
	int i = 0;
	//趟数
	for (i = 0; i < sz - 1; i++)
	{
		//一趟冒泡排序
		int j = 0;
		for (j = 0; j < sz - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}
struct Stu
{
	char name[20];
	int age;
};
int main()
{
	int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	struct Stu s[3] = { {"zhangsan",20},{"lisi",30},{"wangwu",10} };
	bubble_sort(arr, sz);//这个冒泡排序类型只能排序整型,不能排序其他类型
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}
那我们如何优化这种代码呢???这里我们需要了解一下qsort库函数
qsort----quick sort快速排序
qsort库函数有4个参数,这里重点说一下最后一个参数,这里的*先和compar结合,说明他是一个桌指针,然后再和(const void*,const void*e2)结合说明

这是一个函数,这就是一个函数指,且函数的返回类型为int型给大家解释一下这四个参数分别代表的意思

base:目标数组的起始位置

num:数组的大小(单位为元素),也就是数组有几个元素

size:元素的大小(单位为字节),也就是一个元素的大小(单位为字节)

compar:比较

现在我们来看代码

#include<stdio.h>
#include<stdlib.h>
void qsort(void* base, size_t num, size_t size, int (*compar)(const void* e1, const void* e2));
int cmp_int(const void* e1, const void* e2)
{

}
int main()
{
	int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	//struct Stu s[3] = { {"zhangsan",20},{"lisi",30},{"wangwu",10} };//结构体数组
	//bubble_sort(arr, sz);//这个冒泡排序类型只能排序整型,不能排序其他类型
	qsort(arr, sz, sizeof(arr[0]), cmp_int);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

我们把cmp_int函数放到qsort这个函数中,,函数名和参数值以及返回类型和qsort的第四个参数的函数参数以及函数的返回值是一致的,所以我们就可以通过(*compar)找到cmp_int这个函数名(也可以叫做是函数的地址)大家这里可能有个疑问,我们见过int*,char*,double*,float*等等,但是没有见过void*,我这里给大家解释一下,我们来看代码

#include<stdio.h>
int main()
{
	int a = 10;
	int* pa = &a;
	char* pc = &a;
	void* p = &a;
	p = &pc;
	//void*类型的指针,可以接收任意类型的地址
}

void*类型的指针,可以接收任意类型的地址

当我们要排序其他的类型(int*,char*等等),这是void就可以接收这些类型,就不用我们多次去改变变量类型

我们来看一下void*类型需要注意的事项,我们看代码

#include<stdio.h>
int main()
{
	int a = 10;
	int* pa = &a;
	char* pc = &a;
	void* p = &a;
	*p = 0;
	p++;
	//void*类型的指针,可以接收任意类型的地址
	//void*类型的指针,不能进行解引用操作
	//void*类型的指针,不能进行+-整数的操作
}

我们接着来看刚才我们写到的qsort函数,这里的void*指针变量的值不能被改变(不能解引用),我们需要强制类型转换,强制类型转换为int*类型的指针就可以进行*解引用了

打印出来是从小到大的升序数组

#include<stdio.h>
#include<stdlib.h>
//void qsort(void* base, size_t num, size_t size, int (*compar)(const void* e1, const void* e2));
int cmp_int(const void* e1, const void* e2)
{
	return *(int*)e1 - *(int*)e2;
}
int main()
{
	int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	//struct Stu s[3] = { {"zhangsan",20},{"lisi",30},{"wangwu",10} };//结构体数组
	//bubble_sort(arr, sz);//这个冒泡排序类型只能排序整型,不能排序其他类型
	qsort(arr, sz, sizeof(arr[0]), cmp_int);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

结构体数组的快速排序和float类型的快速排序我将在下一个博客的开头给大家做详细的讲解!

本章终,这一章节难度大,大家多消化理解一下

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/651773.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Shiro】第三章 Shiro入门

目录 1、身份认证 2、Realm 3、编码、散列算法 4、Realm使用散列算法 1、身份认证 【1】基本流程 流程如下: 1、Shiro把用户的数据封装成标识token,token一般封装着用户名&

《C++程序设计原理与实践》笔记 第19章 向量、模板和异常

本章将完成最常见、最有用的STL容器vector的设计与实现。我们将展示如何实现元素数量可变的容器&#xff0c;如何以参数形式指定容器的元素类型&#xff0c;以及如何处理越界错误。本章使用的技术依赖模板和异常&#xff0c;因此我们将介绍如何定义模板&#xff0c;并给出资源管…

糖化学试剂:4594-52-9,1,3,5-三乙酰基-2-脱氧-D-赤式戊呋喃糖,试剂用途说明

基础产品数据&#xff08;Basic Product Data&#xff09;&#xff1a; CAS号&#xff1a;4594-52-9 中文名&#xff1a;1,3,5-三乙酰基-2-脱氧-D-赤式戊呋喃糖 英文名&#xff1a;1,3,5-Tri-O-acetyl-2-deoxy-D-erythro-pentofuranose 沸点 &#xff1a;329.342.0 C at 760 m…

vue2、vue3分别配置echarts多图表的同步缩放

文章目录 ⭐前言⭐使用dataZoom api实现echart的同步缩放&#x1f496; vue2实现echarts多图表同步缩放&#x1f496; vue3实现echarts多图表同步缩放 ⭐结束 ⭐前言 大家好&#xff01;我是yma16&#xff0c;本文分享在vue2和vue3中配置echarts的多图表同步缩放 背景&#xf…

进程描述+PCB+fork用法介绍

进程控制块PCB 进程id&#xff1a;系统中每个进程有唯一的id,在c语言中用pid_t 表示&#xff0c;其实就是非负整数进程的状态&#xff1a;就绪&#xff0c;运行&#xff0c;挂起&#xff0c;停止&#xff0c;僵尸等状态进程切换是需要保存和恢复的一些cpu寄存器描述虚拟地址空…

微调Hugging Face中图像分类模型

前言 本文主要针对Hugging Face平台中的图像分类模型&#xff0c;在自己数据集上进行微调&#xff0c;预训练模型为Google的vit-base-patch16-224模型&#xff0c;模型简介页面。代码运行于kaggle平台上&#xff0c;使用平台免费GPU&#xff0c;型号P100&#xff0c;笔记本地址…

【惯性导航】隧道、高架桥、高楼林立弱信号环境室外定位_惯导模块

汽车行驶在路上&#xff0c;视野可能会受到周边的树木、同行的卡车、城市楼群的遮挡&#xff0c;卫星导航系统容易受到周围环境的影响&#xff0c;例如树木楼房等&#xff0c;造成多路径效应&#xff0c;使得定位结果精度降低甚至丢失&#xff0c;尤其是在隧道或者室内环境中&a…

树莓派开Samba协议和Windows电脑共享资料

文章目录 1. 前言2. 树莓派安装和配置Samba2.1. 更新源2.2. 安装Samba软件2.3. 修改Samba配置文件2.4. 重启Samba服务2.5. 添加用户到Samba 3. Windows访问共享目录3.1. 查看树莓派的地址3.2. 打开这个IP地址 4. 报错4.1. 用户名或者密码不正确 1. 前言 虽然出门派很方便&…

C++算法————二分查找

又是鸽了三千万年 马上要打csp了&#xff0c;开始回流学j组的知识了&#xff0c;浅说一下二分吧&#xff08;&#xff09; --------------------------------------------------------------------------------------------------------------------------------- 二分查找 …

tsx写法

1.安装插件 npm install vitejs/plugin-vue-jsx -D vite.config.ts 配置 import { defineConfig } from vite import vue from vitejs/plugin-vue import vueJsx from vitejs/plugin-vue-jsx; // https://vitejs.dev/config/ export default defineConfig({plugins: [vue(),v…

TC15WProteus仿真DS18B20温度采集报警控制系统STC15W4K32S4

STC15WProteus仿真DS18B20温度采集报警控制系统STC15W4K32S4 Proteus仿真小实验&#xff1a; STC15WProteus仿真DS18B20温度采集报警控制系统STC15W4K32S4 功能&#xff1a; 硬件组成&#xff1a;STC15W4K32S4单片机 LCD1602显示器DS18B20温度传感器蜂鸣器 1.单片机读取DS18…

数据链路层(MAC)、网络层(IP)、传输层(TCP/UDP)抓包分析

目录 OSI七层模型数据包逐层封装头部抓包分析数据包概况数据链路层抓包网络层抓包&#xff08;IP协议抓包&#xff09;UDP抓包数据负载抓包 Linux cooked-mode capture OSI七层模型 OSI模型&#xff08;OSI model&#xff09;&#xff0c;开放式系统互联通信参考模型&#xff…

【读书笔记】《小王子》- [法] 安托万•德•圣埃克苏佩里 / [法国] 安东尼·德·圣-埃克苏佩里

文章目录 Chapter 01Chapter 02Chapter 03Chapter 04Chapter 05Chapter 06Chapter 07Chapter 08Chapter 09 Chapter 01 Chapter 02 “因为我住的地方非常小…” 想起了陀思妥耶夫斯基书中的一句话&#xff0c;“要爱具体的人&#xff0c;不要爱抽象的人&#xff1b;要爱生活本…

给开发者的ChatGPT提示词工程指南

ChatGPT Prompt Engineering for Development 基本大语言模型和指令精调大语言模型的区别&#xff1a; 指令精调大语言模型经过遵从指令的训练&#xff0c;即通过RLHF&#xff08;基于人类反馈的强化学习&#xff09;方式在指令上精调过&#xff0c;因而更加有帮助&#xff0…

OverLeaf(LaTeX在线编辑器)制作项目周报

目录 注册及登录 1、登录官网 2、设置语言 制作周报 1、新建项目 2、整体预览 3、分段解析 3.1 页面大小/页边距 3.2 页眉页脚 3.3 标题样式 3.4 内容分栏显示 3.5 调整行间距 3.6 插入图片 3.7 图片和文字排版 3.8 分页 3.9 标题和内容 4、编译和导出 4.1 编…

hutool poi、apache poi实现导入导出以及解析excel

一、前言 看了例子之后后续需要更加深入学习或者更多理解其他API的话&#xff0c;建议看官方文档。hutool项目是中国人维护的&#xff0c;有中文文档&#xff0c;阅读起来很方便。apache poi比较底层一点&#xff0c;可以更加自由去二次开发自己所需的功能。 hutool官方文档 …

zkML零知识机器学习介绍

1. 引言 零知识证明技术的2大基石为&#xff1a; 1&#xff09;succinctness&#xff1a;相比于直接运行整个计算本身&#xff0c;验证该计算完整性证明要简单很多。2&#xff09;zero-knowledge&#xff1a;可在不泄露计算隐私的情况下&#xff0c;证明计算的完整性。 生成…

【Java入门】-- Java基础详解之 [数组、冒泡排序]

目录 1.为什么需要数组&#xff1f; 2.数组的介绍 3.数组的快速入门 4.数组的使用 5.动态初始化 6.静态初始化 7.数组的细节 8.数组的赋值机制 9.数组拷贝 10.数组反转 11.二维数组 12.冒泡排序 1.为什么需要数组&#xff1f; 有五个学生&#xff0c;他们英语成绩…

探索不同学习率对训练精度和Loss的影响

验证精度、验证Loss的影响 1 问题 在探索mnist数据集过程中&#xff0c;学习率的不同&#xff0c;对我们的实验结果&#xff0c;各种参数数值的改变有何变化&#xff0c;有何不同。 学习率对精度和损失的影响研究。训练周期100学习率 [0.1, 0.01, 0.001, 0.0001](1) 不同学习率…

蓝牙网关Gateway_数据采集,连接控制,室内定位VDB2602

蓝牙网关&#xff0c;内部集成了WiFi、蓝牙、4G等多种无线通信方式&#xff0c;因此也继承了蓝牙、WiFi的有扫描功能、连接功能、数据透传功能&#xff0c;被应用于智能家居的各种场景中&#xff0c;例如&#xff1a;远程控制BLE装置&#xff0c;接收BLE设备发送的数据&#xf…