c++高级---C/C++二维数组---与指针的关系

C++的二维数组 在 C++ 中,二维数组是一种常用的数据结构,它可以看作是数组的数组,类似于数学中的矩阵。以下将从定义、初始化、访问元素、内存布局和使用示例等方面详细介绍 C++ 中的二维数组。二维数组的一般定义语法如下:数据类型 数组名[行数][列数];其中,数据类型 可以是任意有效的 C++ 数据类型,如 int、double、char 等;数组名是用户为数组取的名称;行数 和 列数 分别表示数组的行数和列数,它们必须是常量表达式。示例:// 定义一个3行4列的二维整数数组。 阅读详情

先上实例:

#include "stdafx.h"
#include <iostream>

int _tmain(int argc, _TCHAR* argv[])
{
 int v[2][10] = {{1,2,3,4,5,6,7,8,9,10},{11,12,13,14,15,16,17,18,19,20}};
 int (*a)[10] = v; //数组指针
 std::cout<<a<<std::endl;
 std::cout<<*a<<std::endl;
 std::cout<<**a<<std::endl;
 std::cout<<a[0]<<std::endl;
 std::cout<<std::endl;

//-------------------------------------------------------
 std::cout<<a+1<<std::endl;
 std::cout<<*(a+1)<<std::endl;
 std::cout<<**(a+1)<<std::endl;
 std::cout<<std::endl;

//-------------------------------------------------------
 std::cout<<(*a+1)<<std::endl;
 std::cout<<*(*a+1)<<std::endl;
 std::cout<<std::endl;

//-------------------------------------------------------
 std::cout<<(a[0]+1)<<std::endl;
 std::cout<<*(a[0]+1)<<std::endl;
 std::cout<<*(a[1])<<std::endl;
 //std::cout<<**(a[1])<<std::endl;
 return 0;
}

运行结果:

 

下面是收集的一些二维数组和指针的知识

参考:http://blog.youkuaiyun.com/yangchang999/article/details/6664069

很多C++/C初学者对于二维数组与指针的关系总是搞不清楚,对它的误解比比皆是。一下是本人的一些总结,部分内容参考相关资料,希望对大家的理解有所帮助。(本文对于C/C++而言)

首先,我们先从存储的角度对二维数组作一个全面的了解。二维数组在内存中的存储,是按照先行后列依次存放的。从内存的角度看,可以这样说,二维数组其实就是一个一维数组,在内存中没有二维的概念。如果把二维数组的每一行看成一个整体,即看成一个数组中的一个元素,那么整个二维数组就是一个一维数组,它以每一行作为它的元素,这个应该很好理解。

第一,我们来详细介绍二维数组与指针的关系。

首先定义个二维数组 array[3][4],p 为指向数组的指针。

若p=array[0],此时p指向的是二维数组第一行的首地址,则p+i将指向array[0]数组中的元素array[0][i]。由以上所介绍的二维数组在内存中的存储方式可知,对数组中的任一元素array[i][j],其指针的形式为:p+i*N+j(N为每一行的长度)。元素相应的指针表示法为:*(p+i*N+j),下标表示法为:p[i*N+j] 。

For Example:

array[4][3]={{1,2,3},{4,5,6},{7,8,9},{10,11,12}};

int * p=array[0];

数组array有四个元素,分别为array[0],array[1],array[2],array[3],每个元素为包含3个元素的一维数组,

如array[0]的3个元素为 array[0][0],array[0][1],array[0][2]。

元素array[2][2]对应指针为:array+2*3+2,

指针表示法为:*(array+2*3+2) , 

下标表示法为:array[2*3+2] 。

特别注意:虽然array[0]与array都是数组首地址,但两者指向的对象不同,这点要非常明确。array[0] 是一维数组的名字,它指向的是一维数组array[0]的首地址,所以 *array[0]与array[0][0]为同个值。而 array 是二维数组的名字,它指向的是所属元素的首地址,其每个元素为一个行数组。它是以‘行’来作为指针移动单位的,如array+i 指向的是第 i 行。对 array 进行 * 运算,得到的是一维数组 array[0] 的首地址,所以 *array 与 array[0] 为同个值。如果定义 int* p,p为指int类型的指针,指向int 类型,而不是地址。故以下操作 :p=array[0] (正确) ,p=array (错误) 。这点要非常注意。

