c语言——二维指针数组

article/2025/8/21 19:08:54

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(i=0; i<ARRAY_SIZE; i++){printf("data[%-3d]:value %-3d,address:0x%-10x\r\n",i,data[i],&data[i]);}	
    }data address:0xbc4100d0
    data[0  ]:value 0  ,address:0xbc4100d0  
    data[1  ]:value 1  ,address:0xbc4100d4  
    data[2  ]:value 2  ,address:0xbc4100d8  
    data[3  ]:value 3  ,address:0xbc4100dc  
    data[4  ]:value 4  ,address:0xbc4100e0  
    data[5  ]:value 5  ,address:0xbc4100e4  
    data[6  ]:value 6  ,address:0xbc4100e8  
    data[7  ]:value 7  ,address:0xbc4100ec 

结论为:
1 数组元素的地址是线性的、连续的,这也是可以通过数组地址找到所有元素的原因。
2  数组名代表数组指针,同时与首元素的地址相同

1.2一维数组的指针

#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 *pointer=data;int i;printf("data address:0x%-8x\r\n",data);for(i=0; i<ARRAY_SIZE; i++){printf("data[%d]:value %-3d,address:0x%-10x\r\n",i,data[i],&data[i]);}	for(i=0; i<ARRAY_SIZE; i++){printf("[%d]:value %-3d,address:0x%-10x\r\n",i,*(pointer+i),pointer+i);}	 
}data address:0x13bca160
data[0]:value 0  ,address:0x13bca160  
data[1]:value 1  ,address:0x13bca164  
data[2]:value 2  ,address:0x13bca168  
data[3]:value 3  ,address:0x13bca16c  
data[4]:value 4  ,address:0x13bca170  
data[5]:value 5  ,address:0x13bca174  
data[6]:value 6  ,address:0x13bca178  
data[7]:value 7  ,address:0x13bca17c  
[0]:value 0  ,address:0x13bca160  
[1]:value 1  ,address:0x13bca164  
[2]:value 2  ,address:0x13bca168  
[3]:value 3  ,address:0x13bca16c  
[4]:value 4  ,address:0x13bca170  
[5]:value 5  ,address:0x13bca174  
[6]:value 6  ,address:0x13bca178  
[7]:value 7  ,address:0x13bca17c 

结论为:
         1 指向数组的指针加一表示加上每个元素的字节数
          2 指针可以引用一个数组

2 二维度数组与指针

2.1 二维数组元素在内存分布

#include<stdio.h>
#include<stdlib.h>
#include<string.h>#define ARRAY_X 7
#define ARRAY_Y 5void main()
{int data[ARRAY_X][ARRAY_Y]={0};int *pointer=data;int i,j,k,num=0;;for(i=0; i<ARRAY_X; i++){for(j=0;j<ARRAY_Y;j++){data[i][j]=num;}   } 	 for(i=0; i<ARRAY_X;i++){printf("\r\n");for(j=0;j<ARRAY_Y;j++){data[i][j]=num;printf("data[%d][%d]:%d,(address:0x%-10x)\r\n",i,j,data[i][j],&data[i][j]);}	 }	     
}data[0][0]:0,(address:0xfe8a3a10  )
data[0][1]:0,(address:0xfe8a3a14  )
data[0][2]:0,(address:0xfe8a3a18  )
data[0][3]:0,(address:0xfe8a3a1c  )data[1][0]:0,(address:0xfe8a3a20  )
data[1][1]:0,(address:0xfe8a3a24  )
data[1][2]:0,(address:0xfe8a3a28  )
data[1][3]:0,(address:0xfe8a3a2c  )data[2][0]:0,(address:0xfe8a3a30  )
data[2][1]:0,(address:0xfe8a3a34  )
data[2][2]:0,(address:0xfe8a3a38  )
data[2][3]:0,(address:0xfe8a3a3c  )
root@ubuntu:Array# 


 通过实际的地址信息,可以知道:二维数组在内存中是连续发布的,第0行的第一个元素->第0行的最后一个元素->第1行的第1个元素->第1行的最后一个元素,以次类推,地址增长

 

