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

【数据结构C/C++】多维数组的原理、访问方式以及作用

文章目录

  • 什么是多维数组?
  • 代码讲解使用方式
  • 为什么指针遍历的方式是这样子的?(助你理解指针的含义)
  • 使用场景
  • 408考研各数据结构C/C++代码(Continually updating)

什么是多维数组?

在C语言中,多维数组的存储实际上是在内存中按照一维数组的方式连续存储数据的。多维数组的底层原理可以理解为是一维数组的扩展。每个维度的大小(元素个数)决定了存储空间的布局。

考虑一个二维数组的例子,例如int arr[3][4],表示一个3行4列的整数数组。底层存储原理如下:

首先,内存中会分配一个连续的存储空间,大小为3 * 4 * sizeof(int)字节,其中sizeof(int)表示一个整数占用的字节数。

数组的元素在内存中按照行优先(C语言的约定)方式存储,也就是说,首先存储第一行的所有元素,然后是第二行的所有元素,以此类推。

如果我们想访问数组的某个元素,例如arr[1][2],系统会通过内存偏移计算来找到对应的位置。在这个例子中,偏移计算如下:

偏移 = 行号 * 每行的元素个数 + 列号
偏移 = 1 * 4 + 2 = 6

这意味着arr[1][2]的数据存储在偏移地址6的位置上。

多维数组的每个维度的大小(行数和列数等)会影响内存布局和偏移计算。例如,如果有一个三维数组int arr[2][3][4],那么在内存中会按照一维数组的形式存储,同时需要考虑三个维度的大小来计算偏移。

这种按照行优先方式存储多维数组的原理使得访问连续内存位置的元素更加高效,因为它充分利用了现代计算机的缓存机制,可以减少内存访问的开销。同时,它也意味着多维数组的元素在内存中是连续存储的,这对于访问大量数据的性能非常重要。

代码讲解使用方式

#include <stdio.h>int main() {// 定义一个二维数组,表示3行4列的矩阵int matrix[3][4] = {{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12}};// 使用指针遍历多维数组int *ptr = &matrix[0][0]; // 定义一个指向第一个元素的指针printf("遍历多维数组的元素:\n");for (int i = 0; i < 3; i++) {for (int j = 0; j < 4; j++) {// 使用指针访问当前元素int element = *(ptr + i * 4 + j); // 计算偏移并解引用指针printf("%d ", element);  //指针遍历方法printf("%d ", matrix[i][j]); // 数组下标遍历方法}printf("\n");}return 0;
}

原理解释:

  1. 我们首先定义了一个二维数组 int matrix[3][4],表示一个3行4列的矩阵。

  2. 然后,我们定义一个指针 int *ptr 并将其初始化为指向数组的第一个元素,也就是 matrix[0][0]。在C语言中,多维数组在内存中是按照一维数组的方式连续存储的,因此我们可以使用指针来遍历多维数组。

  3. 接下来,我们使用两个嵌套的循环来遍历多维数组的元素。外层循环控制行,内层循环控制列。

  4. 在循环中,我们使用指针 ptr 来访问当前元素。为了计算当前元素的偏移,我们使用了 i * 4 + j 的方式,其中 i 表示当前行数,j 表示当前列数。这是因为在二维数组中,每行有4个元素。

  5. 我们通过 *(ptr + i * 4 + j) 来解引用指针,从而获取当前元素的值,并使用 printf 函数打印出来。

为什么指针遍历的方式是这样子的?(助你理解指针的含义)

在Linux64系统下,我们知道一个int类型的大小是4bit。
那么假设我们的数组的第一个元素的起始地址为0x00,那么第一个元素应该是0x04。也就是如下:

matrix[0][0] (地址0) matrix[0][1] (地址4) matrix[0][2] (地址8) matrix[0][3] (地址12)
matrix[1][0] (地址16) matrix[1][1] (地址20) matrix[1][2] (地址24) matrix[1][3] (地址28)
matrix[2][0] (地址32) matrix[2][1] (地址36) matrix[2][2] (地址40) matrix[2][3] (地址44)

但是为什么我们在使用指针遍历的时候,写法是:

 int element = *(ptr + i * 4 + j); // 计算偏移并解引用指针

根据这个计算方式,我们在第一行中得到以下偏移:

matrix[0][0] 的偏移是 i * 4 + j = 0 * 4 + 0 = 0。
matrix[0][1] 的偏移是 i * 4 + j = 0 * 4 + 1 = 1。
matrix[0][2] 的偏移是 i * 4 + j = 0 * 4 + 2 = 2。
matrix[0][3] 的偏移是 i * 4 + j = 0 * 4 + 3 = 3

这看上去与我们上面写的地址是0,4,8不太一样,为什么呢?

这是因为 ptr 是一个指向 int 类型的指针,它的增量是 sizeof(int) 字节,因此每次移动一个 int 的大小(通常是4字节)。这正是为什么我们在计算偏移时只需要考虑 i 和 j,而不需要考虑元素的物理大小。

所以,偏移是按照指针的增量来计算的,而不是根据元素的物理大小。这种方式使得多维数组的遍历更加通用,不受元素大小的影响。

使用场景

多维数组是一种在程序中组织和存储数据的重要数据结构,它可以用于解决各种问题,具有广泛的应用场景。以下是多维数组的一些常见作用和使用场景,以及一些例子:

  • 矩阵和二维数据的表示: 多维数组通常用于表示矩阵、表格和类似的二维数据结构。例如,图像处理中的像素矩阵、棋盘游戏的棋盘状态、二维地图等。

  • 多维数据的存储和处理: 多维数组可以用于存储和处理具有多个维度的数据。例如,科学和工程领域中的多维数据集,如立体图像数据、声音信号、气象数据等(当然,考研你肯定处理不到这玩意,我写代码可能用得到)。

  • 矩阵运算: 线性代数中的矩阵运算和矩阵乘法通常需要使用多维数组表示。例如,计算机图形学中的矩阵变换和投影(算法题经常需要用到矩阵变换)。

嵌套结构: 多维数组可以用于表示嵌套结构的数据,例如多层的树形结构或多层的地理数据。

图和网络算法: 图和网络算法通常使用多维数组来表示节点和边的关系。例如,图的邻接矩阵或邻接列表(图是最经典的用多维数组的方法了)。

游戏开发: 多维数组常用于游戏开发中的地图、迷宫、游戏棋盘、角色位置等(迷宫算法以及路径算法也都会用到)。

动态规划: 动态规划算法中,多维数组常用于存储中间计算结果,以解决优化问题,如最短路径、最长公共子序列等(最常见的还是在动态规划中)。

空间和时间复杂度优化: 多维数组可以用于优化数据访问和算法性能。例如,在一些计算密集型任务中,多维数组的合理使用可以降低时间复杂度。

408考研各数据结构C/C++代码(Continually updating)

408考研各数据结构C/C++代码(Continually updating)
这个模块是我应一些朋友的需求,希望我能开一个专栏,专门提供考研408中各种常用的数据结构的代码,并且希望我附上比较完整的注释以及提供用户输入功能,ok,fine,这个专栏会一直更新,直到我认为没有新的数据结构可以讲解了。
目前我比较熟悉的数据结构如下:
数组、链表、队列、栈、树、B/B+树、红黑树、Hash、图。
所以我会先有空更新出如下几个数据结构的代码,欢迎关注。 当然,在我前两年的博客中,对于链表、哈夫曼树等常用数据结构,我都提供了比较完整的详细的实现以及思路讲解,有兴趣可以去考古。

相关文章:

【数据结构C/C++】多维数组的原理、访问方式以及作用

文章目录 什么是多维数组&#xff1f;代码讲解使用方式为什么指针遍历的方式是这样子的&#xff1f;&#xff08;助你理解指针的含义&#xff09;使用场景408考研各数据结构C/C代码&#xff08;Continually updating&#xff09; 什么是多维数组&#xff1f; 在C语言中&#x…...

2023年中国烹饪机器人市场发展概况分析:整体规模较小,市场仍处于培育期[图]

烹饪机器人仍属于家用电器范畴&#xff0c;是烹饪小家电的进一步细分&#xff0c;它是烹饪小家电、人工智能和服务机器在厨房领域的融合。烹饪机器人是一种智能化厨房设备&#xff0c;可以根据预设的程序实现自动翻炒和烹饪&#xff0c;是多功能料理机和炒菜机结合的产物。 烹…...

Android原生实现控件选择背景变色方案(API28及以上)

Android控件点击/选择后控件背景变色的实现方式有很多种&#xff0c;例如使用selector的xml文件实现。这里介绍一下另一种Android原生的点击/选择实现方案&#xff08;API28及以上&#xff09;&#xff0c;也就是ColorStateListDrawable。 ColorStateListDrawable是一个可根据不…...