【经测试输出array、array[0]与输出*array都是同一个值,都是整个二维数组第一个元素地址值,虽然变量array和array[0]以及*array的值一样,但他们的类型不一样,array指向一个大类型(大内存块),而array[0]和*array指向大类型内部的一个小类型(小内存块)。array[0]和*array这两个东西是一模一样的,值和类型都一样。】

【另外要注意也是需要死记硬背的东西是,array虽然指向一个大内存块的首地址(数组的首地址),但*array和array[0]的结果并不是返回整个大内存块内存放的内容(大数组),比如并不返回整个3个int元素,而是返回大内存块内部的小内存块的首地址(其实就是返回一个小数组),也即是只需要记住array是一种大类型的地址,而*array和array[0]仍然是一个地址,只不过类型是小类型而已,仅仅只是类型变了而已,值是不变的,至于为什么估计是编译器特殊实现了吧。】。

 

第二,看看如何用数组名作地址表示其中元素。

我们知道,对二维数组array,array[0]由array指向,故*array 与array[0] 是相同的,依次类推可得 array[i] 由array+i 指向,*(array+i) 与array[i]是相同的。 因此,对于数组元素 array[i][j] ,用数组名表示为 *(*(array+i)+j) ,指向该元素的指针为 *(array+i)+j 。

注意:数组名虽然是地址,但与指向数组的指针性质不同。指针变量可以随时改变其所指向对象,而数组名不可以,一旦被定义,就不能通过赋值使其指向另外一个数组,但是在Java中则可以。

 

第三,顺便了解一下不太常用的‘行数组指针’。

我们知道,对于二维数组array[4][3],与int* p 。二维数组名array 不能直接赋值给p。原因前面已讲过,两只的对象性质不同【类型不同】。在C语言中,我们可以通过定义一个行数组指针,使得这个指针与二维数组名具有同样的性质,实现它们之间可以直接赋值。行数组指针定义如下:

int (*p)[3]; 它表示,数组 *p 具有三个int类型元素,分别为 (*p)[0] , (*p)[1] , (*p)[2] ,即 p指向的是具有三个int类型的一维数组,也就是说,p为行指针。此时,以下运算 p=array 是正确的。

【int (*p)[3]中的小括号作用只是为了改变优先级,不加括号由于中括号优先级高于*号就变成了int* p[3],即一个一纬数组,每个元素都是int*类型的。】

【可以向c#那样把int (*p)[3]改成int[3] *p就好理解了。】

第四,二维数组作为函数参数。

二维数组作为函数参数一般有两种方式:(1) void func(int **array){...}   (2) void func(int array[ ][N])

注意第二种方式一定要指明二维数组的列数

当二维数组名作为函数实参时,对应的形参必须是一个行指针变量。

和一维数组一样,数组名传送给变量的是一个地址值,因此,对应的形参也必须是一个类型相同的指针变量,在函数中引用的将是主函数中的数组元素,系统只为形参开辟一个存放地址的存储单元,而不可能在调用函数时为形参开辟一系列存放数组的存储单元。

int main()

       double a[3][4];

       ……

       fun(a);

       ……

fun(double (*a)[n])

       ……

C/C++指针详解之提高篇(史上最全最易懂指针学习指南!!!!) 目录 一. 堆空间与指针的相爱相杀 1.1 堆上一维空间 1.1.1 返回值返回(一级指针) 1.1.2 参数返回(二级指针) 1.2堆上二维空间 1.2.1指针作返值输出 1.2.2 空间申请与释放 1.2.3 多级指针作参数输出 1.2.4 具体实例之序列加密 二. const修饰指针 1.1const 修饰变量 1.2 const 修饰指针 1.3co... 阅读详情

相关推荐

掌握C++二级指针与二维数组的值操作

