C语言------二维数组指针从入门到精通

前言:

        目标:需要了解及掌握数组指针的行地址、列地址、具体元素地址、具体元素地址的值是怎样定义及实现。

        重点:指针的偏移,指针解引用。

        难点:指针的升阶与降阶。

1. 基本概念

  • 二维数组:二维数组可以看作是一个数组的数组。例如,int a[3][4] 表示一个 3 行 4 列的二维数组。

  • 数组指针:数组指针是一个指针,指向一个数组。例如,int (*p)[4] 表示一个指向包含 4 个整数的数组的指针。

  • 指针数组:指针数组是一个数组,其元素是指针。例如,int *p[3] 表示一个包含 3 个整型指针的数组。

  • 数组名与指针的区别

    • 数组名:在大多数情况下,数组名可以被视为指向其第一个元素的指针。

    • 指针:指针是一个变量,可以指向任何类型的变量,并且可以被重新赋值。

  • 指针运算

    • 指针加减:指针加减操作会根据指针类型调整偏移量。例如,int *p; p + 1 表示 p 向前移动一个 int 的大小。

    • 指针解引用:使用 * 运算符访问指针指向的值。

  • 二维数组的指针表示

    • int arr[3][4]; 中,arr 是一个指向 int [4] 的指针。

    • arr[0] 是一个指向 int 的指针,表示第一行的第一个元素。

    • arr[i] 等价于 *(arr + i),表示第 i 行的第一个元素。

  • 行地址和列地址的区别:二维数组中每一行的行地址和每一行第一列地址在数值上是相同的,但含义不同。行地址是指向整个行的指针,而列地址是指向行中某个元素的指针。

  • 二维数组的地址:二维数组的名字 a 本身就是一个指向第一行的指针,即 a 等价于 &a[0]

2.二维数组的内存布局

        对于二维数组 int arr[2][3];的内存布局如下:

        对于二维数组 int arr[3][4];,内存布局如下:

arr[0][0] arr[0][1] arr[0][2] arr[0][3]

arr[1][0] arr[1][1] arr[1][2] arr[1][3]

arr[2][0] arr[2][1] arr[2][2] arr[2][3]

        假设每个 int 占用4字节,内存地址如下:

arr[0][0] -> 0x7ffee3b8e990
arr[0][1] -> 0x7ffee3b8e994
arr[0][2] -> 0x7ffee3b8e998
arr[0][3] -> 0x7ffee3b8e99c
arr[1][0] -> 0x7ffee3b8e9a0
arr[1][1] -> 0x7ffee3b8e9a4
arr[1][2] -> 0x7ffee3b8e9a8
arr[1][3] -> 0x7ffee3b8e9ac
arr[2][0] -> 0x7ffee3b8e9b0
arr[2][1] -> 0x7ffee3b8e9b4
arr[2][2] -> 0x7ffee3b8e9b8
arr[2][3] -> 0x7ffee3b8e9bc

  3. 二维数组指针代码分析

#include <stdio.h> 
 
int main() { 
    int arr[3][4] = { 
        {1, 2, 3, 4}, 
        {5, 6, 7, 8}, 
        {9, 10, 11, 12} 
    }; 
 
    // 行地址 
    printf("第一行地址: %p\n", (void *)arr); 
    printf("第二行地址: %p\n", (void *)(arr + 1)); 
    printf("第三行地址: %p\n", (void *)(arr + 2)); 
 
    // 列地址 
    printf("第一行第一列地址: %p\n", (void *)arr[0]); 
    printf("第一行第二列地址: %p\n", (void *)(arr[0] + 1)); 
    printf("第二行第一列地址: %p\n", (void *)(*(arr + 1))); 
 
    // 具体元素地址 
    printf("a[1][2]的地址: %p\n", (void *)(arr[1] + 2)); 
    printf("a[1][2]的地址: %p\n", (void *)(*(arr + 1) + 2)); 
    printf("a[1][2]的地址: %p\n", (void *)&arr[1][2]); 
 
    // 具体元素的值 
    printf("a[1][2]的值: %d\n", *(arr[1] + 2)); 
    printf("a[1][2]的值: %d\n", *(*(arr + 1) + 2)); 
    printf("a[1][2]的值: %d\n", arr[1][2]); 
 
    return 0; 
}

