C语言基础学习笔记(11):指针与数组的关系
图: 北英格兰,惠特比港(Whitby Harbour)
Guderian出品
指针与一维数组的关系
一维数组在内存中是线性排列的。假设存在一个任意的int
类型数组a[N]
,数组名a
代表了数组的首地址&a[0]
,则&a[i]
等价于(a+i)
。注意这里a+1
不是加上1
个字节,而是取决于a
的基类型(这里是int
,即为4
个字节):a+1
等价于a+sizeof(基类型)
。因此我们可以得出一维数组元素的等价引用形式:a[i]
等价于*(a+i)
。下面举两个例子:
示例一
用指针读入一维数组并用指针输出一维数组:
1 |
|
示例二
示例一的另一种实现方式:
1 |
|
指针与二维数组的关系
兄弟们,做好心理准备,
下面的内容对萌新不友好
内存中数据的存储形式都是线性的,二维数组在内存中按行线性存储,但可以用两种方式看待它。
第一种方式:行是列的索引
以a[2][3]
为例,它的存储结构如图:
想要访问某一行某一列的元素,需要先访问某一行,再访问某一列:首先定义类型为int [3]
的行指针int (*p)[3]
(不要写成*p[3]
,否则就成了有三个元素的指针数组)用于存储a[2][3]
的行指针,只需这么做:p = a
或者p = &a[0]
。
这里要正确理解a
和&a[0]
的含义,一种较为简单的理解方式是:首先把a
看做一个一维数组a[2]
,有两个int [3]
型元素,那么其首地址就是a
或者&a[0]
;然后再把a[2]
看成一个一维数组a[2][3]
,那么其首地址就是a[0]
或者*a
。a
和&a[0]
的含义就是第0
行的行指针,*a
和a[0]
和&a[0][0]
的含义就是第0
行第0
列的指针(后面在第二种方式会讲到)。
1 |
|
输出结果为:
1 | 1 2 3 4 5 6 |
第二种方式:Only one dimension in RAM!
这种方式模拟了数组在内存上存储的真实情况,把a[2][3]
看做一维数组,先按行分块,每一块再按列排序,要访问一个元素只需计算它内存地址的偏移量即可。定义int *p;
并令p = &a[0][0]
(或*a
或a[0]
),那么要访问a[i][j]
只需等价于访问*(p+i*2+j)
。
1 |
|
输出结果为:
1 | 1 2 3 4 5 6 |
【更多C语言系列】