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

指针(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)有点难

指针&#xff08;4&#xff09; 来做个简单的回顾&#xff1a; 指针数组&#xff1a; 1.是数组 2.是存放指针的数组 char* arr1[5]; int*arr2[3]; 数组指针&#xff1a; 1 .是指针 2 .指向数组的指针 字符指针&#xff1a;char*pc; 整型指针&#xff1a;int*pi; int …...

初步了解json文件

来自wetab 的AI pro: JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;易于人阅读和编写&#xff0c;同时也易于机器解析和生成。JSON采用完全独立于语言的文本格式&#xff0c;但是它使用了类似于编程语言&#xff08;特别是J…...

赶紧收藏!2024 年最常见 100道 Java 基础面试题(四十)

上一篇地址&#xff1a;赶紧收藏&#xff01;2024 年最常见 100道 Java 基础面试题&#xff08;三十九&#xff09;-CSDN博客 七十九、forward和redirect的区别&#xff1f; 在Java Web应用程序中&#xff0c;forward和redirect是两种不同的服务器端重定向机制&#xff0c;它…...

初步了解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…...

前端工程化的基本介绍

文章目录 一、概念二、前端工程化的细节模块化组件化规范化 一、概念 工程化&#xff0c;可以理解为使用一些方式&#xff0c;去改良提高行业中现有的步骤、设计、应用方式。前端工程化&#xff0c;就是指对前端进行一些流程的标准化&#xff0c;让开发变得更有效率&#xff0…...

linux上Redis安装使用

环境centOS8 redis是缓存数据库&#xff0c;主要是用于在内存中存储数据&#xff0c;内存的读写很快&#xff0c;加快系统读写数据库的速度 一、Linux 安装 Redis 1. 下载Redis 官网下载Downloads - Redis 历史版本Index of /releases/ 本文中安装的版本为&#xff1a;h…...

prometheus+grafana的安装与部署及优点

一、Prometheus 的优点 1、非常少的外部依赖&#xff0c;安装使用超简单&#xff1b; 2、已经有非常多的系统集成 例如&#xff1a;docker HAProxy Nginx JMX等等&#xff1b; 3、服务自动化发现&#xff1b; 4、直接集成到代码&#xff1b; 5、设计思想是按照分布式、微服…...

JWK和JWT 学习

JWK和JWT 介绍 JWK (JSON Web Key) 和 JWT (JSON Web Token) 是现代Web应用程序中用于安全通信的两个重要概念。它们都是基于JSON的&#xff0c;并且是OAuth 2.0和OpenID Connect等协议的核心组成部分。 官方文档 JWT官方网站 JWK和JWK Set的RFC文档 JWT的RFC文档 JWK (JS…...

Go 使用mqtt

1、创建一个文件夹&#xff0c;并且使用go modules go mod init <module_name> 其中<module_name>是你的模块名称&#xff0c;如下 go mod init example.com/myproject 2、安装mqtt扩展 go get github.com/eclipse/paho.mqtt.golang 3、开始写主程序 package ma…...

C++ primer plus习题及解析第十二章(类和动态内存分配)

题目&#xff1a;12.1 题&#xff1a; 对于下面的类声明&#xff1a; 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 调试&#xff1a;只对可执行文件进行调用&#xff0c;无法直接用gdb调试.c文件 1.查找命令帮助&#xff1a; &#xff08;gdb&#xff09; help data &#xff08;gdb&#xff09; help call -l (list) 查看载入文件&#xff08;默认为10行&#xff09…...

使用Simulink Test进行单元测试

本文摘要&#xff1a;主要介绍如何利用Simulink Test工具箱&#xff0c;对模型进行单元测试。内容包括&#xff0c;如何创建Test Harness模型&#xff0c;如何自动生成excel格式的测试用例模板来创建测试用例&#xff0c;如何手动填写excel格式的测试用例模板来手动创建测试用例…...

深度学习中超参数设置

1、batchsize 在训练深度学习模型时&#xff0c;batch size&#xff08;批大小&#xff09;和 epochs&#xff08;迭代次数&#xff09;之间的关系取决于您的数据集大小、模型复杂度、计算资源等因素。下面是一些一般性的指导原则&#xff1a; 较大的 Batch Size&#xff1a;通…...

Docker nsenter 命令使用

查看容器对应宿主机上面的pid&#xff0c;容器技术的实质是进程&#xff0c;并没有完整的操作系统&#xff0c;就相当于在主机上面fork了一个子进程&#xff0c;通过docker daemon去fork一个子进程&#xff0c;这个子进程是可以在主机上面看到其pid的。 $ docker inspect -f {…...

十二种网络威胁防护方案

一、SQL注入 SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严&#xff0c;攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句&#xff0c;在管理员不知情的情况下实现非法操作&#xff0c;以此来实现欺骗数据库服务器执行非授权的任…...

C++ sort()排序详解

头文件 在C中使用sort()函数需要使用#include<algorithm> sort()基本使用方法 sort()函数可以对给定区间所有元素进行排序。它有三个参数sort(begin, end, cmp) 其中begin为指向待sort()的数组的第一个元素的指针&#xff0c;end为指向待sort()的数组的最后一个元素的…...

移动机器人系统与技术:自动驾驶、移动机器人、旋翼无人机

这本书全面介绍了机器人车辆的技术。它介绍了道路上自动驾驶汽车所需的概念。此外&#xff0c;读者可以在六足机器人的构造、编程和控制方面获得宝贵的知识。 这本书还介绍了几种不同类型旋翼无人机的控制器和空气动力学。它包括各种旋翼推进飞行器在不同空气动力学环境下的模…...

zTasker v1.88.1一键定时自动化任务

软件介绍 zTasker是一款完全免费支持定时、热键或条件触发的方式执行多种自动化任务的小工具&#xff0c;支持win7-11。其支持超过100种任务类型&#xff0c;50种定时/条件执行方法&#xff0c;而且任务列表可以随意编辑、排列、移动、更改类型&#xff0c;支持任务执行日志&a…...

时序医疗数据集---adfecgdb

数据集简介 该数据库包含了在波兰西里西亚医科大学妇产科&#xff0c;通过使用KOMPOREL系统收集的5位临产孕妇&#xff08;孕38至41周&#xff09;的多通道胎儿心电图&#xff08;FECG&#xff09;记录。这些记录通过腹部四个电极和安置在胎儿头部的直接心电图电极同步收集&am…...

ruoyi-vue-pro 使用记录(4)

ruoyi-vue-pro 使用记录&#xff08;4&#xff09; CRM数据库线索客户商机合同回款产品其他 CRM 文档 主要分为 6 个核心模块&#xff1a;线索、客户、商机、合同、回款、产品。 线索管理以 crm_clue 作为核心表客户管理以 crm_customer 作为核心表商机管理以 crm_business 作…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

C++ 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

HDFS分布式存储 zookeeper

hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架&#xff0c;允许使用简单的变成模型跨计算机对大型集群进行分布式处理&#xff08;1.海量的数据存储 2.海量数据的计算&#xff09;Hadoop核心组件 hdfs&#xff08;分布式文件存储系统&#xff09;&a…...