【C++】对数组指针的理解,例如 int (*p)[3]

news2024/9/29 21:20:08

目录

  • 简介
  • 思考
  • 理解
  • 结语

在这里插入图片描述

简介

Hello!
非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出~
 
ଘ(੭ˊᵕˋ)੭
昵称:海轰
标签:程序猿|C++选手|学生
简介:因C语言结识编程,随后转入计算机专业,获得过国家奖学金,有幸在竞赛中拿过一些国奖、省奖…已保研
学习经验:扎实基础 + 多做笔记 + 多敲代码 + 多思考 + 学好英语!
 
唯有努力💪
 
本文仅记录自己感兴趣的内容

思考

数组指针,指向数组的指针

int (*p)[3]

  • 首先括号里面是*p,说明p是一个指针,*只作用于p,对int无影响(因为有括号)
  • 所以数组大小为3,且里面的元素都是int类型

也就是,p是一个指针,指向含有三个int元素的数组

在这里插入图片描述


场景一:

int (*p)[3]
那么++p时,指针p是怎么移动的呢?

++p

那么每次p就会跨过3个int元素
在这里插入图片描述

举例分析:

#include<bits/stdc++.h>
using namespace std;
int main() {
    // 
    int a[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    int (*p)[3];
    p = (int (*)[3])a;
    cout << "p[0][0] = "<< p[0][0] << endl;// 1
    cout << "p[0][1] = "<<p[0][1] << endl;// 2
    cout << "p[0][2] = "<<p[0][2] << endl;// 3

    cout << "p[1][0] = "<<p[1][0] << endl;// 4
    cout << "p[1][1] = "<<p[1][1] << endl;// 5
    cout << "p[1][2] = "<<p[1][2] << endl;// 6

    cout << "p[2][0] = "<<p[2][0] << endl;// 7
    cout << "p[2][1] = "<<p[2][1] << endl;// 8
    cout << "p[2][2] = "<<p[2][2] << endl;// 9
    return 0;
}

运行结果:

在这里插入图片描述

代码解释:

  • int a[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; 构造一个一维数组,长度为9
  • int (*p)[3];,p是一个指向3个int类型元素的指针,也就是数组的指针->数组指针
  • p = (int (*)[3])a;,这里就很关键!
    • p一次只能指向含有3个int元素的数组
    • 但是a其中有9个元素
    • 所以此时其实可以想象为:p一次可以指向(代表)3个int,那么9个int,则需要3个p指针进行表示即可
    • 所以其实此时隐约有p[0],p[1],p[2],其中p[0]指向1,2,3,p[1]指向4,5,6…
    • 也就是若执行++p,其实p移动了3个int类型元素长度(跨了3个int类型)
    • 注:这里表述其实不太好,仅为个人理解过程

在这里插入图片描述

所以p[0][0]表示p[0]中3个元素的第一个元素,即p[0][0] = 1

如果++p,会发生什么呢?

#include<bits/stdc++.h>
using namespace std;
int main() {
    // 
    int a[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    int (*p)[3];
    p = (int (*)[3])a;
    cout << "p[0][0] = "<< p[0][0] << endl;// 1
    cout << "p[0][1] = "<<p[0][1] << endl;// 2
    cout << "p[0][2] = "<<p[0][2] << endl;// 3

    ++p;
    // 此时p一下移动了3个int元素的位置
    cout << "p[0][0] = "<< p[0][0] << endl;// 4
    return 0;
}

在这里插入图片描述
解释:++p,p每次会移动3个int类型的位置,因为p指向含有3个int类型元素的数组,那么每次移动,就是会跨过3个int元素

再修改一下:改为int (*p)[4];,也就是p指针一次可以指向4个元素

#include<bits/stdc++.h>
using namespace std;
int main() {
    // 
    int a[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    int (*p)[4];
    p = (int (*)[4])a;
    cout << "p[0][0] = "<< p[0][0] << endl;// 1
    cout << "p[0][1] = "<<p[0][1] << endl;// 2
    cout << "p[0][2] = "<<p[0][2] << endl;// 3
    cout << "p[0][3] = "<<p[0][3] << endl;// 4

    cout << "p[1][0] = "<<p[1][0] << endl;// 5
    cout << "p[1][1] = "<<p[1][1] << endl;// 6
    cout << "p[1][2] = "<<p[1][2] << endl;// 7
    cout << "p[1][3] = "<<p[1][3] << endl;// 8 

    cout << "p[2][1] = "<<p[2][0] << endl;// 9
    return 0;
}

结果:

在这里插入图片描述
在这里插入图片描述


场景二:在二维数组中呢

#include<bits/stdc++.h>
using namespace std;
int main() {
    int a[4][4];
    for(int i = 0; i < 4; ++i) {
        for(int j = 0; j < 4; ++j) {
            a[i][j] = i * 4 + j + 1;
        }
    }
    int (*p)[4];
    p = (int (*)[4])a;
    cout << "p[0][0]= " << p[0][0] << endl;// 1
    cout << "p[0][1]= " << p[0][1] << endl;// 2
    cout << "p[0][2]= " << p[0][2] << endl;// 3
    cout << "p[0][3]= " << p[0][3] << endl;// 4

    cout << "p[1][0]= " << p[1][0] << endl;// 5
    cout << "p[1][1]= " << p[1][1] << endl;// 6
    cout << "p[1][2]= " << p[1][2] << endl;// 7
    cout << "p[1][3]= " << p[1][3] << endl;// 8
    return 0;
}

在这里插入图片描述

其实和一维数组差不多,因为二维数组在内存也是顺序存储的(这里按照行存储)

在这里插入图片描述

修改一下:int (*p)[3];

#include<bits/stdc++.h>
using namespace std;
int main() {
    int a[4][4];
    for(int i = 0; i < 4; ++i) {
        for(int j = 0; j < 4; ++j) {
            a[i][j] = i * 4 + j + 1;
        }
    }
    int (*p)[3];
    p = (int (*)[3])a;
    cout << "p[0][0]= " << p[0][0] << endl;// 1
    cout << "p[0][1]= " << p[0][1] << endl;// 2
    cout << "p[0][2]= " << p[0][2] << endl;// 3
    cout << endl;
    cout << "p[1][0]= " << p[1][0] << endl;// 4
    cout << "p[1][1]= " << p[1][1] << endl;// 5
    cout << "p[1][2]= " << p[1][2] << endl;// 6
    return 0;
}

运行结果:

在这里插入图片描述

其实理解就想成每三个元素为一组,进行不断划分就好了(画图帮助自己理解)
在这里插入图片描述

理解

记住:

  • 数组指针,是一个数组的指针,指向一个数组
  • 无论是一维还是二维,反正就是按照数组大小进行划分为多个组,每次++或者--,要跨过n个元素

结语

文章仅作为个人学习笔记记录,记录从0到1的一个过程

希望对您有一点点帮助,如有错误欢迎小伙伴指正

在这里插入图片描述

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

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

相关文章

Win7 无法安装 VMware Tools 解决方法

文章目录 1.下载kb4474419补丁2.虚拟机 > 设置 > 软盘&#xff0c;选中“使用物理驱动器”3.解决IE浏览器只能访问百度4.下载windows iso的正确方式 win7版本&#xff1a;cn_windows_7_ultimate_with_sp1_x64_dvd_u_677408_2&#xff08;iso大小3.18 GB&#xff09; vmwa…

C++内联函数(编译器角度,汇编角度),auto关键字,范围for语法糖,nullprt与NULL区别等

TIPS 在C当中有一个东西可以打印类型&#xff1f;typeid(变量名).name()数组一旦从参数进入到函数里面&#xff0c;它就已经是个指针了&#xff0c;再也不是一整个数组了 内联函数&#xff08;正常函数定义前加个inline修饰&#xff09; 在实际当中&#xff0c;有时候去调用…

13、拦截器

文章目录 1、HandlerInterceptor 接口2、配置拦截器3、拦截器原理 【尚硅谷】SpringBoot2零基础入门教程-讲师&#xff1a;雷丰阳 笔记 路还在继续&#xff0c;梦还在期许 1、HandlerInterceptor 接口 /*** 登录检查* 1、配置好拦截器要拦截哪些请求* 2、把这些配置放在容器中…

爬虫——肯德基

import requests #UA伪装&#xff1a;将对应的User-Agent封装到一个字典中 headers{User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 Edg/112.0.1722.48 } #指定url url http://www.kfc.com.c…

【jvm系列-09】垃圾回收底层原理和算法以及JProfiler的基本使用

JVM系列整体栏目 内容链接地址【一】初识虚拟机与java虚拟机https://blog.csdn.net/zhenghuishengq/article/details/129544460【二】jvm的类加载子系统以及jclasslib的基本使用https://blog.csdn.net/zhenghuishengq/article/details/129610963【三】运行时私有区域之虚拟机栈…

一图看懂 xlrd 模块:读写 Excel 文件的数据和格式信息, 资料整理+笔记(大全)

本文由 大侠(AhcaoZhu)原创&#xff0c;转载请声明。 链接: https://blog.csdn.net/Ahcao2008 一图看懂 xlrd 模块&#xff1a;读写 Excel 文件的数据和格式信息, 资料整理笔记&#xff08;大全&#xff09; 摘要模块图类关系图模块全展开【xlrd】统计常量intdict 模块26 os27 …

【蓝桥杯省赛真题19】python完数及个数 青少年组蓝桥杯python编程省赛真题解析

目录 python完数及个数 一、题目要求 1、编程实现 2、输入输出 二、解题思路

itop-3568开发板驱动学习笔记(22)设备树(一)设备树基础

《【北京迅为】itop-3568开发板驱动开发指南.pdf》 学习笔记 文章目录 设备树简介设备树编译设备树语法设备根节点设备子节点节点名称reg 属性#address-cell 和 #size-cells 属性model 属性status 属性compatible 属性aliases 节点chosen 节点device_type 属性自定义属性 设备树…

使用Docker创建并运行Jenkins详细步骤

文章目录 一、使用Docker搭建Jenkins二、为Jenkins配置执行节点1、进入管理页面2、新建节点3、配置节点信息4、子节点连接master节点5、在子节点机器上运行上面复制下来的命令6、查看子节点是否在线 三、创建一个简单的job1、进入创建页面2、设置job名称3、配置job相关信息4、构…

eBay变现方式有哪些?如何利用好测评自养号?

近年来&#xff0c;越来越多的人选择在eBay开店&#xff0c;甚至很多其他平台的卖家也转型到了eBay。但很多卖家发现&#xff0c;在运营了一段时间后&#xff0c;过了对新账号的流量扶持期&#xff0c;店铺突然出现流量开始下滑的情况&#xff0c;针对这种情况卖家可以采取哪些…

计算机网络(数据链路层)部分习题

1. 通过传统以太网发送中文“华南师范大学计算机学院”&#xff0c;封装成以太网帧&#xff0c;请问该帧的数据字段有效字节是多少&#xff1f;需要填充多少个字节&#xff1f; 答&#xff1a;一个字两个字节&#xff0c;“华南师范大学计算机学院”共11个字&#xff0c;有效字…

Visual Studio容器工具要求在构建,调试或运行容器化项目之前运行Docker

出现此提示&#xff0c;是因为电脑未安装Docker所致&#xff0c;接下来就教大家如何安装Docker。 第一步&#xff1a;下载 地址&#xff1a;Install Docker Desktop on Windows | Docker Documentation 第二步&#xff1a;安装 1、双击Docker Desktop Installer.exe运行安装程…

电子束与材料相互作用Matlab代码

标题 1 题目2 实验原理2.1 蒙特卡洛模拟的基本思想2.2 电子散射的基本概念 3 代码 1 题目 扫描透射电镜(STEM)的基本原理是用极细的扫描电子束透射样品,透射电子直接被具有一定张角的接收器所接收&#xff0c;透射电流的强度直接反应了样品的质量厚度。 对于一定厚度的样品&am…

面试官:一千万的数据,你是怎么查询的?

面试官&#xff1a;一千万的数据&#xff0c;你是怎么查询的&#xff1f; 1 先给结论 对于1千万的数据查询&#xff0c;主要关注分页查询过程中的性能 针对偏移量大导致查询速度慢&#xff1a; 先对查询的字段创建唯一索引 根据业务需求&#xff0c;先定位查询范围&#xff08…

23Java面试专题 八股文面试全套真题(含大厂高频面试真题)

准备篇-01-企业简历筛选规则 准备篇-02-简历注意事项 等写简历的时候看02和04... 准备篇-03-应届生该如何找到合适的练手项目 &#xff01;准备篇-04-Java程序员的面试过程 Redis篇-01-redis开篇 感觉有点难 Redis篇-02-redis使用场景-缓存-缓存穿透 Redis篇-03-redis使用场景-…

一日一题:第十题---并查集(集合合并)and 二叉树遍历

​作者&#xff1a;小妮无语 专栏&#xff1a;一日一题 &#x1f6b6;‍♀️✌️道阻且长&#xff0c;不要放弃✌️&#x1f3c3;‍♀️ 今天来更前几天做的&#xff0c;怕忘记了hh 目录 并查集题目描述(集合合并)代码对路径压缩的解释 二叉树遍历题目描述代码 并查集 ​​​…

【JavaEE】死锁是什么?如何避免死锁(保姆级讲解)

博主简介&#xff1a;想进大厂的打工人博主主页&#xff1a;xyk:所属专栏: JavaEE初阶 本篇文章将介绍什么是死锁&#xff0c;死锁的四大必要条件&#xff0c;如何去避免死锁~~~ 目录 一、死锁是什么&#xff1f; 二、关于死锁的情况 2.1 一个线程的情况 2.2 两个线程的情…

javaweb家具购物商城的电商设计与实现

目 录 1 绪论 1 1.1 项目背景 1 1.2 研究意义 1 1.3 本系统概述 2 2系统分析 3 2.1 系统需求分析 3 2.1.1 功能需求 3 2.1.2 性能需求 4 2.2 系统可行性分析 4 2.2.1 技术及开发方法可行性 4 2.2.2 管理可行性 4 2.2.3 经济可行性 5 2.3 业…

CPU的一、二、三级缓存

在Java并发编程中&#xff0c;我们经常会遇到共享变量的读写问题&#xff0c;关于这类问题我们经常会说到原子性、可见性、有序性这三大特性&#xff0c;再进一步会了解到总线和CPU的一、二、三级缓存。关于这三个级别的缓存网上文章介绍比较多&#xff0c;今天我们这篇文章&am…

Django REST Framework(DRF)框架之其他常用API的使用

DRF之其他常用API的使用 限流Throttling限流类设置全局默认限流策略基于类视图限流定义限流频次自定义限流类 过滤Filtering查询集过滤查询参数过滤使用过滤器组件使用过滤器字段过滤字段排序 分页Pagination常用分页类全局与局部的使用自定义分页类 异常处理Exceptions常见异常…