二级指针是C/C++等高级语言中的一个重要概念,它是一种指向指针的指针,能够存储并操作另一个指针的地址。理解二级指针对于深入掌握指针操作以及动态内存管理至关重要。断点调试是开发者利用调试工具在代码中的关键位置设置断点,让程序运行至断点处暂停执行的一种调试方法。通过逐步执行或监视程序的运行状态,开发者可以详细地观察程序的行为和变量的变化,从而理解代码逻辑,定位和修正问题。常见的断点调试工具有GDB(GNU Debugger)、LLDB(LLVM Debugger)、Visual Studio的调试器等。

weixin_42360846的博客 854

C++学习6(二维数组)

#include <iostream> using namespace std; #include <string> int main() { //二维数组的定义方式 /*1.数据类型 数组名[行数][列数]; 2.数据类型 数组名[行数][列数]={{数据1,数据2},{数据3,数据4}...} 3.数据类型 数组名[行数][列数]={数据1,数据2,数据3,数据4...} 4.数据类型 数组名[][列数]={数据1,数据2,数据3,数据4...}*/ cou

henu@wyx南念 1479

C++ 数组 多维数组 -- 二维数组

数组的概念和定义 一维数组 多维数组 -- 二维数组 字符型数组和字符串型数组

C++中string二维数组的介绍

因为数据类型是字符串,所以各个元素的长短不一致也没关系,输出元素,看好行和列就好了!这个数据类型的二维数组,定义和使用都很简单,看案例。看输出结果-----

jsjsjejsj的博客 3507

基于迁移学习的花卉识别系统

本研究采用了预训练的经典深度学习模型,包括ResNet、AlexNet和VGG,通过微调的方式在Oxford-102数据集和一个自制花卉数据集上进行训练,并对图像进行了多种数据增强操作,以提高模型的泛化能力,致力于实现花卉的高效分类。

m0_71146337的博客 2375

linux redis7 完整的集群搭建过程

一。安装: 1.1 说明: Redis官方只提供了源码,并没有提供经过编译之后的安装包。 因此,安装Redis,要先编译、后安装。(即源码安装方式) 注意:需要联网安装 1.2 安装编译的工具: yum install gcc gcc-c++ -y 1.3 下载tar包,上传到linux服务器,解压配置环境变量 1.4 cd +解压的目录下:编译 make 注意:如果编译失败,请重新进行解压编译,...

m0_38028438的博客 719

C++中的二维数组

C++中的二维数组,二维数组定义,二维数组数组名,二维数组案例——考试成绩统计。

m0_48873188的博客 1557

EPS+ArcGIS+CASS三剑客:等高线裁剪的完整工作流与避坑指南

本文详细介绍了EPS、ArcGIS和CASS三款软件在等高线裁剪中的协同工作流程与避坑指南。通过发挥各软件优势,解决数据完整性、拓扑准确性和流程可靠性等核心挑战,提升40%以上的工作效率。特别适合大型测绘项目中复杂地形的处理,涵盖数据准备、核心处理到后期优化的全流程。

weixin_30352645的博客 617

C++实现二维字符串数组