2.2二维数组的指针

2.2.1指针的使用方法

声明一个二维数组 :int data[3][4]
 1 根据”数组名同时是数组首元素的地址“的原则,data是首元素的地址,二维数组data[3][4]的首元素是一维数组,所以data是一维数组data[0]的地址
 2 根据”数组名同时是数组首元素的地址“的原则,因此data的值等于&data[0],data[0]表示数组data[3][4]的首元素,这个首元素也是数组。根据“数组名同时是数组首元素的地址”的原则,data[0] 等于&data[0][0]
 3 根据“指针加1等于加上指针所指向的元素的大小“的原则,data+1并不等于data[0]+1,前者是4个单位,后者是1个单位“
 4 对一个指针取值得到的是该指针所指向对象的数值。data[0]表示一维数组data[0]的首元素即data[0][0]的地址,则*(data[0])表示元素data[0][0]的值

2.2.2 指针、指针的指针、变量

声明一个二维数组 :int data[3][4]

本例中,哪些是一维数组指针,哪些是二维数组指针,哪些是元素值?
  二维数组指针:data
  一维数组指针:data[0]、data[1]、data[2]
  元素值:data[0][0]、data[0][1]、data[0][2]、data[0][3]

  c语言中,*号表示取值,&号表示取地址,按照原则,可以知道:
    data 是二维数组指针,*data是二维数组的元素即一维数组data[0];data[0]表示一维数组的地址,data[0]就表示一位数组data[0]首元素data[0][0]的地址。所以 **data的值就是data[0][0],data的值就是&&data[0][0]

 

注意:比较简单的方法是,将指针转化为数组来理解,例如*(*(pointer+i)+j)的代码写成pointer[i][j],减少出错的概率,[]表示偏移后取值

 

2.2.3 使用二维数组指针去访问元素

声明一个二维数组 :int data[3][4],data代表这个二维数组的指针

data第一个元素的地址,该元素是一维数组
data+1第二个元素的地址,该元素是一维数组
*(data+1)数组的地址,也是数组的首元素的地址,该数组是一维数组。*(data+1)的值于data+1相同,但是意义不一样。
(*(data+1)+2)二维数组第1行第2列的元素的地址,也是一位数组data+1的第2个元素的地址。   
*(*(data+1)+2)二维数组第一行第二列元素的值


   

#include<stdio.h>
#include<stdlib.h>
#include<string.h>#define ARRAY_X 3
#define ARRAY_Y 4void main()
{int data[ARRAY_X][ARRAY_Y]={0};int *pointer=data;int i,j,k,num=10;;for(i=0; i<ARRAY_X; i++){for(j=0;j<ARRAY_Y;j++){data[i][j]=num++;}   } 	 for(i=0; i<ARRAY_X;i++){printf("\r\n");for(j=0;j<ARRAY_Y;j++){		printf("data[%d][%d]:%d,(address:0x%-10x)\r\n",i,j,data[i][j],&data[i][j]);}	}     printf("data:0x%x\r\n",data);printf("*data:0x%x\r\n",*data);   printf("**data:0x%x\r\n",**data);printf("data[0][0]:0x%x\r\n",data[0][0]);printf("&data[0][0]:0x%x\r\n",&data[0][0]);		printf("data[0]:0x%x\r\n",data[0]);	printf("&data[0]:0x%x\r\n",&data[0]);printf("&data[0][0]:0x%x\r\n",&data[0][0]);for(i=0; i<ARRAY_X;i++){printf("\r\n");for(j=0;j<ARRAY_Y;j++){		 	printf("*(data+%d)):0x%x\r\n",i,*(data+i));	 printf("*(*(data+%d)+%d):%d\r\n",i,j,*(*(data+i)+j));}	 }	}data[0][0]:10,(address:0xf49fe5e0  )
data[0][1]:11,(address:0xf49fe5e4  )
data[0][2]:12,(address:0xf49fe5e8  )
data[0][3]:13,(address:0xf49fe5ec  )data[1][0]:14,(address:0xf49fe5f0  )
data[1][1]:15,(address:0xf49fe5f4  )
data[1][2]:16,(address:0xf49fe5f8  )
data[1][3]:17,(address:0xf49fe5fc  )data[2][0]:18,(address:0xf49fe600  )
data[2][1]:19,(address:0xf49fe604  )
data[2][2]:20,(address:0xf49fe608  )
data[2][3]:21,(address:0xf49fe60c  )
data:0xf49fe5e0
*data:0xf49fe5e0
**data:0xa
data[0][0]:0xa
&data[0][0]:0xf49fe5e0
data[0]:0xf49fe5e0
&data[0]:0xf49fe5e0
&data[0][0]:0xf49fe5e0*(data+0)):0xf49fe5e0
*(*(data+0)+0):10
*(data+0)):0xf49fe5e0
*(*(data+0)+1):11
*(data+0)):0xf49fe5e0
*(*(data+0)+2):12
*(data+0)):0xf49fe5e0
*(*(data+0)+3):13*(data+1)):0xf49fe5f0
*(*(data+1)+0):14
*(data+1)):0xf49fe5f0
*(*(data+1)+1):15
*(data+1)):0xf49fe5f0
*(*(data+1)+2):16
*(data+1)):0xf49fe5f0
*(*(data+1)+3):17*(data+2)):0xf49fe600
*(*(data+2)+0):18
*(data+2)):0xf49fe600
*(*(data+2)+1):19
*(data+2)):0xf49fe600
*(*(data+2)+2):20
*(data+2)):0xf49fe600
*(*(data+2)+3):21

