Chinaunix首页 | 论坛 | 博客
  • 博客访问: 104633518
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类: C/C++

2008-04-16 21:47:24

 来源:


变量在内存存放是有地址的,数组在内存存放也同样具有地址。对数组来说,数组名就是数组在内存安放的首地址。指针变量是用于存放变量的地址,可以指向变量,当然也可存放数组的首址或数组元素的地址,这就是说,指针变量可以指向数组或数组元素,对数组而言,数组和数组元素的引用,也同样可以使用指针变量。下面就分别介绍指针与不同类型的数组。
6.4.1指针与一维数组
假设我们定义一个一维数组,该数组在内存会有系统分配的一个存储空间,其数组的名字就是数组在内存的首地址。若再定义一个指针变量,并将数组的首址传给指针变量,则该指针就指向了这个一维数组。我们说数组名是数组的首地址,也就是数组的指针。而定义的指针变量就是指向该数组的指针变量。对一维数组的引用,既可以用传统的数组元素的下标法,也可使用指针的表示方法。
inta[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
main()
{
intn,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
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
[例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。请思考下面的程序段:
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指针与二维数组
定义一个二维数组:
inta[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
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
[例6-11]用指针法输入输出二维数组各元素。
#include
main()
{
int a[3][4],*ptr;
int i,j;
ptr=a[0];
for(i=0;i<3;i++)
for(j=0;j<4;j++)
scanf("%d",ptr++);/*指针的表示方法*/
ptr=a[0];
for(i=0;i<3;i++)
{
for(j=0;j<4;j++)
printf("%4d",*ptr++);
printf("\n");
}
}
运行程序:
RUN
1 2 3 4 5 6 7 8 9 10 11 12
1 2 3 4

6.4.3 数组指针作函数的参数
学习了指向一维和二维数组指针变量的定义和正确引用后,我们现在学习用指针变量作
函数的参数。
[例6-12] 调用子程序,实现求解一维数组中的最大元素。
我们首先假设一维数组中下标为0的元素是最大和用指针变量指向该元素。后续元素与该
元素一一比较,若找到更大的元素,就替换。子程序的形式参数为一维数组,实际参数是指
向一维数组的指针。
# include
m a i n ( )
{
int sub_max(); / * 函数声明* /
int n,a[10],*ptr=a; / *定义变量,并使指针指向数组* /
int max;
f o r ( n = 0 ; n < = i - 1 ; n + + ) / *输入数据* /
s c a n f ( " % d " , & a [ n ] ) ;
m a x = s u b _ m a x ( p t r , 1 0 ) ; / * 函数调用,其实参是指针* /
p r i n t f ( " m a x = % d \ n " , m a x ) ;
}
int sub_max(b,i) / * 函数定义,其形参为数组* /
int b[],i;
{
int temp,j;
t e m p = b [ 0 ] ;
f o r ( j = 1 ; j < = 9 ; j + + )
if(tempreturn temp;
}
程序的m a i n ( )函数部分,定义数组a 共有1 0个元素,由于将其首地址传给了p t r,则指针
变量ptr 就指向了数组,调用子程序,再将此地址传递给子程序的形式参数b,这样一来,b
数组在内存与a 数组具有相同地址,即在内存完全重合。在子程序中对数组b 的操作,与操
作数组a 意义相同。其内存中虚实结合的示意如图6 - 9所示。
m a i n ( )函数完成数据的输入,调用子程序并输出运行结果。s u b _ m a x ( )函数完成对数组元
素找最大的过程。在子程序内数组元素的表示采用下标法。运行程序:
R U N
1 3 5 7 9 2 4 6 8 0
m a x = 9
[例6-13] 上述程序也可采用指针变量作子程序的形式参数。
# include
m a i n ( )
{
int sub_max();
int n,a[10],*ptr=a;
int max;
f o r ( n = 0 ; n < = 9 ; n + + )
s c a n f ( " % d " , & a [ n ] ) ;

阅读(226) | 评论(0) | 转发(0) |
0

上一篇:指针的地址分配

下一篇:指针与数组(2)

给主人留下些什么吧!~~