c语言中 指针和一维数组 简要总结

本文简要总结了一维数组与指针的基本概念、操作方法及应用场景,包括使用数组和指针进行一维数组内容的遍历输出,探讨了不同操作方式的优劣,并提供了两种通用性强的操作方法。

          今天把指针和一维数组的知识,做一个简要的总结。

 <pre name="code" class="cpp">	int liv_arr[] = {11, 22, 33, 44, 55};
	int * lpv_sum = liv_arr;
	printf("liv_arr[2]=%d   *(lpv_sum+2)=%d   *(liv_arr+2)=%d\n", liv_arr[2], *(lpv_sum+2), *(liv_arr+2));
	printf("liv_arr[2]=%x   *(lpv_sum+2)=%x   *(liv_arr+2)=%x\n", &liv_arr[2], lpv_sum+2, liv_arr+2);


输出的结果为

<span style="white-space:pre">	</span>liv_arr[2]=33   *(lpv_sum+2)=33   *(liv_arr+2)=33
<span style="white-space:pre">	</span>&liv_arr[2]=2dfa90   *(lpv_sum+2)=2dfa90   *(liv_arr+2)=2dfa90
那么说明他们的结果都是一样的,所以我们在操作的一维数组的时候,就有了三种方式进行操作。

比如我们现在想使用一个函数,将一维数组中的内容全部遍历输出,我们可以使用如下方式

方式一:使用数组方式:

<span style="white-space:pre">	</span><pre name="code" class="cpp"><pre name="code" class="cpp"><span style="white-space:pre">	</span>//使用数组方式进行打印一维数组中的元素
<pre name="code" class="cpp">       /*
           int * pArr    为一维指针数组
<span style="font-family: Arial, Helvetica, sans-serif;">               */</span>
void printArr(int arr[5]){ for (int i=0; i<5; i++) { printf("arr[%d] = %d \n", i, arr[i]); }}


        
<span style="white-space:pre">	</span>//调用
<span style="white-space:pre">	int liv_arr[] = {11, 22, 33, 44, 55};
<span style="white-space:pre">	</span>printArr(liv_arr);</span>


       输出结果:

<span style="white-space:pre">	</span>arr[0] = 11
<span style="white-space:pre">	</span>arr[1] = 22
<span style="white-space:pre">	</span>arr[2] = 33
<span style="white-space:pre">	</span>arr[3] = 44
<span style="white-space:pre">	</span>arr[4] = 55
但是使用这种方式会发现代码的复用性比较差,因为参数必须是5个元素的int类型的数组
  
         方式二:使用指针方式

<span style="white-space:pre">	</span>//使用指针方式进行打印一维数组中的元素<span style="white-space:pre">	</span>
      /*
         int * pArr    为一维指针数组
         int count     为一维指针数组元素个数
       */
       void printArr(int * pArr, int count)
