首页 > 编程笔记 > C语言笔记 阅读:13

C语言数组指针用法详解(附带实例)

C语言程序中定义数组时,系统会在内存中为其分配一段存储空间,数组名就是数组在内存中的首地址。若再定义一个指针变量,并将数组的首地址传给指针变量,则该指针就指向了这个数组。

例如:
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 列的二维数组,其元素地址的表示方法如下:
【实例】输出 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] 是等价的。 

相关文章