为什么要学C语言及C语言存在的意义

为什么要学C语言及C语言存在的意义 汇编生C&#xff0c;C生万物。linus说自己最喜欢的语言就是C语言&#xff0c;因为看到写出的代码就能想到对应的汇编码。一方面说明C语言足够简洁&#xff0c;没有像C中一样的复杂概念封装&#xff0c;另一方面也说明C语言足够的底层&#xf…...

数据结构——空间复杂度

空间复杂度&#xff0c;与算法运行时所需的内存空间有关。 默认问题规模为n。 举例案例&#xff0c;具体分析。 1.全是普通变量 2.一维数组 3.二维数组 4.递归--变量 不递归的时候空间复杂度是O(1)&#xff0c;递归的话递归n次&#xff0c;乘以n&#xff0c;所以空间复杂度…...

uniapp:swiper-demo效果

单元格轮播 <swiper class"swiper1" :circular"true" :autoplay"true" interval"3000" previous-margin"195rpx" next-margin"195rpx"><swiper-item v-for"(item,index) in 5" :key"inde…...

Graphviz 作图工具

选择 Graphviz 作为作图工具&#xff0c;主要是想通过代码创建图标&#xff0c;按照 Graphviz 的代码规范就可以生成 svg 的图片。当然&#xff0c;这样的工具也有很多&#xff0c;有些 markdown 编辑器也做了集成&#xff0c;比如&#xff1a; flowchart.jsMermaid 了解 Gra…...

vue、vuex状态管理、vuex的核心概念state状态

每一个 Vuex 应用的核心就是 store&#xff08;仓库&#xff09;。“store”基本上就是一个容器&#xff0c;它包含着你的应用中大部分的状态 (state)。Vuex 和单纯的全局对象有以下两点不同&#xff1a; Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候&…...

【QT】Qt Application Manager启动应用源码分析

Qt Application Manager启动应用源码分析 Qt Application Manager&#xff08;以下简称QTAM&#xff09;是QT推出的一款应用管理程序&#xff0c;可以把它简单理解成Android的LauncherSystemUI。但是&#xff0c;QTAM又集成了Wayland功能&#xff0c;并且自身实现了一套Compos…...

MyBatisPlus(十)判空查询

说明 判空查询&#xff0c;对应SQL语句中的 IS NULL语句&#xff0c;查询对应字段为 NULL 的数据。 isNull /*** 查询用户列表&#xff0c; 查询条件&#xff1a;电子邮箱为 null 。*/Testvoid isNull() {LambdaQueryWrapper<User> wrapper new LambdaQueryWrapper<…...

AIGC(生成式AI)试用 8 -- 曾经的难题

长假&#xff0c;远离电脑、远离手机、远离社交。 阴雨连绵&#xff0c;望着窗外发呆&#xff0c;AIGC为何物&#xff1f;有什么问题要问AIGC&#xff1f;AIGC可以代替我来发呆&#xff0c;还是可是为我空出时间发呆&#xff1f; 如果可以替代我发呆&#xff0c;要我何…...

文化主题公园旅游景点3d全景VR交互体验加深了他们对历史文化的认知和印象

如今&#xff0c;沉浸式体验被广泛应用于文旅行业&#xff0c;尤其是在旅游演艺活动中。在许多城市&#xff0c;沉浸式旅游演艺活动已成为游客“必打卡”项目之一。因其独特体验和强互动性&#xff0c;这类演艺活动不仅吸引了外地游客&#xff0c;也吸引了本地观众。 随着信息化…...

京东数据分析平台:2023年8月京东奶粉行业品牌销售排行榜

鲸参谋监测的京东平台8月份奶粉市场销售数据已出炉&#xff01; 鲸参谋数据显示&#xff0c;8月份京东平台上奶粉的销售量将近700万件&#xff0c;环比增长约15%&#xff0c;同比则下滑约19%&#xff1b;销售额将近23亿元&#xff0c;环比增长约4%&#xff0c;同比则下滑约3%。…...

Java 21:虚拟线程介绍

Java 21 版本更新中最重要的功能之一就是虚拟线程 (JEP 444)。这些轻量级线程减少了编写、维护和观察高吞吐量并发应用程序所需的工作量。 正如我的许多其他文章一样&#xff0c;在推出新功能之前&#xff0c;让我们先看看 Java 21 版本更新前的现状&#xff0c;以便更好地了解…...

Redis-缓存穿透,缓存击穿,缓存雪崩

