指针(4)有点难
指针(4)
来做个简单的回顾:
指针数组:
1.是数组
2.是存放指针的数组
char* arr1[5];
int*arr2[3];
数组指针:
1 .是指针
2 .指向数组的指针
字符指针:char*pc;
整型指针:int*pi;
int (*p) [10];//P就是数组指针,p指向的数组有10个元素,每个元素的类型是int
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{int arr[10] = { 0 };int(*p)[10] = &arr;//取的是整个数组的地址return 0;
}
例子:
想使用p这个数组访问arr数组的内容
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int(*p)[10] = &arr;//取的是整个数组的地址int i = 0;
for (i = 0; i <= 10; i++)
{printf("%d", p[i]);//*(p+i)
}
1 .二维数组传参的本质
代码如下:
void Print(int arr[3][5], int r, int c)//int (*arr)[5]
{int i = 0;for (i = 0; i <=r; i++){for (int j = 0; j <=c; j++){printf("%d", arr[i][j]);//*(*(arr+i)+j)//*(arr+i)==arr[i]//arr[i]是第i行的数组名,数组名又是数组首元素的地址,arr[i]=&arr[i][0]}printf("\n");}
}int main()
{int arr[3][5] = { (1,2,3,4,5),(2,3,4,5,6),(3,4,5,6,7) };Print(arr, 3, 5);return 0;
}
前情回顾:
一维数组传参
数组名是首元素的地址,一维数组传参的时候,其实传递的是首元素的地址。
函数的参数可以写成数组,也可以写成指针。
那二维数组呢?
其实二维数组的数组名也是数组首元素的地址,二维数组的数组名就是它第一行的地址,第一行是一个一维数组,传过去的是第一行这个一维数组的地址
[外链图片转存中…(img-Lf2wiLHP-1715345940161)]
[外链图片转存中…(img-HzRavJos-1715345940162)]
总结:
arr[i]==*(arr+i)
arr[i] [j]=* (*(arr+i)+j)
不管是一维数组还是二维数组,形参可以写成数组,也可以写成指针,这里要对数组名做深入理解
2 .函数指针变量
void Add(int x, int y)
{return x + y;
}int main()
{int a = 2;int b = 6;Add(a, b);printf("%p\n", &Add);return 0;
}
运行结果:
[外链图片转存中…(img-lowcQ39K-1715345940163)]
小小的不同:
&函数名和函数名的地址没有不同
[外链图片转存中…(img-815uKMMu-1715345940163)]
[外链图片转存中…(img-1Si0XL6D-1715345940163)]
函数指针变量的注意点:
我们之前学习调用函数的时候
形式如下:
int ret2 = Add(4, 5);
其实函数指针变量也可以写成另外一种形式,也是可以的:
int ret3 = pf(4, 5);
但是写上*的时候,不要忘记加(),因为这时候pf会和(4,5)相结合,调用的·是函数值的地址,这就有问题了
函数指针类型解析:
int (*pf3) (int x, int y)
| | ------------
| | |
| | pf3指向函数的参数类型和个数的交代
| 函数指针变量名
pf3指向函数的返回类型
int (*) (int x, int y) //pf3函数指针变量的类型
3 .两段有趣的代码
代码1:
(*(void (*)())0)();
[外链图片转存中…(img-pL9wxN6Q-1715345940163)]
代码2:
void (*signal(int , void(*)(int)))(int);
[外链图片转存中…(img-FNyDCtyc-1715345940164)]
[外链图片转存中…(img-3hjNYgd0-1715345940164)]
可以这样理解,但是语法不允许这样写
4 .typedef关键字
typedef unsigned int unit;
int main()
{unsigned int num;unit num;return 0;
}
对数组指针重命名:
typedef int(*parr_t)[10]//一定要把指针放里面
int main()
{int arr[6] = { 0 };int(*p) = &arr;parr_t p2 = &arr;return 0;
}
对函数指针重命名:
int Add(int x, int y)
{return x + y;
}
typedef int(*pf_t)(int, int);int main()
{int(*pf)(int, int) = Add;pf_t pf2 = Add;return 0;
}
那么我们在有趣的代码这一节中那个函数的声明也可以写成:
typedef void(*pf_t)(int)int main()
{pf_t signal(int,pf_t);return 0;
}
5 .函数指针数组
int Add(int x, int y)
{return x + y;
}
int Sub(int x, int y)
{return x - y;
}
int Plus(int x, int y)
{return x * y;
}
int Div(int x, int y)
{return x / y;
}
int main()
{int(*pf[4])(int,int) = {Add,Sub,Plus,Div};//函数指针数组//0, 1 ,2 ,3int i=0;for(i=0;i<4;i++){int ret=pf[i](6,2);printf("%d\n",ret);
}return 0;
}
6 .转移表
函数指针数组的⽤途:转移表
例子:计算器
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
void menu(){printf("**************************\n");printf("*******1 .Add 2 .Sub******\n");printf("*******3 .Plus4 .Div******\n");printf("*******0 .exit************\n");printf("**************************\n");}int Add(int x, int y)
{return x + y;
}
int Sub(int x, int y)
{return x - y;
}
int Plus(int x, int y)
{return x * y;
}
int Div(int x, int y)
{return x / y;
}
int main()
{int input = 0;int x = 0;int y = 0;int ret = 0;do{menu();printf("请选择:");scanf("%d", &input);int(*prArr[5])(int,int) = {0,Add,Sub,Plus,Div};//函数指针数组if (input >= 1 && input <= 4){printf("请输入两个操作数:");scanf("%d %d", &x, &y);ret = prArr[input](x, y);printf("%d\n", ret);}if (input == 0){printf("您已退出计算器\n");}else{printf("请重新做选择\n");}} while (input);return 0;
}
7 .回调函数是什么?
回调函数就是⼀个通过函数指针调⽤的函数。
如果你把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被⽤来调⽤其所指向的函数 时,被调⽤的函数就是回调函数。回调函数不是由该函数的实现⽅直接调⽤,⽽是在特定的事件或条 件发⽣时由另外的⼀⽅调⽤的,⽤于对该事件或条件进⾏响应。
[外链图片转存中…(img-wA8XZowf-1715345940164)]
ret);
}
if (input == 0)
{
printf(“您已退出计算器\n”);
}
else
{
printf(“请重新做选择\n”);
}
} while (input);
return 0;
}
## 7 .回调函数是什么?回调函数就是⼀个通过函数指针调⽤的函数。如果你把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被⽤来调⽤其所指向的函数 时,被调⽤的函数就是回调函数。回调函数不是由该函数的实现⽅直接调⽤,⽽是在特定的事件或条 件发⽣时由另外的⼀⽅调⽤的,⽤于对该事件或条件进⾏响应。[外链图片转存中...(img-wA8XZowf-1715345940164)]Calc起到了封装的作用
相关文章:
指针(4)有点难
指针(4) 来做个简单的回顾: 指针数组: 1.是数组 2.是存放指针的数组 char* arr1[5]; int*arr2[3]; 数组指针: 1 .是指针 2 .指向数组的指针 字符指针:char*pc; 整型指针:int*pi; int …...
初步了解json文件
来自wetab 的AI pro: JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。JSON采用完全独立于语言的文本格式,但是它使用了类似于编程语言(特别是J…...
赶紧收藏!2024 年最常见 100道 Java 基础面试题(四十)
上一篇地址:赶紧收藏!2024 年最常见 100道 Java 基础面试题(三十九)-CSDN博客 七十九、forward和redirect的区别? 在Java Web应用程序中,forward和redirect是两种不同的服务器端重定向机制,它…...
初步了解Kubernetes
目录 1. K8S概述 1.1 K8S是什么 1.2 作用 1.3 由来 1.4 含义 1.5 相关网站 2. 为什么要用K8S 3. K8S解决的问题 4. K8S的特性 5. Kubernetes集群架构与组件 6. 核心组件 6.1 Master组件 6.1.1 Kube-apiserver 6.1.2 Kube-controller-manager 6.1.3 kube-schedul…...
前端工程化的基本介绍
文章目录 一、概念二、前端工程化的细节模块化组件化规范化 一、概念 工程化,可以理解为使用一些方式,去改良提高行业中现有的步骤、设计、应用方式。前端工程化,就是指对前端进行一些流程的标准化,让开发变得更有效率࿰…...
linux上Redis安装使用
环境centOS8 redis是缓存数据库,主要是用于在内存中存储数据,内存的读写很快,加快系统读写数据库的速度 一、Linux 安装 Redis 1. 下载Redis 官网下载Downloads - Redis 历史版本Index of /releases/ 本文中安装的版本为:h…...
prometheus+grafana的安装与部署及优点
一、Prometheus 的优点 1、非常少的外部依赖,安装使用超简单; 2、已经有非常多的系统集成 例如:docker HAProxy Nginx JMX等等; 3、服务自动化发现; 4、直接集成到代码; 5、设计思想是按照分布式、微服…...
JWK和JWT 学习
JWK和JWT 介绍 JWK (JSON Web Key) 和 JWT (JSON Web Token) 是现代Web应用程序中用于安全通信的两个重要概念。它们都是基于JSON的,并且是OAuth 2.0和OpenID Connect等协议的核心组成部分。 官方文档 JWT官方网站 JWK和JWK Set的RFC文档 JWT的RFC文档 JWK (JS…...
Go 使用mqtt
1、创建一个文件夹,并且使用go modules go mod init <module_name> 其中<module_name>是你的模块名称,如下 go mod init example.com/myproject 2、安装mqtt扩展 go get github.com/eclipse/paho.mqtt.golang 3、开始写主程序 package ma…...
C++ primer plus习题及解析第十二章(类和动态内存分配)
题目:12.1 题: 对于下面的类声明: class Cow { private:char name[20];char* hobby;double weight; public:Cow();Cow(const char* nm, const char* ho, double wt);//有参构造Cow(const Cow& c);//拷贝构造函数~Cow();//析构函数Cow&…...
gdb调试功能描述
gdb调试功能描述 gdb 调试:只对可执行文件进行调用,无法直接用gdb调试.c文件 1.查找命令帮助: (gdb) help data (gdb) help call -l (list) 查看载入文件(默认为10行)…...
使用Simulink Test进行单元测试
本文摘要:主要介绍如何利用Simulink Test工具箱,对模型进行单元测试。内容包括,如何创建Test Harness模型,如何自动生成excel格式的测试用例模板来创建测试用例,如何手动填写excel格式的测试用例模板来手动创建测试用例…...
深度学习中超参数设置
1、batchsize 在训练深度学习模型时,batch size(批大小)和 epochs(迭代次数)之间的关系取决于您的数据集大小、模型复杂度、计算资源等因素。下面是一些一般性的指导原则: 较大的 Batch Size:通…...
Docker nsenter 命令使用
查看容器对应宿主机上面的pid,容器技术的实质是进程,并没有完整的操作系统,就相当于在主机上面fork了一个子进程,通过docker daemon去fork一个子进程,这个子进程是可以在主机上面看到其pid的。 $ docker inspect -f {…...
十二种网络威胁防护方案
一、SQL注入 SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任…...
C++ sort()排序详解
头文件 在C中使用sort()函数需要使用#include<algorithm> sort()基本使用方法 sort()函数可以对给定区间所有元素进行排序。它有三个参数sort(begin, end, cmp) 其中begin为指向待sort()的数组的第一个元素的指针,end为指向待sort()的数组的最后一个元素的…...
移动机器人系统与技术:自动驾驶、移动机器人、旋翼无人机
这本书全面介绍了机器人车辆的技术。它介绍了道路上自动驾驶汽车所需的概念。此外,读者可以在六足机器人的构造、编程和控制方面获得宝贵的知识。 这本书还介绍了几种不同类型旋翼无人机的控制器和空气动力学。它包括各种旋翼推进飞行器在不同空气动力学环境下的模…...
zTasker v1.88.1一键定时自动化任务
软件介绍 zTasker是一款完全免费支持定时、热键或条件触发的方式执行多种自动化任务的小工具,支持win7-11。其支持超过100种任务类型,50种定时/条件执行方法,而且任务列表可以随意编辑、排列、移动、更改类型,支持任务执行日志&a…...
时序医疗数据集---adfecgdb
数据集简介 该数据库包含了在波兰西里西亚医科大学妇产科,通过使用KOMPOREL系统收集的5位临产孕妇(孕38至41周)的多通道胎儿心电图(FECG)记录。这些记录通过腹部四个电极和安置在胎儿头部的直接心电图电极同步收集&am…...
ruoyi-vue-pro 使用记录(4)
ruoyi-vue-pro 使用记录(4) CRM数据库线索客户商机合同回款产品其他 CRM 文档 主要分为 6 个核心模块:线索、客户、商机、合同、回款、产品。 线索管理以 crm_clue 作为核心表客户管理以 crm_customer 作为核心表商机管理以 crm_business 作…...
51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)
一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…...
【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error
在前端开发中,JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作(如 Promise、async/await 等),开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝(r…...
Modbus RTU与Modbus TCP详解指南
目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...
【iOS】 Block再学习
iOS Block再学习 文章目录 iOS Block再学习前言Block的三种类型__ NSGlobalBlock____ NSMallocBlock____ NSStackBlock__小结 Block底层分析Block的结构捕获自由变量捕获全局(静态)变量捕获静态变量__block修饰符forwarding指针 Block的copy时机block作为函数返回值将block赋给…...
