【指针与二维数组】

文章详细阐述了指针与二维数组的关系,强调在C语言中二维数组按行优先存储。一级指针可以指向二维数组的一维子数组,而行指针(数组指针)则能直接指向整行。通过行指针,可以更有效地访问和操作二维数组的元素。

介绍指针与二维数组,包括一级指针如何访问二维数组以及行指针如何访问二维数组 

目录

一、指针与二维数组

二、行指针

总结


一、指针与二维数组

1.概念复习:

多维数组就是具有两个或两个以上下标的数组

在C语言中,二维数组的元素连续存储,按行优先存,在地址上是连续的几个一维数组

int a[2][3]; 

a[0][0]  a[0][1]

a[1][0]  a[1][1]    可以分解为a[0],a[1],a[2]三个一维数组;因此在二维数组中这三个是数组名

a[2][0]  a[2][1]

2.指针与二维数组的关系

(1)一个“ * ”的指针和一维数组的维度是一样的,都是在一条线上的,可以直接指向数组,但是

在二维数组中,一个二维数组不能直接用一个*的指针表示,要把数组和指针调整到一个维度上才能让指针指向数组的地址;

 分析:

⚪这时候a[0]是第一行数组的数组名,代表地址常量,所以a[0]这时候是一个一维数组。可以用p指向它;

⚪因为a[0]是第一行首元素的地址,所以也是a的首元素的地址,所以两者的地址一样。

⚪这个时候a[0]是一个一维数组,所以在物理内存上加减数字能够访问到二维数组的所有元素,通俗点讲二维数组就是在物理内存上是几个一维数组串联起来的更大的一维数组;

⚪因为a[0],a[1]为数组名  ,两个数组分别一个数组代表一行  所以a加减是以行为单位的,从代码中可以看出a+1后,地址增加的是一行数组的地址空间

 

分析:

在纯粹的一维数组中a[i]   p[i]   *(p+i)  *(a+i) 这几种表达方式完全相同,在二维数组中,对于*(p+i)  *(a+i),p[i]是完全相同的,但是不能用a[i]来访问数组元素,因为这时候a[0],a[1]都是数组名了,是地址常量

二、行指针

1. 二维数组名代表数组的起始地址,数组名加1,是移动一行元素。因此,二维数组名常被称为行地址

 2.

行指针(数组指针)

存储行地址的指针变量,叫做行指针变量。

形式如下: <存储类型>   <数据类型>   (*<指针变量名>)[表达式] ;

例如,int a[2][3];  int (*p)[3]; 方括号中的常量表达式表示指针加1,移动几个数据。

当用行指针操作二维数组时,表达式一般写成1行的元素个数,即列数

(1)

分析:

⭕当用行指针表示二维数组时,此时二维数组和行指针的类型是一样的,相当于是在一个维度上,所以此时p可以直接指向a,因此p和a地址值相同,可以用p替换a做数组名;

⭕直接对二维数组或者行指针取“ * ”,相当于是把数组或者行指针降级改变性质(即降低维度)

从上图可得

*(a+1)为a[1],而在二维数组中,a[1]是一个一维数组名,所以 此时进行的是一个数组名为a[1]的一维数组的操作,此时a[1]加减访问的是一列一列的数组元素的地址;

程序举例如下:

总结

主要介绍了指针与二维数组,包括一级指针如何访问二维数组以及行指针如何访问二维数组 

### 指针二维数组的关系及操作 在 C 语言中,指针二维数组之间存在紧密的联系。这种关系可以通过指针算术和指针数组来实现对二维数组元素的访问和操作。 #### 1. 二维数组的基本概念 二维数组可以看作是一个数组的数组。例如,`int a[3][4]` 表示一个 3 行 4 列的二维数组。在内存中,这个二维数组是以行优先的方式存储的,即第一行的所有元素连续存储,接着是第二行的所有元素,依此类推[^1]。 #### 2. 数组名地址的关系 - 对于二维数组 `a[3][4]`,数组名 `a` 是指向第一行的指针,等价于 `&a[0]`。 - 每一行(如 `a[0]`)本身是一个一维数组,因此 `a[0]` 是指向该行第一个元素的指针,等价于 `&a[0][0]`[^4]。 #### 3. 指针二维数组的操作 通过指针算术,可以灵活地访问二维数组中的元素。以下是一些关键点: - **访问单个元素** 假设有一个二维数组 `int a[3][4]` 和一个指针 `int (*p)[4]`,可以通过以下方式访问元素: ```c int a[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} }; int (*p)[4] = a; // p 指向二维数组的第一行 printf("%d\n", p[1][2]); // 输出 7 ``` 在这里,`p[1][2]` 等价于 `*(*(p + 1) + 2)`[^3]。 - **指针加法** 指针加法可以用来移动到不同的行或列。例如: ```c int a[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} }; int (*p)[4] = a; printf("%d\n", *(p[0] + 2)); // 输出 3 printf("%d\n", *(*(p + 1) + 3)); // 输出 8 ``` - **使用指针数组模拟二维数组** 可以通过指针数组来模拟二维数组的行为。例如: ```c int row1[] = {1, 2, 3}; int row2[] = {4, 5, 6}; int row3[] = {7, 8, 9}; int *array[] = {row1, row2, row3}; // 指针数组 printf("%d\n", array[1][2]); // 输出 6 ``` #### 4. 注意事项 - 在使用指针操作二维数组时,需要确保指针偏移量正确,以免发生越界错误[^1]。 - 当将二维数组传递给函数时,通常需要指定列数,因为编译器需要知道每一行的大小以便正确计算地址。 ### 示例代码 以下是一个完整的示例,展示如何使用指针访问二维数组中的元素: ```c #include <stdio.h> int main() { int a[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} }; int (*p)[4] = a; for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { printf("a[%d][%d] = %d\n", i, j, p[i][j]); } } return 0; } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

放牛的守护神_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值