2.2.4 指向二维数组的指针

 在编写函数时,入参通常会是一个二维数组的指针,怎样正确访问这个二维数组的指针呢?

声明一个二维数组 :int data[3][4]。

声明一个指针int (* pointer)[4],该指针指向一个包含4个元素的数组.

[4]通知编译器,每次pointer+1将会移动4个单位的长度。

错误的声明:int  ** pointer,等价于int (* pointer)[1],编译器不知道宽度,每次pointer+1只会移动1个单位的长度

错误的声明:int  * pointer[4],变成了指针数组,指针指向整型数。

void main()
{int data[ARRAY_X][ARRAY_Y]={0};int (*pointer)[ARRAY_Y]=data;int i,j,k,num=10;;for(i=0; i<ARRAY_X; i++){for(j=0;j<ARRAY_Y;j++){data[i][j]=num++;}   } 	 for(i=0; i<ARRAY_X;i++){printf("\r\n");for(j=0;j<ARRAY_Y;j++){		printf("data[%d][%d]:0x%x,(address:0x%-10x)\r\n",i,j,data[i][j],&data[i][j]);}	}     printf("data:0x%x\r\n",data);printf("*data:0x%x\r\n",*data);   printf("**data:0x%x\r\n",**data);printf("data[0][0]:0x%x\r\n",data[0][0]);printf("&data[0][0]:0x%x\r\n",&data[0][0]);		printf("data[0]:0x%x\r\n",data[0]);	printf("&data[0]:0x%x\r\n",&data[0]);printf("&data[0][0]:0x%x\r\n",&data[0][0]);for(i=0; i<ARRAY_X;i++){printf("\r\n");for(j=0;j<ARRAY_Y;j++){		 	printf("*(pointer+%d)+%d: 0x%x\r\n",i,j, *(pointer+i)+j);		 printf(" *(*(pointer+%d)+%d): 0x%x\r\n",i,j, *(*(pointer+i)+j));}	 }	}data[0][0]:0xa,(address:0xb8a93be0  )
data[0][1]:0xb,(address:0xb8a93be4  )
data[0][2]:0xc,(address:0xb8a93be8  )
data[0][3]:0xd,(address:0xb8a93bec  )data[1][0]:0xe,(address:0xb8a93bf0  )
data[1][1]:0xf,(address:0xb8a93bf4  )
data[1][2]:0x10,(address:0xb8a93bf8  )
data[1][3]:0x11,(address:0xb8a93bfc  )data[2][0]:0x12,(address:0xb8a93c00  )
data[2][1]:0x13,(address:0xb8a93c04  )
data[2][2]:0x14,(address:0xb8a93c08  )
data[2][3]:0x15,(address:0xb8a93c0c  )
data:0xb8a93be0
*data:0xb8a93be0
**data:0xa
data[0][0]:0xa
&data[0][0]:0xb8a93be0
data[0]:0xb8a93be0
&data[0]:0xb8a93be0
&data[0][0]:0xb8a93be0*(pointer+0)+0: 0xb8a93be0*(*(pointer+0)+0): 0xa
*(pointer+0)+1: 0xb8a93be4*(*(pointer+0)+1): 0xb
*(pointer+0)+2: 0xb8a93be8*(*(pointer+0)+2): 0xc
*(pointer+0)+3: 0xb8a93bec*(*(pointer+0)+3): 0xd*(pointer+1)+0: 0xb8a93bf0*(*(pointer+1)+0): 0xe
*(pointer+1)+1: 0xb8a93bf4*(*(pointer+1)+1): 0xf
*(pointer+1)+2: 0xb8a93bf8*(*(pointer+1)+2): 0x10
*(pointer+1)+3: 0xb8a93bfc*(*(pointer+1)+3): 0x11*(pointer+2)+0: 0xb8a93c00*(*(pointer+2)+0): 0x12
*(pointer+2)+1: 0xb8a93c04*(*(pointer+2)+1): 0x13
*(pointer+2)+2: 0xb8a93c08*(*(pointer+2)+2): 0x14
*(pointer+2)+3: 0xb8a93c0c*(*(pointer+2)+3): 0x15