缓存穿透&#xff0c;缓存击穿&#xff0c;缓存雪崩 缓存穿透处理方案解决方案1 缓存空数据解决方案2 布隆过滤器 缓存击穿处理方案解决方案 1 互斥锁解决方案2 逻辑过期 缓存雪崩处理方案解决方案 1 给不同的key的过期时间设置添加一个随机值&#xff0c;降低同一个时段大量ke…...

如何使用Docker实现分布式Web自动化!

01、前言 顺着docker的发展&#xff0c;很多测试的同学也已经在测试工作上使用docker作为环境基础去进行一些自动化测试&#xff0c;这篇文章主要讲述在docker中使用浏览器进行自动化测试如果可以实现可视化&#xff0c;同时可以对浏览器进行相关的操作。 02、开篇 首先我们…...

从零开始:制作出色的产品原型图的详细教程

在设计产品的初始版本或模型时&#xff0c;产品原型起着非常重要的作用&#xff0c;可以帮助设计师和团队更好地了解产品需求和用户需求&#xff0c;优化和改进设计&#xff0c;确保设计最终满足用户的需求和期望。如果你不知道如何绘制产品原型图&#xff0c;绘制产品原型图的…...

美国访问学者签证如何申请加急办理?

许多中国学者梦想着前往美国深造&#xff0c;积累更多的学术经验和知识。然而&#xff0c;签证申请过程可能会变得复杂和繁琐&#xff0c;特别是如果你需要在紧急情况下前往美国。但别担心&#xff0c;本文知识人网小编将为您介绍美国访问学者签证加急办理的一些建议和步骤。 首…...

33 WEB漏洞-逻辑越权之水平垂直越权全解

目录 前言水平&#xff0c;垂直越权&#xff0c;未授权访问Pikachu-本地水平垂直越权演示(漏洞成因)墨者水平-身份认证失效漏洞实战(漏洞成因)原理越权检测-Burpsuite插件Authz安装测试(插件使用)修复防御方案 前言 越权漏洞文章分享&#xff1a;https://www.cnblogs.com/zhen…...

【FreeRTOS】【STM32】02 FreeRTOS 移植

基于 [野火]《FreeRTOS%20内核实现与应用开发实战—基于STM32》 正点原子《STM32F429FreeRTOS开发手册_V1.2》 准备 基础工程&#xff0c;例如点灯 FreeRTOS 系统源码 FreeRTOS 移植 上一章节已经说明了Free RTOS的源码文件在移植时所需要的&#xff0c;FreeRTOS 为我们提供…...

STM32F4X 内部FLASH使用

STM32F4X 内部FLASH使用 STM32F4X 内部FLASHSTM32F4X内部FLASH结构STM32F40X和STM32F41X内部FLASH结构STM32F42X和STM32F43X内部FLASH结构 STM32F4X内部FLASH操作例程internal_flash.hinternal_flash.cmain.c 在嵌入式开发中&#xff0c;经常需要实时保存一些数据。如果工程的代…...

减小windows或linux虚拟机导出ova体积大小

减小windows或linux虚拟机导出ova体积大小 删除无用的文件&#xff0c;比如日志或者命令&#xff0c;程序等&#xff1b;去除磁盘碎片将不用的内存空间填充为0&#xff0c;便于vmdk压缩。 例子&#xff1a; 日志文件置空&#xff1a; 批量置空 /sf/data/log/ 目录下的日志文…...

WPF livecharts 折线图遮挡数字问题

在WPF里使用livecharts&#xff0c;如果折线图或者柱状图有多个的时候&#xff0c;可能会出现两个数字遮挡问题&#xff0c;这时候要设置DataLabelsTemplate 属性。 如LineSeries设置代码如下&#xff1a; 第一个折线图的DataLabelsTemplate var stackPanelFactory new Fra…...

电力系统数字化升级改造之配电室无人值守

随着科技的不断进步&#xff0c;电力系统的数字化升级改造已成为必然趋势。其中&#xff0c;配电室的无人值守是其中重要的一环。 配电室是电力系统的重要组成部分&#xff0c;其运行状态直接影响到电力系统的稳定性和可靠性。然而&#xff0c;传统的配电室存在很多问题&am…...

集合Set

目录 一、去重问题 一、去重问题 题目描述&#xff1a; 小明想在学校中请一些同学一起做一项问卷调查&#xff0c;为了实验的客观性他先用计算机生成了N个1&#xff5e;1000之间的随机整数(N<1000),N是用户输入的&#xff0c;对于其中重复的数字&#xff0c;只保留一个&am…...

