二维数组与指针

article/2025/8/21 19:20:38

转载自:https://www.cnblogs.com/chenyangyao/p/5222696.html

声明:本文为原创博文,如有转载,请注明出处。若本文有编辑错误、概念错误或者逻辑错误,请予以指正,谢谢。

     指针与数组是C/C++编程中非常重要的元素,同时也是较难以理解的。其中,多级指针与“多维”数组更是让很多人云里雾里,其实,只要掌握一定的方法,理解多级指针和“多维”数组完全可以像理解一级指针和一维数组那样简单。

     首先,先声明一些常识,如果你对这些常识还不理解,请先去弥补一下基础知识:

1、实际上并不存在多维数组,所谓的多维数组本质上是用一维数组模拟的。2、数组名是一个常量(意味着不允许对其进行赋值操作),其代表数组首元素的首地址。3、数组与指针的关系是因为数组下标操作符[],比如,int a[3][2]相当于*(*(a+3)+2) 。4、指针是一种变量,也具有类型,其占用内存空间大小和系统有关,一般32位系统下,sizeof(指针变量)=4。5、指针可以进行加减算术运算,加减的基本单位是sizeof(指针所指向的数据类型)。6、对数组的数组名进行取地址(&)操作,其类型为整个数组类型。7、对数组的数组名进行sizeof运算符操作,其值为整个数组的大小(以字节为单位)。8、数组作为函数形参时会退化为指针。

 一、一维数组与数组指针

      假如有一维数组如下:

  char a[3];

      该数组一共有3个元素,元素的类型为char,如果想定义一个指针指向该数组,也就是如果想把数组名a赋值给一个指针变量,那么该指针变量的类型应该是什么呢?前文说过,一个数组的数组名代表其首元素的首地址,也就是相当于&a[0],而a[0]的类型为char,因此&a[0]类型为char *,因此,可以定义如下的指针变量:  

  char * p = a;//相当于char * p = &a[0]

      以上文字可用如下内存模型图表示。

      大家都应该知道,a和&a[0]代表的都是数组首元素的首地址,而如果你将&a的值打印出来,会发现该值也等于数组首元素的首地址。请注意我这里的措辞,也就是说,&a虽然在数值上也等于数组首元素首地址的值,但是其类型并不是数组首元素首地址类型,也就是char *p = &a是错误的。

      前文第6条常识已经说过,对数组名进行取地址操作,其类型为整个数组,因此,&a的类型是char (*)[3],所以正确的赋值方式如下: 

  char (*p)[3] = &a;

      注:很多人对类似于a+1,&a+1,&a[0]+1,sizeof(a),sizeof(&a)等感到迷惑,其实只要搞清楚指针的类型就可以迎刃而解。比如在面对a+1和&a+1的区别时,由于a表示数组首元素首地址,其类型为char *,因此a+1相当于数组首地址值+sizeof(char);而&a的类型为char (*)[3],代表整个数组,因此&a+1相当于数组首地址值+sizeof(a)。(sizeof(a)代表整个数组大小,前文第7条说明,但是无论数组大小如何,sizeof(&a)永远等于一个指针变量占用空间的大小,具体与系统平台有关

二、二维数组与数组指针

      假如有如下二维数组:

  char a[3][2];

      由于实际上并不存在多维数组,因此,可以将a[3][2]看成是一个具有3个元素的一维数组,只是这三个元素分别又是一个一维数组。实际上,在内存中,该数组的确是按照一维数组的形式存储的,存储顺序为(低地址在前):a[0][0]、a[0][1]、a[1][0]、a[1][1]、a[2][0]、a[2][1]。(此种方式也不是绝对,也有按列优先存储的模式)

      为了方便理解,我画了一张逻辑上的内存图,之所以说是逻辑上的,是因为该图只是便于理解,并不是数组在内存中实际的存储模型(实际模型为前文所述)。

     

      如上图所示,我们可以将数组分成两个维度来看,首先是第一维,将a[3][2]看成一个具有三个元素的一维数组,元素分别为:a[0]、a[1]、a[2],其中,a[0]、a[1]、a[2]又分别是一个具有两个元素的一维数组(元素类型为char)。从第二个维度看,此处可以将a[0]、a[1]、a[2]看成自己代表”第二维”数组的数组名,以a[0]为例,a[0](数组名)代表的一维数组是一个具有两个char类型元素的数组,而a[0]是这个数组的数组名(代表数组首元素首地址),因此a[0]类型为char *,同理a[1]和a[2]类型都是char *。而a是第一维数组的数组名,代表首元素首地址,而首元素是一个具有两个char类型元素的一维数组,因此a就是一个指向具有两个char类型元素数组的数组指针,也就是char(*)[2]。

     也就是说,如下的赋值是正确的:

  char (*p)[2]  = a;//a为第一维数组的数组名,类型为char (*)[2]char * p = a[0];//a[0]维第二维数组的数组名,类型为char *

      同样,对a取地址操作代表整个数组的首地址,类型为数组类型(请允许我暂且这么称呼),也就是char (*)[3][2],所以如下赋值是正确的:  

  char (*p)[3][2] = &a;

===========================================================================

测试一下:

int v[2][3] = {{1,2,3}, {4,5,6}};
int (*a)[3] = v;cout << *a << endl;         // 1's addr
cout << (*a+1) << endl;	    // 2's addr
cout << (*a+2) << endl;	    // 3's addr
cout << *(*a+1) << endl;    // 2
cout << *(*a+2) << endl;    // 3
cout << *(a+1) << endl;	    // 4's addr
cout << **(a+1) << endl;    // 4


http://chatgpt.dhexx.cn/article/HrBu5svP.shtml

相关文章

二维数组指针,指针数组与数组指针的区别,一看就懂

目录 一.二维数组基本概念 二.指针数组和数组指针的区别 1.数组指针 2.指针数组 3.总结 三.二维数组的首地址和数组名 四.二维数组如何运用指针&#xff1f; 五.代码分析,加深了解。 一.二维数组基本概念 二维数组在概念上是二维的&#xff0c;有行和列&#xff0c;但在…

二维数组与数组指针详解

二维数组 深入理解二维数组 首先定义一个二维数组 int a[2][3]{{1,2,3},{4,5,6}}; #or int a[2][2]{1,2,3,4};新的理解&#xff1a;我们可以这样认为&#xff0c;a可以看作是一个一维数组&#xff0c;包含2个元素&#xff0c;每个元素恰好是包含3个整型的元素&#xff0c;a这个…

c语言——二维指针数组

1 一维度数组与指针 1.1一维数组元素在内存分布 #include<stdio.h> #include<stdlib.h> #include<string.h>#define ARRAY_SIZE 8void main() {int data[ARRAY_SIZE]{0,1,2,3,4,5,6,7};int i;printf("data address:0x%-8x\r\n",data);for(i0; i&l…

c++二维数组指针

&#xff11;.定义指针指向二维数组 为了方便根据用户输入动态定义二维数组的行和列&#xff0c;引入变量rowsNum(行)&#xff0c;colsNum(列&#xff09;。 以定义&#xff15;行&#xff14;列的二维数组为例&#xff0c; int rowsNum 4;int colsNum 5;float** a new fl…

二维数组名是指针的指针吗?

我们知道一维数组名是常量指针&#xff0c;我们可以将一维数组名赋给一个指针类型再对一维数组进行相关的操作&#xff0c;那二维数组名又是什么&#xff1f; 我们这样初始化一个二维数组int A[3][3]{1,2,3,4,5,6,7,8}或者为int A[3][3]{ {1,2,3},{4,5,6}&#xff0c;{7,8,9}}…

c++二维数组中指针详解

二维数组 a[2][3]{{1,2,3},{4,5,6}};指针p有如下几种表达形式&#xff1a; 1 方式一&#xff1a;int (*p)[3]a (或&a[0]&#xff09;; 一定要加上括号&#xff0c;因为[]的优先级高于*&#xff1b;意思是定义一个指向3个int类型变量的指针。p代表二维数组中第一个…

C语言 二维数组和指针

二维数组可以看成是元素为一维数组的数组&#xff0c;假设有一个三行四列的二维数组a&#xff0c;它定义为&#xff1a; int a[3][4] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; a 是二维数组名。a 数组包含 3 行&#xff0c;即 3 个行元素&#xff1a;a[0]&#xff0c;a[1]…

C/C++指向二维数组的指针

1. 二维数组 设有整型二维数组a[3][4]如下&#xff1a;     0 1 2 3     4 5 6 7     8 9 10 11   它的定义为&#xff1a;       int a[3][4]{{0,1,2,3},{4,5,6,7},{8,9,10,11}}  设数组a的首地址为1000&#xff0c;各下标变量的首地址及其值如图所…

二维数组与二级指针

关于二维数组与二级指针那些你必须知道的事 首先,来看一个例子一个error嗯,我是解析指针数组与数组指针 首先,来看一个例子 #include <iostream>using namespace std;int main(void) {int **p;pnew int*[5];for(int i0;i<5;i){p[i]new int[5];}return 0; }不严格地说…

C语言二维数组指针用法

目录 题目 背景概念梳理 一维线性 数组指针 指针步长 数组名与指向其的指针变量名等价 数组的初始化与取元素 数组指针转换关系 解题过程 选项A&#xff1a;* (( * prt1)[2]) 选项B&#xff1a;* ( * (p5)) 选项C&#xff1a;( * prt1)2 选项D&#xff1a; * ( * (…

二维数组指针表示,C语言指针引用二维数组详解

指针变量可以指向一维数组中的元素&#xff0c;当然也就可以指向二维数组中的元素。但是在概念和使用方法上&#xff0c;二维数组的指针比一维数组的指针要复杂一些。要理解指针和二维数组的关系首先要记住一句话&#xff1a;二维数组就是一维数组&#xff0c;这句话该怎么理解…

C语言二维数组指针(指向二维数组的指针)详解

声明&#xff01;本文转载仅为方便学习使用&#xff01; 如有需要&#xff0c;请访问C语言指针数组&#xff08;数组每个元素都是指针&#xff09;详解C语言二维数组指针&#xff08;指向二维数组的指针&#xff09;详解 二维数组在概念上是二维的&#xff0c;有行和列&#x…

c语言 二维数组指针

文章目录 前言一、二维数组指针的定义&#xff1a;二、二维数组指针遍历数组元素&#xff1a;总结 前言 前面我们讲了一维数组指针&#xff0c;今天我们讲一下二维数组指针。 一、二维数组指针的定义&#xff1a; 概述&#xff1a; 二维数组指针的定义就是把一维数组换成二维…

关于二维数组,二维数组指针

最近学习指针&#xff0c;一不小心就掉进了二维数组指针的坑里面&#xff0c;在迷惑了接近一个星期后&#xff0c;我有了以下的总结。&#xff08;希望有大佬看见了能指点指点&#xff0c;我也不知道这么理解到底对不对&#xff0c;虽然我觉得是对的&#xff09; 这是我一开始…

二维数组与指针的关系详解

静态二维数组与指针 我们定义一个二维数组int a[4][3]。 二维数组实际是由多个一维数组组成&#xff0c;在这里&#xff0c;a[3][4]就是由3个长度为4的一维数组组成的二维数组。并且它们在空间上是连续的&#xff0c;相当于一个长为12的一维数组。 这里a&#xff0c;a[i]全部…

二维数组与指针(详解)

如果对字符串和二维数组有基本概念可以直接跳去看他们的关系及使用 于4.3 00:08修改&#xff0c;改正了之前文章中错误的观点&#xff0c;修改了一些低级错误 欢迎大家在文章下留言 于21-05-19 22:37再次更新,前几天有个同学问了我这么个问题&#xff0c;我觉得是一个非常好的…

C/C++二维数组指针(指向二维数组的指针)详解

多维数组与指针 用指针变量可以指向一维数组中的元素&#xff0c;也可以指向多维数组中的元素。1) 多维数组元素的地址 设有一个二维数组 a&#xff0c;它有 3 行 4 列。它的定义为&#xff1a; int a[3][4]{{1,3,5,7},{9,11,13,15},{17,18,21,23}}; a 是一个数组名。a 数…

C语言 指针+二维数组详解 (应付期末、考研的最强笔记,建议收藏)

哈喽&#xff01;这里是一只派大鑫&#xff0c;不是派大星。本着基础不牢&#xff0c;地动山摇的学习态度&#xff0c;从基础的C语言语法讲到算法再到更高级的语法及框架的学习。更好地让同样热爱编程(或是应付期末考试 狗头.jpg)的大家能够在学习阶段找到好的方法、路线&#…

多任务Multitask Learning

一次只学习一个任务&#xff0c;大部分机器学习都属于单任务学习。 多任务学习&#xff1a;把多个相关的任务放在一起学习&#xff0c;同时学习多个任务。 对于复杂的问题&#xff0c;可以分解为简单的相互独立的子问题来解决&#xff0c;然后再合并结果&#xff0c;得到最初复…

Distral: Robust multitask reinforcement learning.

作者&#xff1a;张楚珩 链接&#xff1a;https://zhuanlan.zhihu.com/p/51091244 来源&#xff1a;知乎 著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。 中Distral是Distill & transfer learning的缩写。 原文传送门 Teh, Yee, et…