行列指针迷思

在中国的C语言编程领域中,有一对概念叫做“行指针”与“列指针”,他们两个形如下: int arr[3][4]; int (*pRow)[4] = arr; // Row Pointer int *pCol = arr[0]; // Column Pointer 其中行列指针都是用来访问一个二维数组而用,但是其访问的方式有一些不同,比如我要访问二行三列的元素时,行列指针访问其元素的方法分别如下: int value = 0; // Access a Row Pointer value = pRow[2][3]; value = *(*(pRow + 2) + 3); // Access a Column Pointer value = *(pCol + 4 * 2 + 3); 但有趣的事情是,行指针看起来似乎与数组指针长得更像一些,而列指针更加偏向于传统的一般指针。于是我打算从英文资料内去寻找相关资料。但当我尝试使用类似于row pointer或者column pointer的关键词在Google上搜索相关资料时,真正在讨论这个概念的英文页面是从CSDN机器翻译的中文文章。加之这个概念本身与一般指针过于类似,我开始考虑这个概念本身是否是正确的。 先讨论内存结构 一维指针与二维指针的结构是极其类似的,他们两个都是连续的排列在一段连续的内存空间内,类似一条条带一样。但是不同点在于一维指针没有主次序之分,而二维指针存在主次序。用一个具体例子来说明: 假设这里有一个最多可以容纳8个元素的一维指针: 长度为sizeof(int) * 8,那么那将会在内存中开辟出一块连续的空间,并给我们指向这个内存空间起始位置的地址。此时我们可以直接通过对指针本身添加偏差值来获取我们指定一维序的地址。 有一个简化的计算方法是对一维指针添加单个Index符号(也就是[])来计算偏差值并访问其元素。 我们再来假设另外一个可以容纳8个元素的二维指针: 其中二维序长度为2,一维序长度为4,那么这一个指针的长度就是sizeof(int) * 2 * 4。同样的,我们在此也会开辟出一块连续的内存空间,同时也将会获得指向这一块内存空间起始位置的地址。 此时我们同样也是对指针添加偏差值来获得指定序的地址,但有一点不同的是,此处我们并非直接通过指定一维序来计算偏差值,而是通过公式二维序 * 二维序长度 + 一维序作为偏差值来计算目标序的地址。有一个简化的计算方法是对一维指针添加两个Index符号(也就是[][])来计算偏差值并访问其元素。...

2022/6/30 · Ca2didi