最近有个需求,要利用c++实现一个二维的字符串数组,网上查了下,竟然没找到 因为c++的string用起来感觉非常繁琐,所以还是决定利用char型指针来做这个功能 思路是二维数组里存的都是一维数组,一维数组里存char* 所以解决方案如下: const char* getContent(int row,int column){ const char* temp1[] =

lindir的专栏 2万+

第4课 SiC MOSFET的动态特性——关断过程

本文分析了SiC MOSFET的关断过程,将其划分为四个阶段:栅源电容放电阶段(t6-t7)、米勒平台阶段(t7-t8)、电压过冲阶段(t8-t9)和换流结束阶段(t9-t10)。通过等效电路详细描述了各阶段的电压电流变化特点。同时探讨了MOSFET的极间电容特性,包括输入电容Ciss、输出电容Coss和反向转移电容Crss,分析了它们对器件开关速度、损耗及电压变化速率的影响。研究指出这些非线性电容会显著影响器件的动态性能。

嵌入式老牛的博客 1044

Selenium ChromeDriver反爬与性能优化实战指南

ChromeDriver作为Selenium的核心驱动,本质是浏览器自动化执行引擎,其默认行为会暴露大量JS运行时指纹(如navigator.webdriver、window.chrome),极易被前端反爬系统识别;同时因进程管理粗放、渲染等待机制僵化,导致内存泄漏、僵尸进程和高并发下稳定性崩塌。本文围绕真实生产场景,系统解析浏览器指纹伪造原理、进程级资源管控策略、基于页面状态的智能等待范式,并提供Docker容器化、K8s弹性扩缩与Prometheus可观测性落地路径,助力开发者将ChromeDriver

weixin_29762151的博客 1259

C/C++ 指针详解与各种指针定义

本文系统讲解了C/C++指针的概念与应用,从基础定义到复杂用法逐步深入。主要内容包括:指针的基本概念与作用;各种指针类型的声明方法(如指针数组、数组指针、函数指针等);指针与数组的关系,特别是二维数组的指针运算;函数指针在qsort等场景的实际应用;多级指针的使用场景。文章通过大量示例和规律总结,帮助读者掌握指针这一核心概念,强调理解指针的关键在于从变量名往外读并结合括号优先级,同时提供了二维数组地址运算表等实用工具。

shark_dev的博客 1201

什么是 SAP Build Process Automation?

SAP Build Process Automation 是一款综合性的低代码工具,允许企业用户快速开发和自动化端到端业务流程。它整合了工作流管理、任务自动化和人工智能技术,提供了一个易于使用的平台,帮助企业更好地应对现代商业挑战。通过该工具,用户无需具备深厚的编程技能即可创建复杂的业务流程。例如,用户可以使用直观的拖放式界面设计流程、设置触发条件、定义任务分配规则,并通过内置的分析功能对流程效率进行评估。流程建模与设计:提供图形化界面,帮助用户直观地设计业务流程。任务自动化。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1257

指针数组和数组指针

C/C++语言中的指针变量可以指向任何类型的对象,baokuo

拉姆塞的专栏 554

《网络安全自学教程》- MySQL脱库原理和步骤

MySQL脱库,脱库的原理,怎么脱库,脱库的步骤,一库三表六字段

wangyuxiang946的博客 1万+

JAVA:Spring Boot 集成 Baidu UID-Generator ID 生成器

百度UID-Generator是一款高性能分布式ID生成器,支持600万QPS,提供Snowflake扩展版和Cache模式两种实现方式。文章详细介绍了如何在Spring Boot项目中集成该组件,包括Maven依赖配置、MySQL表结构初始化、Spring Boot数据源配置、WorkerId分配策略实现以及UID生成器的核心配置。该方案具有无中心依赖、ID单调递增、支持集群部署等特点,适用于订单号、用户ID等分布式场景。通过缓存模式(Cache-Buffer)可进一步提升性能,满足高并发业务需求。

木头 487

第26节 多维数组和多维指针

-------------------------------------资源来源于网络,仅供自学使用,如有侵权,联系我必删. 第一: 指向指针的指针 ? 指针变量在内存中会占用一定的空间 ? 可以定义指针来保存指针变量的地址值 int main() { int a = 0; int* p = NULL; int** pp = NULL; pp = &...

一名从事物联网开发者的博客 136

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

指针(二)

指向一维整型数组的指针,修饰的是数组的数据类型。int a[10];不能int *p;p = &a;int *p[10];定义了一个长度为10的指针数组,int(*p)[10],这个才是指向一维数组的数组指针。

2401_84308772的博客 479

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

C/C++指针、函数、结构体、共用体

到此这篇关于C/C++指针、函数、结构体、共用体的文章就介绍到这了。两个指针同时指向一个数组。++ 、--、比较、关系、&、*数组存放指针,指针指向函数,函数返回值是指针类型。这里代码体现什么是指针常量什么是指针变量?指针是指向某块地址。指针(地址)是常量。变量名就是你抽象出来的某块空间的别名。都是8字节,linux 64 位中。类型 (*数组名[下标])(形参);a是数组名字是一个表示地址的常量。变量是对某一块空间的抽象命名。指针变量是可以发生变化的。返回值 * 函数名(参数)函数与指针关系的详细剖析。

m0_74824865的博客 20

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

C/C++程序设计(十二)—— 指针(二):指针进阶

定义 12.2.1(指针数组):一个数组,其每个元素都是指针,称为指针数组。类型 *数组名[元素个数];这里week是含 7 个指针的数组,每个指针指向一个字符串字面量。形式化描述:设数组元素类型为T∗T^{*}T∗,元素个数为nnnweekT∗;nweeki∈T∗即"数组的每个槽里放的是一个指针"。定义 12.3.1(数组指针):指向"整个数组"的指针(而不是指向首元素的普通指针),称为数组指针。

theperson1的博客 57

必看,C/C++学习路线,C++基础到高级方法指南

C/C++学习路线之C++基础到高级方法指南 C/C++遍布的领域有后端服务器,移动互联网后端,经典Windows界面开发,移动互联网端界面开发,跨平台界面开发,图形分析,系统架构,应用设计,还有现在最为流行的分布架构等一些新的技术领域。所以说:C/C++俨然已成为一门贵族语言,成为了编程界最重要的语言之一。   C/C++入门阶段 刚入门的时候我们主要是学习培养编程思维和动手能力,深刻理...

7564

C/C++ 中指针的本质(2)——指针之高级篇

【指针之高级篇】 基于上篇的理解,再继续深入学习下指针。 1.    指向指针的指针 既然指针也是占据内存空间的,那指针也就是有地址的了,那么对于指针的地址又是存放到哪里呢?——指向指针的指针。 首先假设程序中有这样一个变量:int weight = 60; 那么指向该int类型数据的指针的定义:int *pWeight = &weight; 指向pWeight的指针(指向指针的指针)

yaodongwei00的专栏 1112

C语言指针数组和数组指针详解

C语言文章更新目录 C语言学习资源汇总,史上最全面总结,没有之一 C/C++学习资源(百度云盘链接) 计算机二级资料(过级专用) C语言学习路线(从入门到实战) 编写C语言程序的7个步骤和编程机制 C语言基础-第一个C程序 C语言基础-简单程序分析 VS2019编写简单的C程序示例 简单示例,VS2019调试C语言程序 C语言基础-基本算法 C语言基础-数据类型 C语言中的输入输出函数 C语言流程控制语句 C语言数组——一维数组 C语言数组——二维数组 C语言数组——字符数组 C语言中常用的6个字符串处理函

专注于C语言编程干货分享 5674

C/C++指针整理(C部分)

C/C++指针整理(C部分) 文章目录C/C++指针整理(C部分)1.什么是指针1.1指针的大小1.2指针的声明和类型及解引用1.3指针的运算1.3.1指针+-整数1.3.2指针+-指针2.什么是野指针2.1野指针的成因2.1.1指针未初始化2.1.2指针越界访问2.1.3指针指向的内存释放了2.1.3.1函数栈帧中在栈上的内存2.1.3.2堆上的内存释放2.2规避野指针的方法3.指针和数组的关系3.1**结论**3.2数组名和数组首元素的地址3.3 数组名VS&数组名4.二(多)级指针5.指针数组

代码笔记本 1052

C++ 指针常见用法小结

本文主要面向 C++ 初学者。 指针在 C\C++ 语言中是很重要的内容,并且和指针有关的内容一向令初学者头大。在本教程中,我总结了一些关于指针和数组的用法(尤其是指针和二维数组)。初学者经常遇到的很多关于指针和数组的问题应该可以在本文找到答案。 本场 Chat 只有文章,没有交流。...

GitChat 9860

C/C++指针&智能指针一

本文主要讲解了指针的基础概念以及使用,通过这篇文章一定会增加你对指针的认识和理解。

weixin_73497355的博客 1322
上一篇: 设计模式总结
下一篇: c++基础---C++之Static
HNFXS985
博客等级 码龄14年 219粉丝 150原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值