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

详解下c语言下的多维数组和指针数组

    在实际c语言编程中,三维及以上数组我们使用的很少,二维数组我们使用得较多。说到数组,又不得关联到指针,因为他们两者的联系太紧密了。今天我们就详细介绍下c语言下的多维数组(主要是介绍二维数组)和指针。

一、二维数组

1.1,存储格式

    一般大家看待二维数,都会把它看作一张表格,例如一个int a[3][4]的数组:

    实际上,计算机中二维数组是以顺序的方式存储的,其内部存储格式如下,还是以int a[3][4]为例子:

1.2,二维数组声明和访问

    我们可以通过如下方式进行二维数组声明和初始化:

    char c[3][10]; //声明一个char类型的二维数组,它是包含3个长度为10的char数组int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12}; //声明并初始化一个int类型的二维数组并初始化

   二维数组的访问:

    int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};for(int i=0;i<3;i++){for(int j=0;j<4;j++){printf("the element a[i][j] is %d\n", a[i][j]);}}

    

    我们也可以利用指针的形式进行访问(数组的名字实际代表的数组首地址):

 

    int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};for(int i=0;i<3;i++){for(int j=0;j<4;j++){printf("the element a[i][j] is %d\n", *(*(a+i)+j));}}

 二、指针数组

 2.1,指针数组存储格式

    指针数组代表某一数组中的所有元素都是指针,其内部存储格式如下,我们以int *p[3]为例:

    具体代码如下:

int main() {int a = 100;int b = 200;int c = 300;int *p[3] = {&a, &b, &c};printf("the a address is %x\n", p[0]);printf("the a address is %x\n", p[1]);printf("the a address is %x\n", p[2]);return 0;
}

 

 2.2,指针数组的声明和访问

    我们可以通过如下方式进行指针数组的声明和初始化;

    char *c[10];//声明一个包含10个char类型指针的数组int a = 100;int b = 200;int c = 300;int *p[3] = {&a, &b, &c};//声明一个包含3个int类型指针数组,并进行了初始化

    指针数组的访问,我们可以通过如下两种方式进行指针数组指向内容的访问:

int main() {int a = 100;int b = 200;int c = 300;int *p[3] = {&a, &b, &c};for(int i=0;i<3;i++){printf("the element i point to value is %d\n", *p[i]);}for(int j=0;j<3;j++){printf("the element i point to value is %d\n", **(p+j));}return 0;
}

 

三、二维数组与指针数组的比对

    我们可以看到,对于二维数组和指针数组,我们都可以通过*(*(a+i)+j)的方式去访问,于是很多人误认为二维数组和指针数组是同一个东西,然两者其实还是有区别的。

    对于二维数组

char a[3][4] = {{'t','p','c'},{'i','s'},{'m','a','n'}}

    无论每个数组中元素是否存储值,它的存储空间必需为sizeof(char)*3*4的。 

    二维数组元素访问(*(*(a+i)+j)),a的地址在程序编译阶段即可知道,我们获取数组某个元素,然后如下进行:

  • 1,取a的地址值
  • 2,取i的值,得知需要获取跨过的行长度(sizeof(char)*4*i),然后加到a地址值上
  • 3,取j的值,得知需要获取跨过的元素长度(sizeof(char)*j),然后加到上一步得到的地址上
  • 4,从第3步获取的地址,得到需要取得的元素的地址,从中取出值

    对于指针数组

