指针与数组(二)
[例6-11]用指针法输入输出二维数组各元素。
#include<stdio.h>
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 <stdio.h>
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(temp<b[j]) temp=b[j];
return 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 <stdio.h>
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 ] ) ;
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 < = i – 1 ; j + + )
if(temp<b[j]) temp=b[j];
return temp;
}
在子措施中,形式参数是指针,挪用措施的实际参数p t r为指向一维数组a的指针,虚实结
合,子措施的形式参数b获得p t r的值,指向了内存的一维数组。数组元素回收下标法暗示,即
一维数组的头指针为b,数组元素可以用b [ j ]暗示。其内存中虚实参数的团结如图6 – 1 0所示。
运行措施:
R U N
1 3 5 7 9 2 4 6 8 0¿
m a x = 9
[例6-14] 上述措施的子措施中,数组元素还可以用指针暗示。
# include <stdio.h>
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 ] ) ;
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 + + ;
f o r ( j = 1 ; j < = i – 1 ; j + + )
if(temp<*b) temp=*b++;
return temp;
}
在措施中,赋值语句t e m p = * b + +;可以解析为:t e m p = * b;b + +;两句,先作t e m p = * b;后
作b + +;措施的运行功效与上述完全沟通。
对上面的措施作修改,在子措施中不只找最大元素,同时还要将元素的下标志录下来。
# include <stdio.h>
m a i n ( )
{
int *max();/* 函数声明* /
int n,a[10],*s,i;
f o r ( i = 0 ; i < 1 0 ; i + + ) / * 输入数据* /
scanf("%d",a+i);
s = m a x ( a , 1 0 ) ; / *函数挪用* /
p r i n t f ( " m a x = % d , i n d e x = % d \ n " , * s , s – a ) ;
}
int *max(a,n) / *界说返回指针的函数* /
int *a,n;
{
int *p,*t; / * p 用于跟踪数组,t用于记录最大值元素的地点* /
f o r ( p = a , t = a ; p – a < n ; p + + )
if(*p>*t) t=p;
return t;
}
在m a x()函数中,用p – a < n来节制轮回竣事, a是数组首地点, p用于跟踪数组元素的地点,p – a正好是所跟踪元素相对数组头的间隔,可能说是所跟踪元素相对数组头的元素个数,所以在m a i n ( )中,最大元素的下标就是该元素的地点与数组头的差,即s – a。运行措施:
R U N
1 3 5 7 9 2 4 6 8 0¿
m a x = 9 , i n d e x = 4
[例6-15] 用指向数组的指针变量实现一维数组的由小到大的冒泡排序。编写三个函数用于输入数据、数据排序、数据输出。
在第5章的例题中,我们先容过选择法排序及算法,此例再先容冒泡排序算法。为了将一组n个无序的数整理成由小到大的顺序,将其放入一维数组a [ 0 ]、a [ 1 ]. . .a [ n – 1 ]。冒泡算法如下:
(开序)
① 相邻的数组元素依次举办两两较量,即a [ 0 ]与a [ 1 ]比、a [ 1 ]与a [ 2 ]比. . . a [ n – 2 ]与a [ n – 1 ]比,通过互换担保数组的相邻两个元素前者小,后者大。此次完全的两两较量,能免实现a [ n – 1 ]成为数组中最大。
② 余下n – 1个元素,凭据上述原则举办完全两两较量,使a [ n – 2 ]成为余下n – 1个元素中最大。
③ 举办共计n – 1趟完全的两两较量,使全部数据整理有序。
下面给出一趟排序的处理惩罚进程:
#p#分页标题#e#
4个元素举办3次两两较量,获得一个最大元素。若相邻元素暗示为a [ j ]和a [ j + 1 ],用指针
变量P指向数组,则相邻元素暗示为* ( P + j )和* ( P + j + 1 )措施实现如下:
# include<stdio.h>
#define N 10
m a i n ( )
{
void input(); / *函数声明* /
void sort();
void output();
int a[N],*p; / *界说一维数组和指针变量* /
i n p u t ( a , N ) ; / *数据输入函数挪用,实参a是数组名* /
p = a ; / *指针变量指向数组的首地点* /
s o r t ( p , N ) ; / *排序,实参p是指针变量* /
o u t p u t ( p , N ) ; / *输出,实参p是指针变量* /
}
void input(arr,n) / *无需返回值的输入数据函数界说,形参a r r 是数组* /
int arr[],n;
{
int i;
printf("input data:\n");
for ( i = 0 ; i < n ; i + + ) / *回收传统的下标法*/
s c a n f ( " % d " , & a r r [ i ] ) ;
}
void sort(ptr,n) / *冒泡排序,形参ptr 是指针变量* /
int *ptr,n;
{
int i,j,t;
for ( i = 0 ; i < n – 1 ; i + + )
for ( j = 0 ; j < n – 1 – i ; j + + )
if (*(ptr+j)>*(ptr+j+1))/相*临两个元素举办较量*/
{
t = * ( ptr + j ) ; / *两个元素举办互换* /
* ( ptr + j ) = * ( ptr + j + 1 ) ;
* ( ptr + j + 1 ) = t ;
}
}
void output(arr,n) / *数据输出* /
int arr[],n;
{
int i,*ptr=arr; / *操作指针指向数组的首地点* /
printf("output data:\n");
for ( ; ptr – a r r < n ; ptr + + ) / *输出数组的n个元素* /
printf ( " % 4 d " , * ptr ) ;
printf ( " \ n " ) ;
}