3 指针的指针的指针 

3.1 指向二维数组的指针--元素为基本类型

 声明一个二维指针数组:int * p_data[3][4]

        这是一个二维数组,数组元素中存放的是指针,指针指向一个整型数。

   int *(*pointer)[4]

     这是一个指针,指向一个一维数组,该一维数组长度为4,数组的每个元素是一个指向整型数的指针。

 如何使用   pointer来访问p_data的值呢?

    pointer=p_data;

 p_data[i][j] 等价于pointer[i][j],等价于*(*(pointer+i)+j)  ; 

*(p_data[i][j])等价于*(pointer[i][j],等价于 **(*(pointer+i)+j)

3.2 指向二维数组的指针--元素为结构体

声明结构体typedef struct avl{
int name[4];
int age;
}AVL;定义宏
#define ARRAY_X 3
#define ARRAY_y 6声明二维结构提指针数组
AVL* pointer[ARRAY_X][ARRAY_y];    声明指向数组的指针,数组的长度为6,每个元素为存放AVL类型指针
AVL*(*ppp)[ARRAY_y];ppp=pointer;引用方法:
ppp[x][y]   
ppp[x][y])->name
ppp[x][y])->age

二维数组指针的关键是数组的宽度,告诉编译器每次移动一个单位需要偏移多少个字节。


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

相关文章

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…

论文阅读笔记--Clustered Federated Learning:Model-Agnostic Distributed Multitask Optimization Under Privacy

Introduction 传统的Parameter Server&#xff08;P-S&#xff09;架构的联邦学习系统尝试训练出一个模型&#xff0c;让它能适用于每一个client的数据分布&#xff0c;这暗含了一个假设&#xff0c;模型的最优解 θ ∗ \theta^* θ∗同时是所有client的最优解&#xff0c;各个…

CVPR 2021 UniT: Multimodal Multitask Learning with a Unifified Transformer

动机 transformer在包括但不限于自然语言、图像、视频和音频在内的广泛领域都显示出巨大的成功。 前人的研究表明,在大型语料库中训练的transformer在一系列的下游语言任务中学习了强大的表征。在视觉领域中,基于transformer的模型在图像分类、目标检测和全景分割方面取得了非…

Language Models are Unsupervised Multitask Learners 笔记

语言模型是无监督的多任务学习者 摘要 自然语言处理任务&#xff0c;如问题回答、机器翻译、阅读理解和总结&#xff0c;通常是通过任务特定数据集上的监督学习来完成的。我们证明&#xff0c;当语言模型在一个称为WebText的数百万网页的新数据集上训练时&#xff0c;它们可以…