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

news2024/12/16 22:28:52

    在实际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));

}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2260719.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

EXCEL的各种图形,统计图形

目录 0 EXCEL的各种图形&#xff0c;统计图形 1 统计图形 / 直方图 / 其实叫 频度图 hist最合适(用原始数据直接作图) 1.1 什么是频度图 1.2 如何创建频度图&#xff0c;一般是只选中1列数据&#xff08;1个数组&#xff09; 1.3 如何修改频度图的宽度 1.4 hist图的一个特…

npm内存溢出

项目过大运行项目内存溢出 报错代码 运行内存溢出 increase-memory-limit ‘“node --max-old-space-size8192”’ 不是内部或外部命令&#xff0c;也不是可运行的程序 FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of m…

快速部署一套K8s集群-v1.28

快速部署一套K8s集群-v1.28 1.前置知识点 1.1 生产环境可部署Kubernetes集群的两种方式 目前生产部署Kubernetes集群主要有两种方式: kubeadmKubeadm是一个K8s部署工具,提供kubeadm init和kubeadm join,用于快速部署Kubernetes集群。 二进制包从github下载发行版的二进…

Y3编辑器教程5:触发器进阶使用(镜头、UI、表格、函数库、排行榜、游戏不同步)

文章目录 一、游戏声音设计二、 游戏镜头设计2.1 镜头的基本参数2.2 镜头时间轴动画 三、界面编辑3.1 界面编辑器设置3.2 添加按钮事件3.3 触发编写 四、 表格编辑器&#xff08;实现对话UI&#xff09;4.1 一维表和多维表4.2 数据验证、搜索、保存与撤销4.3 Excel导入导出4.4 …

vue3实现页签

功能点&#xff1a; 新增和删除页签拖拽页签 需要引入插件"vue-draggable-plus": "^0.6.0", 代码已注释右键弹框操作页签左右点击滚动页签和鼠标滑轮滚动页签 注意点 useStore涉及的部分是pina的缓存&#xff0c;需要改成自己的&#xff1b;userStore.tab…

ARCGIS国土超级工具集1.2更新说明

ARCGIS国土超级工具集V1.2版本&#xff0c;功能已增加至47 个。在V1.1的基础上修复了若干使用时发现的BUG&#xff0c;新增了"矢量分割工具"菜单&#xff0c;同时增加及更新了了若干功能&#xff0c;新工具使用说明如下&#xff1a; 一、勘测定界工具栏更新界址点成果…

element-ui实现table表格的嵌套(table表格嵌套)功能实现

最近在做电商类型的官网&#xff0c;希望实现的布局如下&#xff1a;有表头和表身&#xff0c;所以我首先想到的就是table表格组件。 表格组件中常见的就是&#xff1a;标题和内容一一对应&#xff1a; 像效果图中的效果&#xff0c;只用基础的表格布局是不行的&#xff0c;因…

图像分割数据集石头rock分割数据集labelme格式2602张3类别

数据集格式&#xff1a;labelme格式(不包含mask文件&#xff0c;仅仅包含jpg图片和对应的json文件) 图片数量(jpg文件个数)&#xff1a;2602 标注数量(json文件个数)&#xff1a;2602 标注类别数&#xff1a;3 标注类别名称:["claystone","silt","…

语音芯片赋能可穿戴设备:开启个性化音频新体验

在科技日新月异的今天&#xff0c;语音芯片与可穿戴设备的携手合作&#xff0c;正引领我们步入一个前所未有的个性化音频时代。这一创新融合&#xff0c;用户可以享受到更加个性化、沉浸式的音频体验。下面将详细介绍语音芯片与可穿戴设备合作的优点和具体应用。 1. 定制化音效…

数据挖掘之聚类分析

聚类分析&#xff08;Clustering Analysis&#xff09; 是数据挖掘中的一项重要技术&#xff0c;旨在根据对象间的相似性或差异性&#xff0c;将对象分为若干组&#xff08;簇&#xff09;。同一簇内的对象相似性较高&#xff0c;而不同簇间的对象差异性较大。聚类分析广泛应用…