4. 地址运算

  • & 运算符:地址升阶,将一个元素的地址提升为指向该元素所在行的指针。
  • *运算符:地址降阶,将一个行地址降阶为该行中某个元素的地址。

5.二维数组指针行地址表示

  • arr

    • arr 是一个指向 int [4] 的指针,表示第一行的地址。

    • 输出:0x7ffee3b8e990

  • arr + 1

    • arr + 1 是一个指向 int [4] 的指针,表示第二行的地址。

    • 输出:0x7ffee3b8e9a0

  • arr + 2

    • arr + 2 是一个指向 int [4] 的指针,表示第三行的地址。

    • 输出:0x7ffee3b8e9b0

6.二维数组指针列地址表示

  • arr[0]

    • arr[0] 是一个指向 int 的指针,表示第一行第一个元素的地址。

    • 输出:0x7ffee3b8e990

  • arr[0] + 1

    • arr[0] + 1 是一个指向 int 的指针,表示第一行第二个元素的地址。

    • 输出:0x7ffee3b8e994

  • *(arr + 1)

    • *(arr + 1) 等价于 arr[1],是一个指向 int 的指针,表示第二行第一个元素的地址。

    • 输出:0x7ffee3b8e9a0

7.二维数组指针具体元素地址表示

  • arr[1] + 2

    • arr[1] + 2 是一个指向 int 的指针,表示第二行第三个元素的地址。

    • 输出:0x7ffee3b8e9a8

  • *(arr + 1) + 2

    • *(arr + 1) + 2 等价于 arr[1] + 2,是一个指向 int 的指针,表示第二行第三个元素的地址。

    • 输出:0x7ffee3b8e9a8

  • &arr[1][2]

    • &arr[1][2] 是一个指向 int 的指针,表示第二行第三个元素的地址。

    • 输出:0x7ffee3b8e9a8

8.二维数组指针具体元素的值表示

  • *(arr[1] + 2)

    • *(arr[1] + 2) 解引用 arr[1] + 2,得到第二行第三个元素的值 7

    • 输出:7

  • *(*(arr + 1) + 2)

    • *(*(arr + 1) + 2) 解引用 *(arr + 1) + 2,得到第二行第三个元素的值 7

    • 输出:7

  • arr[1][2]

    • arr[1][2] 直接访问第二行第三个元素的值 7

    • 输出:7

9. 二维数组指针地址的输出

 // 行地址 
    printf("第一行地址: %p\n", (void *)arr); 
    printf("第二行地址: %p\n", (void *)(arr + 1)); 
    printf("第三行地址: %p\n", (void *)(arr + 2)); 
 
    // 列地址 
    printf("第一行第一列地址: %p\n", (void *)arr[0]); 
    printf("第一行第二列地址: %p\n", (void *)(arr[0] + 1)); 
    printf("第二行第一列地址: %p\n", (void *)(*(arr + 1))); 
 
    // 具体元素地址 
    printf("a[1][2]的地址: %p\n", (void *)(arr[1] + 2)); 
    printf("a[1][2]的地址: %p\n", (void *)(*(arr + 1) + 2)); 
    printf("a[1][2]的地址: %p\n", (void *)&arr[1][2]); 
 
    // 具体元素的值 
    printf("a[1][2]的值: %d\n", *(arr[1] + 2)); 
    printf("a[1][2]的值: %d\n", *(*(arr + 1) + 2)); 
    printf("a[1][2]的值: %d\n", arr[1][2]); 

9. 二维数组指针应用

        使用二维数组指针迎接财神。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AI-ISP论文Learning to See in the Dark解读

论文地址&#xff1a;Learning to See in the Dark 图1. 利用卷积网络进行极微光成像。黑暗的室内环境。相机处的照度小于0.1勒克斯。索尼α7S II传感器曝光时间为1/30秒。(a) 相机在ISO 8000下拍摄的图像。(b) 相机在ISO 409600下拍摄的图像。该图像存在噪点和色彩偏差。©…