TCP/IP(二)导论

一 知识铺垫 以下内容参照 <<电子科技大学TCPIP协议原理>>全 ① 协议和标准 一组规则&#xff1a; 交通规则、学生上学的学生守则等;数据通信的规则,有一个专门的名称叫作协议 protocol语义&#xff1a;具体描述在通信当中,每一个信息的具体含义. 二进制bit流…...

Java之UDP,TCP的详细解析

练习四&#xff1a;文件名重复 public class UUIDTest { public static void main(String[] args) { String str UUID.randomUUID().toString().replace("-", ""); System.out.println(str);//9f15b8c356c54f55bfcb0ee3023fce8a } } public class Client…...

【总结】kubernates crd client-java 关于自定义资源的增删改查

Java model 准备 首先使用 crd.yml 和 kubernetes CRD 自动生成 Java model 类&#xff0c;这是一切的前提&#xff0c;之前在这个地方也卡了很久。如何生成在另外一个文章中已经有所记录。 使用 crd.yml 和 kubernetes CRD 自动生成 Java model 类 CustomObjectsApi 文档学习…...

蓝牙主要知识,一文概览

蓝牙知识相关 文章目录 蓝牙知识相关1.蓝牙版本的发展简史2.低功耗BLE PHY2.1 频段**2.2 BLE调制方案—GFSK**2.3 **蓝牙 LE 传输速度、功率和接收器灵敏度**2.4 **BLE 时分双工 (TDD)**3.BT主从连接过程3.1 主设备工作模式3.1.1 积木编程控制台3.2 从设备工作模式3.2.1 蓝牙遥…...

Linux 守护进程

一 何为守护进程 守护进程&#xff08; Daemon &#xff09;也称为精灵进程&#xff0c;是运行在后台的一种特殊进程&#xff0c;它独立于控制终端并且周期性 地执行某种任务或等待处理某些事情的发生&#xff0c;主要表现为以下两个特点&#xff1a; 长期运行。守护进程是一…...

佛山网站建设永网/nba湖人最新新闻

如何使用Linux Shell脚本查看Java线程的CPU使用情况&#xff1f;线上Java应用&#xff0c;在业务高峰期的时候经常出现CPU跑高&#xff0c;需要查看实时的线程占用cpu情况。以下脚本可以快速导出每个线程的占用CPU情况&#xff0c;结合jstack日志&#xff0c;排查到具体的线程类…...

直接在原备案号下增加新网站/淘宝培训

如下代码&#xff0c;输入评论&#xff0c;如果评论中含有敏感词则更换成*号&#xff0c;否则正常输入。 li ["老师", "你好", "333", "4444"]word str(input(>>>))for i in li: if i in word: num len(i) …...

出售网站建设群/电商网站建设开发

1.页面输出缓存1>.在aspx页面顶部加上下面语句 &#xff0c;则设置整个页面进行输出缓存 <% OutputCache Duration"30" VaryByParam"none" %>Duration:设置缓存的有效时间;VaryByParam:根据Request请求的参数进行改变缓存页面VaryByControl&#…...

志愿者网站时长码怎么做/网站推广的常用方法有哪些?

你有没有考虑过&#xff0c;当你辛辛苦苦写了好多代码&#xff0c;最后编译运行的时候&#xff0c;计算机到底经历了什么过程&#xff1f; 如同施了魔法一般&#xff0c;计算机运行的程序实现了我们当初的构想。 而随着计算机技术的不断提高&#xff0c;我们可以利用集成开发…...

网站建设 图片/安徽网站开发哪家好

很多世界顶尖的“建筑师”可能是你从未听说过的人&#xff0c;他们设计并创造出了很多你可能从未见过的神奇结构&#xff0c;比如在芯片内部源于沙子的复杂体系。如果你使用手机、电脑&#xff0c;或者通过互联网收发信息&#xff0c;那么你就无时无刻不在受益于这些建筑师们的…...

淮安网站建设 淮安网站制作/手机百度经验首页登录官网

众所周知&#xff0c;孩子多吃鱼肉可以快速补充身体所需的营养物质&#xff0c;因为鱼肉里蛋白质和DHA含量较高&#xff0c;而且易于消化。孩子的肠胃不会产生负担&#xff0c;能更好吸收营养。但不是让孩子猛地吃鱼身体就会更好&#xff0c;而且不是所有的鱼吃了都是有好处的。…...