char *a[3] = {"tpc","is","good"};

    a中存在4个char类型指针,每个指针指向的一个char类型数组,但是每个数组的长度不一样。 

    指针数组元素访问(*(*(a+i)+j)),a的地址在程序编译阶段即可知道,我们需要获取数组某个元素,需要如下进行: 

  • 1,取a的地址值(假设为100)
  • 2,取i的值,得知需要跨过的元素的字节长度(sizeof(char *)*i,然后的到具体元素的地址,值为100+sizeof(char *)*i(假设求出来为104)
  • 3,根据地址值104(因为a[i]为指针,我们需要根据指针值再去获取指向内容),我们得到内部存储地址为0x4071d4
  • 4,取j的值,得知需要跨过的元素字节长度(sizeof(char)*j)(假设j为1),那么我们得到需要取得元素的地址为0x4071d4+sizeof(char)*1 = 0x4071d5
  • 5,从0x4071d5中取出内容(对应图中的's')

四、数组指针

    对应一个二维数组,如果我们需要通过声明一个指针来指向它,可以通过如下方式:

int main() {int a[2][3] = {1,2,3,4,5};int (*p)[3] = a;printf("the address of a is %d\n", a);printf("the value of p is %d\n", p);}

 

    我们通过如下方式利用指针访问a中元素。

  • 1,获取指针p存储的值,得到a的地址,a为一个包含2个含有3个元素的数值
  • 2,我们通过p+i,及a+i获取a中对应2个数组元素的首地址 
  • 3,我们通过*(p+i)+j,获取对应数组元素中的具体元素地址
  • 4,我们通过*(*(p+i)+j),获取到具体的元素值
int main() {int a[2][3] = {1,2,3,4,5};int (*p)[3] = a;for(int i=0;i<2;i++)for(int j=0;j<3;j++)printf("the element a[%d][%d] is %d\n", i, j, *(*(p+i)+j));}

 

相关文章:

详解下c语言下的多维数组和指针数组

在实际c语言编程中&#xff0c;三维及以上数组我们使用的很少&#xff0c;二维数组我们使用得较多。说到数组&#xff0c;又不得关联到指针&#xff0c;因为他们两者的联系太紧密了。今天我们就详细介绍下c语言下的多维数组(主要是介绍二维数组)和指针。 一、二维数组 1.1&am…...

免费送源码:Java+ssm+MySQL 基于微服务架构的餐饮系统的设计与实现 计算机毕业设计原创定制

摘 要 近年来,我国经济和社会发展迅速,人们物质生活水平日渐提高,餐饮行业更是发展迅速,人们对于餐饮行业的认识和要求也越来越高。传统形式的餐饮行业都是以人为本,管理起来需要很多人力、物力、财力,既不方便管理者的管理,也不方便顾客实时了解餐厅动态,给传统餐饮行业的经…...

LeetCode hot100-69-N

https://leetcode.cn/problems/valid-parentheses/description/?envTypestudy-plan-v2&envIdtop-100-liked 20. 有效的括号 已解答 简单 相关标签 相关企业 提示 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#x…...

【橘子容器】如何构建一个docker镜像

你肯定打过docker镜像是吧&#xff0c;作为一个开发这很正常&#xff0c;那么你用的什么打包方式呢&#xff0c;这里我们来梳理几种常用的docker镜像构建方式。 ps&#xff1a;这里不是太讲原理&#xff0c;更多的是一种科普和操作。因为讲原理的东西网上已经够多了。 一、Dock…...

EFAK kafka可视化管理工具部署使用

简介&#xff1a;EFAK是开源的可视化和管理软件。它允许您查询、可视化、提醒和探索您的指标&#xff0c;无论它们存储在何处。简单来说&#xff0c;它为您提供了将 Kafka 集群数据转换为漂亮的图形和可视化效果的工具。 环境&#xff1a;①操作系统&#xff1a;CentOS7.6&…...

Spring Boot 工程分层实战(五个分层维度)

1、分层思想 计算机领域有一句话&#xff1a;计算机中任何问题都可通过增加一个虚拟层解决。这句体现了分层思想重要性&#xff0c;分层思想同样适用于Java工程架构。 分层优点是每层只专注本层工作&#xff0c;可以类比设计模式单一职责原则&#xff0c;或者经济学比较优势原…...

vscode IntelliSense Configurations

IntelliSense 是一个强大的代码补全和代码分析功能&#xff0c;它可以帮助开发者提高编程效率。图中显示的是 VSCode 的 IntelliSense 配置界面&#xff0c;具体配置如下&#xff1a; Compiler path&#xff08;编译器路径&#xff09;: 这里指定了用于构建项目的编译器的完整路…...

hbase读写操作后hdfs内存占用太大的问题

hbase读写操作后hdfs内存占用太大的问题 查看内存信息hbase读写操作 查看内存信息 查看本地磁盘的内存信息 df -h查看hdfs上根目录下各个文件的内存大小 hdfs dfs -du -h /查看hdfs上/hbase目录下各个文件的内存大小 hdfs dfs -du -h /hbase查看hdfs上/hbase/oldWALs目录下…...

C++----入门篇

引言 C是在C的基础之上&#xff0c;容纳进去了面向对象编程思想&#xff0c;并增加了许多有用的库&#xff0c;以及编程范式等。熟悉C语言之后&#xff0c;对C学习有一定的帮助&#xff0c;本章节主要目标&#xff1a; 1. 补充C语言语法的不足&#xff0c;以及C是如何对C语言…...

C语言程序设计P5-5【应用函数进行程序设计 | 第五节】—知识要点:变量的作用域和生存期

知识要点&#xff1a;变量的作用域和生存期 视频&#xff1a; 目录 一、任务分析 二、必备知识与理论 三、任务实施 一、任务分析 有一个一维数组&#xff0c;内放 10 个学生成绩&#xff0c;写一个函数&#xff0c;求出平均分、最高分和最低分。 任务要求用一个函数来完…...

用 Sass 模块化系统取代全局导入,消除 1.80.0 引入的 @import 弃用警告

目录 前言 问题 import 的缺陷 命名冲突 重复导入 模块系统 use 规则 forward 规则 实际修改 前言 最初&#xff0c;Sass 使用 import 规则通过单个全局命名空间加载其他文件&#xff0c;所有内置函数也可全局使用。由于模块系统&#xff08;use 和 forward 规则&…...

安卓低功耗蓝牙BLE官方开发例程(JAVA)翻译注释版

官方原文链接 https://developer.android.com/develop/connectivity/bluetooth/ble/ble-overview?hlzh-cn 目录 低功耗蓝牙 基础知识 关键术语和概念 角色和职责 查找 BLE 设备 连接到 GATT 服务器 设置绑定服务 设置 BluetoothAdapter 连接到设备 声明 GATT 回…...

搭建fastapi项目

环境准备 # 创建项目目录 mkdir my_fastapi_project cd my_fastapi_project# 创建和激活虚拟环境 python -m venv venv .\venv\Scripts\activate安装必要的包 pip install fastapi uvicorn python-dotenv创建项目基本结构 my_fastapi_project/ │ .env # …...

Maven学习(Maven项目模块化。模块间“继承“机制。父(工程),子项目(模块)间聚合)

目录 一、Maven项目模块化&#xff1f; &#xff08;1&#xff09;基本介绍。 &#xff08;2&#xff09;汽车模块化生产再聚合组装。 &#xff08;3&#xff09;Maven项目模块化图解。 1、maven_parent。 2、maven_pojo。 3、maven_dao。 4、maven_service。 5、maven_web。 6…...

华为云云原生中间件DCS DMS 通过中国信通院与全球IPv6测试中心双重能力检测

近日&#xff0c;中国信息通信研究院&#xff08;以下简称“中国信通院”&#xff09;与全球IPv6测试中心相继宣布&#xff0c;华为云的分布式缓存服务&#xff08;Distributed Cache Service&#xff0c;简称DCS&#xff09;和分布式消息服务&#xff08;Distributed Message …...

PostgreSQL中事件触发器Event Trigger

在PostgreSQL中&#xff0c;事件触发器&#xff08;Event Trigger&#xff09;是一种特殊的触发器类型&#xff0c;它允许你在特定的数据库系统事件发生时执行特定的操作。与普通的触发器不同&#xff0c;事件触发器并不与特定的表或视图相关联&#xff0c;而是与数据库级别的全…...

uni.request流式(Stream)请求,实现打印机效果

最近使用扣子 - 开发指南 (coze.cn)和智谱AI开放平台开发小程序AI导诊和用药对话指南。 开发的过程中也是走了不少坑,下面就来聊聊走了哪些坑。 坑1 :coze试了v2和v3的接口,两个接口请求还是有点差别的,v2拿到了botId和accessToken可以直接请求不需要做任何处理,v3还需要…...

canvas保存图片

需求&#xff1a;上面有几个按钮&#xff0c;其中有一个切换是图片 用v-if会导致图片加载慢 实现方法&#xff1a; 一进来就加载&#xff0c;通过监听元素显示&#xff0c;用于控制canvas的宽高&#xff0c;从而达到隐藏的效果 组件dowolad.vue <template><view …...

DNS到底有什么用?

举个例子&#xff0c;对于我们来说访问的域名是www.baidu.com&#xff0c;但是实际在计算机并不认识这个域名&#xff0c;计算机是需要通过IP地址去访问这个网站&#xff0c;所以呢&#xff1f;这个时候就需要一个dns解析器&#xff0c;来把这串域名转换为IP地址给计算机去访问…...

什么是CRM系统?CRM系统的功能、操作流程、生命周期

CRM系统作为企业管理和维护客户关系的重要工具&#xff0c;在商业活动中扮演着越来越重要的角色。今天&#xff0c;就让我们一起揭开它的神秘面纱&#xff0c;看看这个“幕后英雄”到底是怎么工作的。 什么是CRM系统&#xff1f; 首先&#xff0c;我们要了解什么是CRM。简单来…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

一、多模态商品数据接口的技术架构 &#xff08;一&#xff09;多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如&#xff0c;当用户上传一张“蓝色连衣裙”的图片时&#xff0c;接口可自动提取图像中的颜色&#xff08;RGB值&…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)

推荐 github 项目:GeminiImageApp(图片生成方向&#xff0c;可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

git: early EOF

macOS报错&#xff1a; Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...

jdbc查询mysql数据库时,出现id顺序错误的情况

我在repository中的查询语句如下所示&#xff0c;即传入一个List<intager>的数据&#xff0c;返回这些id的问题列表。但是由于数据库查询时ID列表的顺序与预期不一致&#xff0c;会导致返回的id是从小到大排列的&#xff0c;但我不希望这样。 Query("SELECT NEW com…...

Vue3 PC端 UI组件库我更推荐Naive UI

一、Vue3生态现状与UI库选择的重要性 随着Vue3的稳定发布和Composition API的广泛采用&#xff0c;前端开发者面临着UI组件库的重新选择。一个好的UI库不仅能提升开发效率&#xff0c;还能确保项目的长期可维护性。本文将对比三大主流Vue3 UI库&#xff08;Naive UI、Element …...

用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章

用 Rust 重写 Linux 内核模块实战&#xff1a;迈向安全内核的新篇章 ​​摘要&#xff1a;​​ 操作系统内核的安全性、稳定性至关重要。传统 Linux 内核模块开发长期依赖于 C 语言&#xff0c;受限于 C 语言本身的内存安全和并发安全问题&#xff0c;开发复杂模块极易引入难以…...

从零手写Java版本的LSM Tree (一):LSM Tree 概述

&#x1f525; 推荐一个高质量的Java LSM Tree开源项目&#xff01; https://github.com/brianxiadong/java-lsm-tree java-lsm-tree 是一个从零实现的Log-Structured Merge Tree&#xff0c;专为高并发写入场景设计。 核心亮点&#xff1a; ⚡ 极致性能&#xff1a;写入速度超…...