自定义数据集 ,使用朴素贝叶斯对其进行分类

代码&#xff1a; # 导入必要的库 import numpy as np import matplotlib.pyplot as plt# 定义类1的数据点&#xff0c;每个数据点是二维的坐标 class1_points np.array([[1.9, 1.2],[1.5, 2.1],[1.9, 0.5],[1.5, 0.9],[0.9, 1.2],[1.1, 1.7],[1.4, 1.1]])# 定义类2的数据点&…

蓝桥杯单片机第七届省赛

前言 这套题不难&#xff0c;相对于第六套题这一套比较简单了&#xff0c;但是还是有些小细节要抓 题目 OK&#xff0c;以上就是全部的题目了&#xff0c;这套题目相对来说逻辑比较简单&#xff0c;四个按键&#xff0c;S4控制pwm占空比&#xff0c;S5控制计时时间&#xff0…

小程序设计和开发:如何研究同类型小程序的优点和不足。

一、确定研究目标和范围 明确研究目的 在开始研究同类型小程序之前&#xff0c;首先需要明确研究的目的。是为了改进自己的小程序设计和开发&#xff0c;还是为了了解市场趋势和用户需求&#xff1f;不同的研究目的会影响研究的方法和重点。例如&#xff0c;如果研究目的是为了…

反向代理模块jmh

1 概念 1.1 反向代理概念 反向代理是指以代理服务器来接收客户端的请求&#xff0c;然后将请求转发给内部网络上的服务器&#xff0c;将从服务器上得到的结果返回给客户端&#xff0c;此时代理服务器对外表现为一个反向代理服务器。 对于客户端来说&#xff0c;反向代理就相当…

一文讲解HashMap线程安全相关问题

HashMap不是线程安全的&#xff0c;主要有以下几个问题&#xff1a; ①、多线程下扩容会死循环。JDK1.7 中的 HashMap 使用的是头插法插入元素&#xff0c;在多线程的环境下&#xff0c;扩容的时候就有可能导致出现环形链表&#xff0c;造成死循环。 JDK 8 时已经修复了这个问…

oracle:子查询

子查询: 一条查询语句中嵌入了另一条查询语句, 被嵌入里面的这条查询语句称为子查询, 外面的查询语句称为主查询 子查询的分类 相关性子查询&#xff08;Correlated Subquery&#xff09;是指子查询的执行依赖于外部查询的每一行数据。也就是说&#xff0c;子查询会对外部查询…

AI技术在SEO关键词优化中的应用策略与前景展望

内容概要 在数字营销的快速发展中&#xff0c;AI技术逐渐成为SEO领域的核心驱动力。其通过强大的数据分析和处理能力&#xff0c;不仅改变了我们优化关键词的方式&#xff0c;也提升了搜索引擎优化的效率和效果。在传统SEO中&#xff0c;关键词的选择与组合常依赖人工经验和直…

Java项目: 基于SpringBoot+mybatis+maven+mysql实现的疫苗发布和接种预约管理系统(含源码+数据库+开题报告+毕业论文)

一、项目简介 本项目是一套基于SpringBootmybatismavenmysql疫苗发布和接种预约管理系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、…

VSCode中快速创建Html文件

1、下载并安装好VSCode软件&#xff0c;启动软件。 2、依次点击左上角选项卡“file”-“New File”。 输入文件名称后缀&#xff0c;如&#xff1a;HelloWorld.html。 选择新建文件的目录所在位置。 3、HelloWorld.html中输入英文格式的!&#xff0c;按回车键后会默认依据…

CMake项目编译与开源项目目录结构

Cmake 使用简单方便&#xff0c;可以跨平台构建项目编译环境&#xff0c;尤其比直接写makefile简单&#xff0c;可以通过简单的Cmake生成负责的Makefile文件。 如果没有使用cmake进行编译&#xff0c;需要如下命令&#xff1a;&#xff08;以muduo库echo服务器为例&#xff09;…

