C指针与一维二维数组、数组指针与指针数组、函数指针_数组的理解使用
文章目录
- 一、指针数组 和 数组指针
- ① 数组指针
- ② 指针数组
- 二、函数指针与函数指针数组
- ① 函数指针
- ② 函数指针数组
- 三、指针与一维、二维数组
- ① 指针与一维数组
- ② 指针与二维数组
一、指针数组 和 数组指针
① 数组指针
数组指针(Array Pointer)是指向数组的指针变量,也可以理解为一维数组与指针的结合。其定义形式为:
type (*ptr)[size]; // 记法:数组指针本身是指针,所以需要括号将*与指针变量括起来
其中,
type
表示数组元素的数据类型,ptr
是指向数组的指针变量,size 是数组的长度。
例如:
arr[5] = { 1, 2, 3, 4, 5 };
int (*p)[5] = &arr; // 定义一个指向长度为 5 的 int 类型数组的指针
上述代码中,
p
是一个指向长度为5
的 int类型数组的指针,指向 arr 数组的首地址。
通过数组指针可以访问数组中的元素。
例如:
(*p)[0] = 10; // 修改 arr 数组的第一个元素为 10
需要注意的是,在使用数组指针访问数组元素时,需要使用 (*p)[i] 的形式。
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
② 指针数组
指针数组(pointer array) 是一个数组,其元素都是指针变量。其定义形式为:
type *ptr[size]; // 指针数组本身是数组,每个元素是指针变量,故不加括号([] 优先级高于 *)
其中,
type
表示指针变量所指向的数据类型,ptr
是指针数组,size
是数组的长度。
例如:
int a = 1, b = 2, c = 3;
int *ptr[3] = { &a, &b, &c }; // 定义一个包含三个 int 类型指针变量的数组
上述代码中,ptr 是一个包含三个 int 类型指针变量的数组,分别指向 a、b、c 三个变量。
通过指针数组可以访问指向的变量。例如:
*ptr[0] = 10; // 修改 a 变量的值为 10
需要注意的是,在使用指针数组访问指针变量所指向的数据时,需要使用
*ptr[i]
的形式。
综上所述,数组指针和指针数组是两个不同的概念,使用时需要根据实际情况选择合适的方式。
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
二、函数指针与函数指针数组
① 函数指针
函数指针(Function Pointer) 是指向函数的指针变量。它可以用来存储和调用函数的地址,实现对函数的动态调用。函数指针的类型必须与所指向的函数的类型一致,包括返回值类型和参数列表。
声明函数指针的格式如下:
return_type (*pointer_name)(params);
其中,return_type
是函数的返回值类型,pointer_name
是函数指针的名称,params
是函数的参数列表。
以下是一个简单的示例,展示了如何声明、赋值和调用函数指针:
#include <iostream>int add(int a, int b) {return a + b;
}int main() {int (*ptr)(int, int) = add; // 声明一个函数指针 ptr,并将其赋值为函数 add 的地址ptr(); // 调用函数指针 ptr,相当于调用函数addreturn 0;
}
在上述代码中,声明了一个函数指针 ptr,它指向无返回值且无参数的函数 add。然后将函数 add 的地址赋值给 ptr,最后通过 ptr() 调用了函数 add。
函数指针在许多情况下非常有用,例如在 回调函数、函数指针数组、函数指针作为函数参数 等场景中都能发挥重要作用。通过函数指针,可以实现函数的灵活调用与动态选择。
② 函数指针数组
函数指针数组(Array of Function Pointers)是一个包含函数指针元素的数组。每个数组元素都是一个函数指针,它们可以指向不同的函数。通过函数指针数组,可以实现对不同函数的动态调用和选择。
声明函数指针数组的格式如下:
return_type (*array_name[size])(params);
以下是一个简单的示例,展示了如何声明、赋值和调用函数指针数组:
#include <iostream>int mul(int a, int b) {return a * b;
}int div(int a, int b) {return a / b;
}int main() {int (*ptrArr[2])() = {mul, div}; // 声明一个包含 2 个函数指针元素的函数指针数组,并将其赋值为函数 mul 和函数 div 的地址for (int i = 0; i < 2; i++) {ptrArr[i](); // 调用函数指针数组中的函数指针}return 0;
}
在上述代码中,声明了一个函数指针数组
ptrArr
,它包含了两个函数指针元素。第一个元素指向函数mul
,第二个元素指向函数div
。通过遍历函数指针数组,逐个调用函数指针,实现了对函数的动态调用。
如果我们要使用switch语句来进行堆函数的调用,可以替换为函数指针数组。
函数指针数组在一些场景中非常有用,例如函数回调、状态机等。通过函数指针数组,可以根据需要灵活地选择和调用不同的函数,使程序具有更高的可扩展性和灵活性。
三、指针与一维、二维数组
① 指针与一维数组
指针与一维数组在 C/C++ 中有紧密的关联,并可以相互转换。
- 数组名作为指针
在 C/C++ 中,数组名可以被看作是指向数组首元素的指针。
例如:
int arr[5] = { 1, 2, 3, 4, 5 };
int *ptr = arr; // 数组名 arr 被隐式地转换为指向数组首元素的指针
上述代码中,
ptr
是一个指向整型变量的指针,它被赋值为数组arr
的首地址。此时,可以通过指针ptr
访问数组中的元素,例如ptr[0]
表示数组arr
的第一个元素。
需要注意的是,虽然数组名可以被看作指针,但它并不是一个普通的指针变量,无法进行赋值操作或修改其值。
- 指针数组和一维数组的转换
指针数组和一维数组可以相互转换。例如:
- 将指针数组转换为一维数组:
int a = 1, b = 2, c = 3;
int *ptr[3] = { &a, &b, &c }; // 定义一个指针数组
int arr[3] = { *ptr[0], *ptr[1], *ptr[2] }; // 将指针数组转换为一维数组
上述代码中,通过 解引用指针数组的元素,可以获取指针所指向的值,然后将这些值赋给一维数组。
- 将一维数组转换为指针数组:
int arr[3] = { 1, 2, 3 };
int *ptr[3];for (int i = 0; i < 3; i++) {ptr[i] = &arr[i];
}
上述代码中,通过循环遍历一维数组,可以将数组中每个元素的地址存储到指针数组中,从而实现一维数组到指针数组的转换。
总结:指针与一维数组之间存在紧密的关系,并可以相互转换。通过理解和灵活运用指针与一维数组的特性,可以更自由地操作和处理数组数据。
② 指针与二维数组
指针与二维数组在 C/C++ 中也有一定的关联,并可以相互转换。
- 指针与二维数组的关系
对于二维数组,可以使用指针来进行访问和操作。我们知道,二维数组实际上是由多个一维数组组成的,每个一维数组都是连续存储的。
int arr[][3] = { {1, 2, 3}, {4, 5, 6} };
int (*ptr)[3] = arr; // 使用指针指向二维数组的首地址
上述代码中,
ptr
是一个指向包含3个整数的一维数组的指针。它被赋值为二维数组 arr 的首地址。通过指针 ptr 可以访问二维数组中的元素,例如
ptr[i][j]
表示二维数组 arr 中第 i 行、第 j 列的元素值。
需要注意的是,在使用指针访问二维数组时,需要使用 (*ptr)[j]
的形式。
- 指针与二维数组的转换
指针与二维数组也可以相互转换。
例如:
- 将指针转换为二维数组:
可以通过将指针转换为二维数组来进行操作和访问。
int (*ptr)[3] = new int[2][3]; // 动态分配一个二维数组
int arr[2][3] = *ptr; // 将指针转换为二维数组
上述代码中,通过使用 new 运算符动态分配一个二维数组,并将其赋给指针 ptr。然后,通过解引用指针,将指针转换为二维数组。
- 将二维数组转换为指针:
可以通过将二维数组转换为指针来实现某些操作和传递给函数。
int arr[2][3] = { {1, 2, 3}, {4, 5, 6} };
int (*ptr)[3] = arr; // 将二维数组转换为指针
上述代码中,将二维数组 arr 赋给指针
ptr
,这样就将二维数组转换为指针。
总结:指针与二维数组之间有一定的关联,并可以相互转换。通过理解和灵活运用指针与二维数组的特性,可以更自由地操作和处理二维数组数据。
相关文章:
C指针与一维二维数组、数组指针与指针数组、函数指针_数组的理解使用
文章目录 一、指针数组 和 数组指针① 数组指针② 指针数组 二、函数指针与函数指针数组① 函数指针② 函数指针数组 三、指针与一维、二维数组① 指针与一维数组② 指针与二维数组 一、指针数组 和 数组指针 ① 数组指针 数组指针(Array Pointer)是指…...
安装运行vue-element-admin的报错问题-解决办法
文章目录 1.第一处2.第二处3.安装运行 在使用vue-element-admin时,使用命令安装: npm install -registryhttps://registry.npm.taobao.org会报错,不通过。需要修改两处。 1.第一处 在目录vue-element-admin-master\src\components\Markdown…...

