C语言数组指针用法详解(附带实例)
C语言程序中定义数组时,系统会在内存中为其分配一段存储空间,数组名就是数组在内存中的首地址。若再定义一个指针变量,并将数组的首地址传给指针变量,则该指针就指向了这个数组。
例如:
也可以写成如下形式:
【实例】定义两个指针变量,再定义两个一维数组,将两个数组元素分别赋给两个指针。利用 for 循环输入两个数组的值(100 以内开始 5 个数和后 5 个数),再用 for 循环和指针输出数组值。代码如下:
(p+n) 和 *(a+n) 都用于表示数组元素 a[n]。语句“printf("%5d", *(p+i));”和“printf("%5d",*(q+i));”表示输出数组 a、b 中对应的元素。
程序中使用指针指向一维数组的过程可以通过下图来表示:

图 1 指针指向一维数组
使用指针引用数组元素的过程可以通过下图来表示:

图 2 通过指针引用数组元素
用 a+n 表示数组元素的地址,*(a+n) 表示数组元素,可以将实例程序中输出数组部分的程序代码改成如下形式(运行结果不变):
表示指针的移动可以使用“++”和“−−”这两个运算符。例如,利用“++”运算符可将数组输出部分的代码改写成如下形式:
还可对实例程序再进一步改写,将数组的输入、输出都采用指针自增运算实现。改写后的程序代码如下:
比较上面的程序会发现,如果在给数组元素赋值时使用了指针自增运算,而且在输出数组元素时也使用指针变量,则需要加上如下语句:
对于一个 m 行 n 列的二维数组,其元素地址的表示方法如下:
【实例】输出 3*5 矩阵。利用指针对二维数组进行输入和输出,具体代码如下:

图 3 二维数组
在运行结果相同的前提下,可将程序改写成如下形式:
【实例】输出第 3 行元素。将一个 3 行 5 列二维数组的第 3 行元素输出,具体代码如下:
也可采用 *(a+i)+j形式输入二维数组元素,代码如下:
同样可以采用 *(a+i)+j 形式输出二维数组元素,代码如下:
例如:
int *p,a[10]; p=a;这里 a 是数组名,也就是数组的首地址,将它赋给指针变量 p,也就是将数组 a 的首地址赋给 p。
也可以写成如下形式:
int *p,a[10]; p=&a[0];上面的语句是将数组 a 中首个元素的地址赋给指针变量 p。由于 a[0] 的地址就是数组的首地址,因此上述两条赋值语句的操作效果完全相同。
【实例】定义两个指针变量,再定义两个一维数组,将两个数组元素分别赋给两个指针。利用 for 循环输入两个数组的值(100 以内开始 5 个数和后 5 个数),再用 for 循环和指针输出数组值。代码如下:
#include<stdio.h> int main() { int *p, *q, a[5], b[5], i; /*定义变量*/ p = &a[0]; /*将数组首地址赋给指针*/ q = b; printf("please input array a:\n"); /*提示输入数组 a*/ for(i = 0; i < 5; i++) scanf("%d", &a[i]); /*利用&a[i]形式输入数组 a*/ printf("please input array b:\n"); /*提示输入数组 b*/ for(i = 0; i < 5; i++) scanf("%d", &b[i]); /*利用&b[i]形式输入数组 b*/ printf("array a is:\n"); /*提示输出数组 a 元素*/ for(i = 0; i < 5; i++) printf("%5d", *(p + i)); /*利用*(p + i)形式输出数组 a */ printf("\n"); printf("array b is:\n"); /*提示输出数组 b*/ for(i = 0; i < 5; i++) printf("%5d", *(q + i)); /*利用*(q + i)形式输出数组 b */ printf("\n"); return 0; }程序运行结果为:
please input array a: 1 2 3 4 5 please input array b: 99 98 97 96 95 array a is: 1 2 3 4 5 array b is: 99 98 97 96 95如下两条语句,都表示将数组首地址赋给指针变量:
p=&a[0]; q=b;p+n 与 a+n 都用于表示数组元素 a[n] 的地址,即 &a[n]。对整个 a 数组来说,共有 5 个元素,n 的取值为 0~4,则数组元素的地址就可以表示为 p+0~p+4 或 a+0~a+4。
(p+n) 和 *(a+n) 都用于表示数组元素 a[n]。语句“printf("%5d", *(p+i));”和“printf("%5d",*(q+i));”表示输出数组 a、b 中对应的元素。
程序中使用指针指向一维数组的过程可以通过下图来表示:

图 1 指针指向一维数组
使用指针引用数组元素的过程可以通过下图来表示:

图 2 通过指针引用数组元素
用 a+n 表示数组元素的地址,*(a+n) 表示数组元素,可以将实例程序中输出数组部分的程序代码改成如下形式(运行结果不变):
printf("array a is:\n"); for(i=0; i<5; i++) printf("%5d", *(a+i)); /*利用*(a+i)形式输出数组 a*/ printf("\n"); printf("array b is:\n"); for(i=0; i<5; i++) printf("%5d", *(b+i)); /*利用*(b+i)形式输出数组 b*/ printf("\n");
表示指针的移动可以使用“++”和“−−”这两个运算符。例如,利用“++”运算符可将数组输出部分的代码改写成如下形式:
printf("array a is:\n"); for(i=0; i<5; i++) printf("%5d", *p++); /*利用*p++形式输出数组 a*/ printf("\n"); printf("array b is:\n"); for(i=0; i<5; i++) printf("%5d", *q++); /*利用*q++形式输出数组 b*/ printf("\n");
还可对实例程序再进一步改写,将数组的输入、输出都采用指针自增运算实现。改写后的程序代码如下:
#include<stdio.h> main() { int *p, *q, a[5], b[5], i; p = &a[0]; q = b; printf("please input array a:\n"); for(i = 0; i < 5; i++) scanf("%d", p++); /*利用 p++形式输入数组 a*/ printf("please input array b:\n"); for(i = 0; i < 5; i++) scanf("%d", q++); /*利用 q++形式输入数组 b*/ p = a; q = b; printf("array a is:\n"); for(i = 0; i < 5; i++) printf("%5d", *p++); /*利用*p++形式输出数组 a*/ printf("\n"); printf("array b is:\n"); for(i = 0; i < 5; i++) printf("%5d", *q++); /*利用*q++形式输出数组 b*/ printf("\n"); }
比较上面的程序会发现,如果在给数组元素赋值时使用了指针自增运算,而且在输出数组元素时也使用指针变量,则需要加上如下语句:
p=a; q=b;这两行语句的作用是将指针变量 p 和 q 重新指向数组 a 和数组 b 在内存中的起始位置。若没有该语句,直接使用“*p++”“*q++”的方法进行输出,将会产生错误。
C语言二维数组指针
定义一个 3 行 5 列的二维数组,其在内存中的存储形式如下图所示,从中可以看到多种表示二维数组中元素地址的方法。对于一个 m 行 n 列的二维数组,其元素地址的表示方法如下:
- a 表示二维数组的首地址,也表示数组第 1 行的首地址,a+1 表示第 2 行的首地址,a+m 表示第 m+1 行的首地址。
- a[0]+n 表示数组第 1 行第 n+1 个元素的地址,a[m]+n 表示第 m+1 行第 n+1 个元素的地址。
- &a[0] 表示数组第 1 行的首地址,&a[m] 表示第 m+1 行的首地址。
- &a[0][0] 既可以表示数组第 1 行 1 列的首地址,也可以看作整个数组的首地址。&a[m][n]就是第 m+1 行 n+1 列元素的地址。指针也可表示地址,因此通过指针可以引用二维数组中的元素。
- *(*(a+m)+n) 和 *(a[m]+n) 含义相同,都表示数组第 m+1 行第 n+1 列元素。
【实例】输出 3*5 矩阵。利用指针对二维数组进行输入和输出,具体代码如下:
#include<stdio.h> int main() { int a[3][5], i, j; printf("please input:\n"); for(i = 0; i < 3; i++) /*控制二维数组的行数*/ { for(j = 0; j < 5; j++) /*控制二维数组的列数*/ { scanf("%d", a[i] + j); /*利用 a[i]+j 形式输入二维数组元素*/ } } printf("the array is:\n"); for(i = 0; i < 3; i++) { for(j = 0; j < 5; j++) { printf("%5d", *(a[i] + j)); /*利用 a[i]+j 形式输出二维数组元素*/ } printf("\n"); } return 0; }程序运行结果为:
please input: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 the array is: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15程序运行结果如下图所示:

图 3 二维数组
在运行结果相同的前提下,可将程序改写成如下形式:
#include<stdio.h> int main() { int a[3][5], i, j, *p; p = a[0]; /*定义 p 为第 1 行元素的首地址*/ printf("please input:\n"); for(i = 0; i < 3; i++) /*控制二维数组的行数*/ { for(j = 0; j < 5; j++) /*控制二维数组的列数*/ { scanf("%d", p++); /*使用 p++形式输入二维数组元素*/ } } p = a[0]; /*再次定义 p 为第 1 行元素的首地址*/ printf("the array is:\n"); for(i = 0; i < 3; i++) { for(j = 0; j < 5; j++) { printf("%5d", *p++); /*使用 p++形式输出二维数组元素*/ } printf("\n"); } return 0; }
【实例】输出第 3 行元素。将一个 3 行 5 列二维数组的第 3 行元素输出,具体代码如下:
#include<stdio.h> int main() { int a[3][5], i, j, (*p)[5]; p = &a[0]; /*定义 p 为第 1 行元素的首地址*/ printf("请输入 3*5 数组内容 t:\n"); for(i = 0; i < 3; i++) /*控制二维数组的行数*/ for(j = 0; j < 5; j++) /*控制二维数组的列数*/ scanf("%d", *(p + i) + j); /*使用*(p+i)+j 形式输入二维数组元素*/ p = &a[2]; /*定义 p 为第 3 行元素的首地址*/ printf("第三行是:\n"); for(i = 0; i < 5; i++) printf("%5d", *(*p + i)); /*使用*(p+i)+j 形式输出二维数组元素*/ printf("\n"); return 0; }程序运行结果为:
请输入 3*5 数组内容 t:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
第三行是:
11 12 13 14 15
也可采用 *(a+i)+j形式输入二维数组元素,代码如下:
scanf("%d", *(a + i) + j);
同样可以采用 *(a+i)+j 形式输出二维数组元素,代码如下:
printf("%5d", *(a + i) + j);
利用指针引用二维数组的关键是要记住 *(a+i) 与 a[i] 是等价的。