<span style="white-space:pre">	</span>{
	    for(int i=0; i<count; i++)
	    {
		printf("*(pArr+%d) = %d \n", i, *(pArr+i));
	    }
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>
        //调用
        int liv_arr[] = {11, 22, 33, 44, 55};
<span style="white-space:pre">	</span>printArr(liv_arr, 5);
       输出结果:

<span style="white-space:pre">	</span>*(pArr+0) = 11
<span style="white-space:pre">	</span>*(pArr+1) = 22
<span style="white-space:pre">	</span>*(pArr+2) = 33
<span style="white-space:pre">	</span>*(pArr+3) = 44
<span style="white-space:pre">	</span>*(pArr+4) = 55
我们使用该种方式的时候,会发现复用性比较好,也建议使用此种方式。





       

<think>我们之前讨论了三维指针数组(使用三级指针动态分配),但用户现在提供的引用内容是关于二维数组的数组指针(指向二维数组的指针)。根据引用内容,用户可能想了解如何用数组指针(指向数组的指针)来处理三维数组,或者如何定义指向二维数组的指针(即数组指针)来模拟三维数组。 然而,用户的问题明确为:“我想用户想了解在C语言中如何定义三维指针数组 请问C语言如何定义三维指针数组” 注意:这里“三维指针数组”可能有歧义: 1. 可以理解为“指针数组的三维形式”,即一个数组,其元素是指针,且这个数组有三个维度(类似于三维数组,但元素是指针)。 2. 也可以理解为“指向二维数组的指针数组”,即一个数组,其元素是指向二维数组的指针。 但根据引用内容,用户提供的引用[1][2]都在讲数组指针(int (*p)[4]这种形式),并且引用[1]中提到了二维数组与指针数组的配合使用。而引用[3]解释了数组指针的用法。 因此,我们需要澄清: - 如果用户想要的是动态分配的三级指针形式(即之前回答的三维指针数组),那么我们已经回答过。 - 如果用户想要的是使用数组指针(指向数组的指针)来处理三维数组(即静态的或模拟的三维数组),那么我们可以用数组指针来定义指向二维数组的指针,从而构建三维数组的访问。 考虑到用户引用的内容都是关于数组指针(指向一维数组指针用于处理二维数组),这里我们重点讲解如何使用数组指针来处理三维数组。 实际上,在C语言中,我们可以定义指向二维数组的指针,从而处理三维数组。但是,标准的做法是使用数组指针的嵌套。 不过,用户的问题明确是“三维指针数组”,我们按照两种理解分别回答: 理解1:动态分配的三维指针数组(三级指针)—— 之前已经详细回答。 理解2:使用数组指针来模拟三维数组(静态方式)。 由于引用内容中都是静态数组,所以这里我们补充静态三维数组的数组指针定义。 但是,用户提到了“指针数组”,而数组指针指针数组是不同的: - 指针数组:是一个数组,数组中的每个元素都是指针。例如:int *arr[10]; 表示arr是一个数组,有10个元素,每个元素是一个int型指针。 - 数组指针:是一个指针,指向一个数组。例如:int (*p)[10]; 表示p是一个指针,指向一个含有10个int元素的数组。 因此,三维指针数组如果按照“指针数组”来理解,那么可以是一个三维数组,每个元素都是指针。但这样的结构通常用于存储指针,而不是直接存储数据。 鉴于用户引用的内容,我猜测用户可能想了解如何用数组指针(即指向二维数组的指针)来处理一个三维数组(比如三维数组可以看成是二维数组的一维数组)。 下面我们分别说明: 方案一:动态分配的三级指针(之前已讲,这里简要回顾) int ***arr; 然后分三层分配。 方案二:使用数组指针处理静态三维数组(将三维数组视为由多个二维数组组成) 例如:一个三维数组 int a[2][3][4]; 我们可以定义一个指向二维数组的指针:int (*p)[3][4]; 然后让p指向a[0](即第一个二维数组),那么p+1就指向a[1](第二个二维数组)。 访问元素:(*p)[i][j] 相当于 a[0][i][j],而(*(p+1))[i][j]相当于a[1][i][j]。 方案三:指针数组(元素是指针)来构建三维结构 例如:我们可以定义一个指针数组,每个元素是一个指向二维数组的指针(即数组指针)。 定义:int (*arr[2])[3][4]; // arr是一个数组,大小为2,每个元素是一个指向二维数组(3行4列)的指针。 然后我们可以让arr[0]指向一个二维数组,arr[1]指向另一个二维数组。 但是,这种结构比较少见,通常我们使用方案二。 下面我们详细展开方案二(数组指针处理三维数组)方案一(动态三级指针)的对比说明。 由于用户问题要求定义三维指针数组,我们重点放在方案三(指针数组)方案一(动态指针数组)上,但引用内容指向数组指针,因此我们也将介绍方案二。 为了明确,我们按照以下结构回答: 1. 动态分配的三维指针数组(三级指针) 2. 静态三维数组的数组指针(指向二维数组的指针) 3. 指针数组构成的三维结构(指针数组,每个元素指向一个二维数组) 但注意:用户问题中的引用[1]提到了如何定义数组指针(用于二维数组),所以我们可以先介绍数组指针在三维数组中的应用(方案二),然后再回到指针数组。 下面开始回答:</think>### C语言中三维指针数组的定义与访问 在C语言中,三维指针数组可以通过**数组指针**或**指针数组**两种方式实现。根据您提供的引用内容(特别是引用[1][2]中关于二维数组指针的用法),以下是三维指针数组的核心定义方法访问技巧: --- #### 1. **数组指针法(推荐)** 通过定义指向二维数组的指针实现三维数组: ```c #include <stdio.h> int main() { // 定义静态三维数组 int arr[2][3][4] = { {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}}, {{13,14,15,16}, {17,18,19,20}, {21,22,23,24}} }; // 定义指向二维数组的指针(数组指针) int (*p)[3][4] = arr; // 指向3×4二维数组的指针 // 访问元素 arr[i][j][k] for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { for (int k = 0; k < 4; k++) { // 三种等效访问方式: printf("%d ", p[i][j][k]); // 直接下标 printf("%d ", *(*(*(p + i) + j) + k)); // 指针偏移 printf("%d ", (*(p + i))[j][k]); // 混合访问[^1][^2] } printf("\n"); } } return 0; } ``` **关键点**: 1. 定义语法:`int (*p)[行数][列数]` 2. 内存连续:所有元素在内存中连续存储,效率高[^1] 3. 指针偏移原理: - `p + i` → 移动`i * sizeof(int[3][4])`字节 - `*(p + i) + j` → 移动`j * sizeof(int[4])`字节 - `*(*(p + i) + j) + k` → 移动`k * sizeof(int)`字节 --- #### 2. **指针数组法** 构建指针数组指向多个二维数组: ```c #include <stdio.h> #include <stdlib.h> int main() { // 动态分配三个二维数组 int (*arr[3])[4]; // 指针数组:3个指向int[4]的指针 for (int i = 0; i < 3; i++) { arr[i] = malloc(sizeof(int[3][4])); // 每个指针指向3×4数组 } // 赋值与访问 for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { for (int k = 0; k < 4; k++) { arr[i][j][k] = i * 100 + j * 10 + k; printf("%d ", arr[i][j][k]); } } } // 释放内存 for (int i = 0; i < 3; i++) { free(arr[i]); } return 0; } ``` **特性对比**: | 方法 | 内存布局 | 访问效率 | 适用场景 | |--------------|-------------|----------|-----------------------| | 数组指针法 | 连续内存 | ⭐⭐⭐⭐⭐ | 固定维度的三维数组 | | 指针数组法 | 非连续内存 | ⭐⭐ | 动态/不规则维度数据[^3] | --- #### 3. **核心区别解析** ```c int *p1[3][4]; // 指针数组:3×4个int*指针 int (*p2)[3][4]; // 数组指针:指向3×4二维数组的指针 int (*p3[2])[3][4]; // 混合:2个指向3×4数组的指针(三维指针数组) ``` - **优先级规则**:`[]` > `*`,用`()`强制绑定指针声明 - **访问本质**: - `p[i][j][k]` 编译为 `*(*(*(p + i) + j) + k)` - 编译器自动计算偏移量:`addr = p + i*sizeof(*p) + j*sizeof(**p) + k*sizeof(***p)` --- #### 4. 实际应用示例(图像处理) 处理RGB三通道的128×128图像: ```c // 定义三维数组指针(通道×行×列) unsigned char (*image)[128][128] = malloc(sizeof(unsigned char[3][128][128])); // 访问绿色通道(G)第10行第20列的像素 unsigned char g = image[1][10][20]; // 通道顺序: R=0, G=1, B=2 // 释放内存 free(image); ``` > ⚠️ **注意事项** > 1. 数组指针维度必须匹配:`int (*p)[3][4]` 只能指向`int[x][3][4]`的数组 > 2. 动态分配需检查`malloc`返回值 > 3. 指针偏移计算依赖元素大小:`sizeof(*p)` ≠ `sizeof(p)`[^1][^3] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值