指针与数组(一)
副标题#e#
变量在内存存放是有地点的,数组在内存存放也同样具有地点。对数组来说,数组名就是数组在内存安顿的首地点。指针变量是用于存放变量的地点,可以指向变量,虽然也可存放数组的首址或数组元素的地点,这就是说,指针变量可以指向数组或数组元素,对数组而言,数组和数组元素的引用,也同样可以利用指针变量。下面就别离先容指针与差异范例的数组。
6.4.1指针与一维数组
假设我们界说一个一维数组,该数组在内存会有系统分派的一个存储空间,其数组的名字就是数组在内存的首地点。若再界说一个指针变量,并将数组的首址传给指针变量,则该指针就指向了这个一维数组。我们说数组名是数组的首地点,也就是数组的指针。而界说的指针变量就是指向该数组的指针变量。对一维数组的引用,既可以用传统的数组元素的下标法,也可利用指针的暗示要领。
int a[10],*ptr;/*界说数组与指针变量*/
做赋值操纵:
ptr=a;或ptr=&a[0];
则ptr就获得了数组的首址。个中,a是数组的首地点,&a[0]是数组元素a[0]的地点,由于a[0]的地点就是数组的首地点,所以,两条赋值操纵结果完全沟通。指针变量ptr就是指向数组a的指针变量。
若ptr指向了一维数组,此刻看一下C划定指针对数组的暗示要领:
1)ptr+n与a+n暗示数组元素a[n]的地点,即&a[n]。对整个a数组来说,共有10个元素,n的取值为0~9,则数组元素的地点就可以暗示为ptr+0~ptr+9或a+0~a+9,与&a[0]~&a[9]保持一致。
2)知道了数组元素的地点暗示要领,*(ptr+n)和*(a+n)就暗示为数组的各元素即等效于a[n]。
3)指向数组的指针变量也可用数组的下标形式暗示为ptr[n],其结果相当于*(ptr+n)。
[例6-5]/*以下标法输入输出数组各元素。
下面从键盘输入10个数,以数组的差异引用形式输出数组各元素的值。
#include <stdio.h>
main()
{
int n,a[10],*ptr=a;
for(n=0;n<=9;n++)
scanf("%d",&a[n]);
printf("1------output!\n");
for(n=0;n<=9;n++)
printf("%4d",a[n]);
printf("\n");
}
运行措施:
RUN
1234567890¿
1------output!
1234567890
[例6-6]回收指针变量暗示的地点法输入输出数组各元素。
#include <stdio.h>
main()
{
int n,a[10],*ptr=a;/*界说时对指针变量初始化*/
for(n=0;n<=9;n++)
scanf("%d",ptr+n);
print f("2------output!\n");
for(n=0;n<=9;n++)
print f("%4d",*(ptr+n));
print f("\n");
}
运行措施:
RUN
1234567890¿
2------output!
1234567890
#p#副标题#e#
[例6-7]回收数组名暗示的地点法输入输出数组各元素。
main()
{
int n,a[10],*ptr=a;
for(n=0;n<=9;n++)
scanf("%d",a+n);
print f("3------output!\n");
for(n=0;n<=9;n++)
print f("%4d",*(a+n));
print f("\n");
}
运行措施:
RUN
1234567890¿
3------output!
1234567890
[例6-8]用指针暗示的下标法输入输出数组各元素。
main()
{
int n,a[10],*ptr=a;
for(n=0;n<=9;n++)
scanf("%d",&ptr[n]);
print f("4------output!\n");
for(n=0;n<=9;n++)
print f("%4d",ptr[n]);
print f("\n");
}
运行措施:
RUN
1234567890
4----output!
1234567890
[例6-9]操作指针法输入输出数组各元素。
main()
{
int n,a[10],*ptr=a;
for(n=0;n<=9;n++)
scanf("%d",ptr++);
print f("5------output!\n");
ptr=a;/*指针变量从头指向数组首址*/
for(n=0;n<=9;n++)
print f("%4d",*ptr++);
print f("\n");
}
运行措施:
RUN
1234567890¿
5-----output!
1234567890
在措施中要留意*ptr++所暗示的寄义。*ptr暗示指针所指向的变量;ptr++暗示指针所指向的变量地点加1个变量所占字节数,详细地说,若指向整型变量,则指针值加2,若指向实型,则加4,依此类推。而print f(“%4d”,*ptr++)中,*ptr++所起浸染为先输出指针指向的变量的值,然后指针变量加1。轮回竣事后,指针变量指向如图6-6所示:
指针变量的值在轮回竣事后,指向数组的尾部的后头。假设元素a[9]的地点为1000,整型占2字节,则ptr的值就为1002。请思考下面的措施段:
#p#分页标题#e#
main()
{
int n,a[10],*ptr=a;
for(n=0;n<=9;n++)
scanf("%d",ptr++);
print f("4------output!\n");
for(n=0;n<=9;n++)
print f("%4d",*ptr++);
print f("\n");
}
措施与例6-9对比,只少了赋值语句ptr=a;措施的运行功效还沟通吗?
6.4.2 指针与二维数组
界说一个二维数组:
int a[3][4];
暗示二维数组有三行四列共12个元素,在内存中按行存放,存放形式为图6-7:
个中a是二维数组的首地点,&a[0][0]既可以看作数组0行0列的首地点,同样还可以看作是二维数组的首地点,a[0]是第0行的首地点,虽然也是数组的首地点。同理a[n]就是第n行的首址;&a[n][m]就是数组元素a[n][m]的地点。
既然二维数组每行的首地点都可以用a[n]来暗示,我们就可以把二维数组当作是由n行一维数组组成,将每行的首地点通报给指针变量,行中的其余元素均可以由指针来暗示。下面的图6-8给出了指针与二维数组的干系:
我们界说的二维数组其元素范例为整型,每个元素在内存占两个字节,若假定二维数组从1000单位开始存放,则以按行存放的原则,数组元素在内存的存放地点为1000~1022。
用地点法来暗示数组各元素的地点。对元素a[1][2],&a[1][2]是其地点,a[1]+2也是其地点。阐明a[1]+1与a[1]+2的地点干系,它们地点的差并非整数1,而是一个数组元素的所占位置2,原因是每个数组元素占两个字节。
对0行首地点与1行首地点a与a+1来说,地点的差同样也并非整数1,是一行,四个元素占的字节数8。
由于数组元素在内存的持续存放。给指向整型变量的指针通报数组的首地点,则该指针指向二维数组。
int *ptr,a[3][4];
若赋值:ptr=a;则用ptr++就能会见数组的各元素。
[例6-10]用地点法输入输出二维数组各元素。
#include<stdio.h>
main()
{
int a[3][4];
int i,j;
for(i=0;i<3;i++)
for(j=0;j<4;j++)
scanf("%d",a[i]+j);/*地点法*/
for(i=0;i<3;i++)
{
for(j=0;j<4;j++)
printf("%4d",*(a[i]+j));/**(a[i]+是j地)址法所暗示的数组元素*/
printf("\n");
}
}
运行措施:
RUN
1 2 3 4 5 6 7 8 9 10 11 12
1 2 3 4
5 6 7 8
9 10 11 12