网络原理(4)—— 网络层详解

目录 一. IP协议报头结构 二. 地址管理 2.1 路由器 2.1.1 路由选择 2.1.2 WAN口&#xff08;Wide Area Network&#xff09; 2.1.3 LAN口&#xff08;Local Area Network&#xff09; 2.1.4 WLAN口&#xff08;Wireless Local Area Network&#xff09; 2.2 网段划分…

Hot100之图论

200岛屿数量 题目 思路解析 把访问过的格子插上棋子 思想是先污染再治理&#xff0c;我们有一个inArea&#xff08;&#xff09;函数&#xff0c;是判断是否出界了 我们先dfs&#xff08;&#xff09;放各个方向遍历&#xff0c;然后我们再把这个位置标为0 我们岛屿是连着…

【HarmonyOS之旅】基于ArkTS开发(三) -> 兼容JS的类Web开发(三)

目录 1 -> 生命周期 1.1 -> 应用生命周期 1.2 -> 页面生命周期 2 -> 资源限定与访问 2.1 -> 资源限定词 2.2 -> 资源限定词的命名要求 2.3 -> 限定词与设备状态的匹配规则 2.4 -> 引用JS模块内resources资源 3 -> 多语言支持 3.1 -> 定…

Python从零构建macOS状态栏应用(仿ollama)并集成AI同款流式聊天 API 服务(含打包为独立应用)

在本教程中,我们将一步步构建一个 macOS 状态栏应用程序,并集成一个 Flask 服务器,提供流式响应的 API 服务。 如果你手中正好持有一台 MacBook Pro,又怀揣着搭建 AI 聊天服务的想法,却不知从何处迈出第一步,那么这篇文章绝对是你的及时雨。 最终,我们将实现以下功能: …

【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】2.4 索引优化:避免意外复制的高效技巧

2.4 索引优化&#xff1a;避免意外复制的高效技巧 目录/提纲 #mermaid-svg-hmMAIqF8kFh46fbH {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-hmMAIqF8kFh46fbH .error-icon{fill:#552222;}#mermaid-svg-hmMAIqF8kF…

【C语言进阶(五)】指针进阶详解(下)

指针详解-下 1. 前言2. 函数指针数组2.1 函数指针数组的用途 3. 指向函数指针数组的指针3.1 回调函数 4. 库函数中qsort分析4.1 为什么这个函数需要我们自己实现?4.2 库函数qsort的使用 5. qsort函数的模拟实现5.1 大框架的实现5.2 比较函数的实现5.3 对于交换函数的思考5.4 交…

18.Word:数据库培训课程❗【34】

目录 题目 NO1.2.3.4 NO5设置文档内容的格式与样式 NO6 NO7 NO8.9 NO10.11标签邮件合并 题目 NO1.2.3.4 FnF12&#xff1a;打开"Word素材.docx”文件,将其另存为"Word.docx”在考生文件夹下之后到任务9的所有操作均基于此文件&#xff1a;"Word.docx”…

99.24 金融难点通俗解释:MLF(中期借贷便利)vs LPR(贷款市场报价利率)

目录 0. 承前1. 什么是MLF&#xff1f;1.1 专业解释1.2 通俗解释1.3 MLF的三个关键点&#xff1a; 2. 什么是LPR&#xff1f;2.1 专业解释2.2 通俗解释2.3 LPR的三个关键点&#xff1a; 3. MLF和LPR的关系4. 传导机制4.1 第一步&#xff1a;央行调整MLF4.2 第二步&#xff1a;银…

五. Redis 配置内容(详细配置说明)

五. Redis 配置内容(详细配置说明) 文章目录 五. Redis 配置内容(详细配置说明)1. Units 单位配置2. INCLUDES (包含)配置3. NETWORK (网络)配置3.1 bind(配置访问内容)3.2 protected-mode (保护模式)3.3 port(端口)配置3.4 timeout(客户端超时时间)配置3.5 tcp-keepalive()配置…