【iOS】OC高级编程 iOS多线程与内存管理阅读笔记——自动引用计数(四)

目录 ARC规则 规则 对象型变量不能作为C语言结构体的成员 显式转换id和void* 属性 数组 ARC规则 规则 在ARC有效的情况下编译源代码必须遵守一定的规则&#xff1a; 主要解释一下最后两条 对象型变量不能作为C语言结构体的成员 要把对象型变量加入到结构体成员中时&a…

Java-25 深入浅出 Spring - 实现简易Ioc-01 Servlet介绍 基本代码编写

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 大数据篇正在更新&#xff01;https://blog.csdn.net/w776341482/category_12713819.html 目前已经更新到了&#xff1a; MyBatis&#xff…

微服务SpringCloud链路追踪之Micrometer+Zipkin

视频教程&#xff1a; https://www.bilibili.com/video/BV12LBFYjEvR 效果演示 当我们发送一个请求给 Gateway 的时候&#xff0c;由 Micrometer trace 进行链路追踪和数据收集&#xff0c;由 Zipkin 进行数据展示。可以清楚的看到微服务的调用过程&#xff0c;以及每个微服务…

【Java】Iterator迭代器相关API

Iterator 是 Java 集合框架中用于遍历集合&#xff08;List、Set 等&#xff09;的工具&#xff0c;它提供了访问集合中每个元素的统一接口&#xff0c;避免直接操作集合的实现细节。 Iterator的基本使用和方法 基本方法 hasNext()&#xff1a;检查是否还有元素可供迭代。ne…

Android 系统应用重名install安装失败分析解决

Android 系统应用重名install安装失败分析解决 文章目录 Android 系统应用重名install安装失败分析解决一、前言1、Android Persistent apps 简单介绍 二、系统 persistent 应用直接安装需求分析解决1、系统应用安装报错返回的信息2、分析解决 三、其他1、persistent系统应用in…

java基础概念49-数据结构2

一、树 1-1、树的基本概念 1、树的节点 2、二叉树 3、树的高度 1-2、二叉查找树 普通二叉树没有规律&#xff0c;不方便查找&#xff0c;没什么作用。 1、基本概念 2、添加节点 此时&#xff0c;该方式添加形成的二叉查找树&#xff0c;根节点就是第一个节点。 3、查找节点 4…

数据仓库工具箱—读书笔记01(数据仓库、商业智能及维度建模初步)

数据仓库、商业智能及维度建模初步 记录一下读《数据仓库工具箱》时的思考&#xff0c;摘录一些书中关于维度建模比较重要的思想与大家分享&#x1f923;&#x1f923;&#x1f923; 博主在这里先把这本书"变薄"~有时间的小伙伴可以亲自再读一读&#xff0c;感受一下…

说说你对java lambda表达式的理解?

大家好&#xff0c;我是锋哥。今天分享关于【说说你对java lambda表达式的理解?】面试题。希望对大家有帮助&#xff1b; 说说你对java lambda表达式的理解? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Java Lambda 表达式是 Java 8 引入的一项重要特性&#…

ambari-server页面错位问题解决

背景&#xff1a; 项目新安装的ambari集群页面错位如下 解决办法&#xff08;临时&#xff09;&#xff1a; 修改ambari-server的前端文件&#xff1a;/usr/lib/ambari-server/web/javascripts/app.js 原代码&#xff1a; initNavigationBar: function () {if (App.get(r…

高效数据集成:钉钉与企业系统无缝对接

钉钉数据集成案例分享&#xff1a;鸿巢基础资料-供应商账号(删除操作) 在企业信息化管理中&#xff0c;数据的准确性和及时性至关重要。本文将聚焦于一个具体的系统对接集成案例——钉钉数据集成到钉钉&#xff0c;详细探讨如何通过轻易云数据集成平台实现“鸿巢基础资料-供应…