P269
第七十六节: 二维数组的指针。
【76.1 二维数组指针的用途。】
前面章节讲了一维指针操作二维数组, 本质是通过“类型强制转换” 实现的, 这种应用局限于某些特定的
场合, 毕竟一维有 1 个下标, 二维有 2 个下标, 一维和二维在队形感上是有明显差别的, 强行用一维指针操作
二维数组会破坏了代码原有的队形感, 大多数的情况, 还是用二维指针操作二维数组。
二维指针主要应用在两个方面, 一方面是 N 个二维数组的“中转站” 应用, 另一方面是函数接口的应用。
比如, 当某项目有 N 个二维数组表格时, 要通过某个变量来切换处理某个特定的表格, 以便实现“N 选一” 的功能,
此时, 二维指针在这 N 个二维数组之间就起到中转站的作用。 又, 当某个函数接口想输入或者输出一个二维数组时, 就必然要用到二维指针作为函数的接口参数。
76.2
举一个例子, 有 3 个现有的二维数组, 通过某个变量来选择切换, 把某个二维数组的数据复制到指定的一个缓存数组中
- #include "stdio.h"
-
- const unsigned char table_1[3][3]={{0x00,0x01,0x02},{0x10,0x11,0x12},{0x20,0x21,0x22}};
-
- const unsigned char table_2[3][3]={{0xA0,0xA1,0xA2},{0xB0,0xB1,0xB2},{0xC0,0xC1,0xC2}};
-
- const unsigned char table_3[3][3]={{0xD0,0xD1,0xD2},{0xE0,0xE1,0xE2},{0xF0,0xF1,0xF2}};
-
- //一个缓存数组
- unsigned char SaveBuffer[3][3];
- //选择变量
- unsigned char TableSec;
-
- //中转站的二维指针?这是一个中转用的指针数组吧
- const unsigned char (*pTable)[3];
- //unsigned char (*pTable)[3];
-
- int main(){
- //选择第二个现有数组
- TableSec=2;
- switch(TableSec){
- case 1:pTable=table_1;break;
- case 2:pTable=table_2;break;
- case 3:pTable=table_3;break;
- }
- //遍历指针数组pTable,将数据传递给 SaveBuffer[][]
- unsigned char R,L;
- for(R=0;R<3;R++){
- for(L=0;L<3;L++){
- SaveBuffer[R][L]=pTable[R][L]+2;
- }
- }
- for(R=0;R<3;R++){
- for(L=0;L<3;L++){
- //SaveBuffer[R][L]=pTable[R][L];
- printf("%02X ",SaveBuffer[R][L]);
- }
- printf("\n");
- }
- return 0;
- }
- 执行结果
- A2 A3 A4
- B2 B3 B4
- C2 C3 C4
复制代码
注意,const unsigned char (*pTable)[3];既不是二维指针,也不是指针数组
二维指针 (unsigned char **p):
这是一个指向指针的指针。它可以用于指向一个指针数组,而这些指针又各自指向不同类型的数据(例如,一维数组)。
指针数组 (unsigned char *arrayOfPointers[]) 或者更具体地 unsigned char *arrayOfPointers[3]:
这是一个数组,其元素是指向 unsigned char 的指针。这意味着你可以有多个指针,每个都指向不同的 unsigned char 数据。
这个其实是
指向数组的指针 (unsigned char (*pArray)[3]):
如你所用,这是一个指向包含 3 个 unsigned char 元素的数组的指针。这种类型的指针可以用来指向整个二维数组的一行,或者任何其他具有相同结构的数组。
const unsigned char (*pTable)[3];:
这里的 (*pTable) 表示 pTable 是一个指针。
[3] 表示该指针指向的对象是一个包含 3 个元素的数组。
const unsigned char 表示这个数组中的每个元素是 const unsigned char类型,即这些元素是不可修改的无符号字符类型。
因此,pTable 是一个指向具有 3 个 unsigned char 元素的数组的指针。
它并不是一个“二维指针”也不是“指针数组”。
又问:pTable是一个指向三个元素的数组的指针,为什么可以用pTable[R][L]这种二维数组的形式?
tongyiqianwen的回答:
你提到的 pTable 是一个指向包含 3 个 unsigned char 元素的数组的指针。尽管从声明上看,它似乎只是一个指向特定大小数组的指针,但在C语言中,你可以通过多维数组的索引方式来访问数据,这是因为C语言中的数组和指针操作有一些内在的关联。
- #include <stdio.h>
-
- int main() {
- // 定义一个二维数组
- const unsigned char table_1[3][3] = {{0x00,0x01,0x02},{0x10,0x11,0x12},{0x20,0x21,0x22}};
-
- // 指向含有3个 unsigned char 元素的数组的指针
- const unsigned char (*pTable)[3];
-
- // 将 pTable 指向 table_1 的第1行
- pTable = table_1;
- // 将 pTable 指向 table_1 的第2行
- //pTable = table_1[1];
-
- // 打印 pTable 指向的内容
- unsigned char i;
- for (i = 0; i < 3; ++i) {
- printf("%02X ", (*pTable)[i]);//00 01 02
- }
- printf("\n");
- return 0;
- }
复制代码
对于
const unsigned char (*pTable)[3];
tongyiqianwen的解答:
这意味着 pTable 是一个指向含有 3 个 unsigned char 元素的数组的指针。
当你使用 pTable[R][L] 访问元素时,实际上是利用了C语言中对指针进行偏移计算的能力。
如何工作的
理解 pTable[R]:
在C语言中,pTable[R] 实际上等价于 *(pTable + R)。这意味着指针 pTable 向前移动 R 次,每次移动的距离是一个包含 3 个 unsigned char 的数组的大小(即 3 * sizeof(unsigned char) 字节)。
因此,pTable[R] 将指向第 R 行的第一个元素。
理解 pTable[R][L]:
接下来,pTable[R][L] 实际上是 *(pTable[R] + L) 或者 *(*(pTable + R) + L)。这意味着在已经定位到第 R 行的基础上,再向前移动 L 个 unsigned char 单位。
结果就是,你能够访问位于 R 行 L 列的元素
|