高数笔记03:几何、物理应用
图源:文心一言 本文是我学习高等数学几何、物理应用的一些笔记和心得,希望可以与考研路上的小伙伴一起努力上岸~~🥝🥝 第1版:查资料、画导图~🧩🧩 参考资料:《高等数学 基础篇》武…...

js + selenium 获取chatgpt的accessToken
chatgpt的accessToken非常有用,在做web api对接时,因为登录超时 会刷新accessToken let elements document.querySelectorAll(.token-string);let concatenatedText [8,9,10].map(index > {return elements[index] ? elements[index].textContent …...
Spring MVC 十一:中文乱码
SpringMVC的中文乱码问题其实已经不是什么问题了,无非就是配置编码方式->解决问题。 但是由于SpringMVC可以通过:xml方式配置、Servlet3.0方式配置,以及是否使用EnableWebMvc等,不同配置方式下,解决中文乱码问题的…...

Excel恢复科学技术法显示的数据
Excel中输入位数较大的数据时,软件会自动使用科学计数法显示。很多时候并不需要这样的计数格式,所以需要把它转变为普通的数字格式 操作方法 选中单元格/列/行》右键》设置单元格式 在打开的窗口中,切换到“数字”选项卡,点击“自…...

springboot 志同道合交友网站演示
springboot 志同道合交友网站演示 liu1113625581...

如何理解BFC、开启BFC、BFC解决哪些问题
1.BFC 概念 BFC 英文名为 Block Formatting Context (块级格式化上下文) 具体可查看 MDN 2.BFC的作用 元素开启BFC后,子元素不会发生margin塌陷问题元素开启BFC后,子元素浮动,元素不发生高度塌陷元素开启BFC后,该元素不被其他元…...

3D包容盒子
原理简述 包围体(包容盒)是一个简单的几何空间,里面包含着复杂形状的物体。为物体添加包围体的目的是快速的进行碰撞检测或者进行精确的碰撞检测之前进行过滤(即当包围体碰撞,才进行精确碰撞检测和处理)。包…...

用 Three.js 创建一个酷炫且真实的地球
接下来我会分步骤讲解,在线示例在数字孪生平台。 先添加一个球体 我们用threejs中的SphereGeometry来创建球体,给他贴一张地球纹理。 let earthGeo new THREE.SphereGeometry(10, 64, 64) let earthMat new THREE.MeshStandardMaterial({map: albed…...

【数据结构】线性表与顺序表
⭐ 作者:小胡_不糊涂 🌱 作者主页:小胡_不糊涂的个人主页 📀 收录专栏:浅谈Java 💖 持续更文,关注博主少走弯路,谢谢大家支持 💖 线性表与顺序表 1. 线性表2. 顺序表2.1 …...

ChatGPT
chatgpt使用地址 https://mycaht.top/#/chat 申请内测免费key https://github.com/chatanywhere/GPT_API_free 设置 接口地址设置改成 https://api.chatanywhere.com.cnAPI Key设置成申请出来的免费key 开始聊天...

矿区井下智慧用电安全监测解决方案
一、背景 矿区井下作业具有复杂的环境和较高的危险性,对于用电安全的要求尤为严格。传统的管理模式和监测方法往往无法实时、准确地掌握井下用电情况,对安全隐患的排查与预防存在一定局限性。因此,引入智慧用电安全监测解决方案ÿ…...

网站列表页加密:三次请求后返回内容多\r
一、抓包第一次请求 url aHR0cDovL2N5eHcuY24vQ29sdW1uLmFzcHg/Y29saWQ9MTA抓包,需要清理浏览器cookie,或者无痕模式打开网址,否则返回的包不全,依照下图中的第一个包进行requests请求 第一次请求后返回 <!DOCTYPE html>…...

12.JVM
一.JVM类加载机制:把类从硬盘文件加载到内存中 1.java文件,编写时是一个.java文件,编译后现成一个.class的字节码文件,运行的时候,JVM就会读取.class文件,放到内存中,并且构造类对象. 2.类加载流程: a.加载:找到.class文件,打开文件,读取内容,尝试解析文件内容. b.验证:检查…...

关于网络协议的若干问题(四)
1、QUIC 是一个精巧的协议,它有哪些特性? 答:QUIC 还有其他特性,一个是快速建立连接。另一个是拥塞控制,QUIC 协议当前默认使用了 TCP 协议的 CUBIC(拥塞控制算法)。 CUBIC 进行了不同的设计&…...

opencv图像卷积操作和常用的图像滤波函数
文章目录 opencv图像卷积操作原理,opencv中常用的图像滤波函数一、图像卷积操作原理:1、卷积操作原理图: 二、opencv常用的图像滤波函数:这些函数的主要作用是对图像进行平滑处理或去除噪声(核心目的是减少图像中的噪声࿰…...

习题1. 31
话不多说 先上代码 (defn product [ term a nxt b](defn iter [a result](if (> a b)1 (* (term a) (iter (nxt a) result))))(iter a 1)) 跟习题1.30比较起来,就是两个地方不同 乘法不能乘0 必须是1。难度来讲,跟1.30难度是一样的。增加了迭代过…...

见微知著:从企业售后技术支持看云计算发展
作者:余凯 售后业务中的细微变化 作为阿里云企业容器技术支持的一员,每天会面对全球各地企业级客户提出的关于容器的各种问题,通过这几年的技术支持的经历,逐步发现容器问题客户的一些惯性,哪些是重度用户࿰…...

C++笔记之如何给 `const char*` 类型变量赋值
C笔记之如何给 const char* 类型变量赋值 code review! 文章目录 C笔记之如何给 const char* 类型变量赋值1.在C中,如果你要给一个 const char* 变量赋值,你通常有几种方法来做这件事,具体取决于你的需求。下面是一些常见的方法:…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...

Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...

有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...