第7章信息学院计算机基础组指针指针的基本概念指向数组的指针指针与函数指针数组本章主要内容:7.1引例例7-1:从键盘输入两个整型数据并求这两个整数之和。程序代码如下:#includestdio.hvoidmain(){intx,y,sumint*px,*py;px=&x;py=&y;scanf(%d%d,&x,&y);sum=*px+*py;/*用指针访问x,y的值*/printf(Sum=%d\n,sum);}直接访问原来的变量x,y的值进行运算的方式,称为直接引用;而使用指针访问数据的方式就称为间接引用。7.2.1指针变量的定义7.2指针变量的定义和引用–指针变量的定义一般形式:[存储类型]数据类型*指针名;合法标识符指针变量本身的存储类型指针的目标变量的数据类型表示定义指针变量不是‘*’运算符例int*p1,*p2;float*q;staticchar*name;注意:1、int*p1,*p2;与int*p1,p2;2、指针变量名是p1,p2,int*为变量p1,p2的类型3、指针变量只能指向定义时所规定类型的变量1.指针定义的初始化intx;int*px=&x;/*初始化*/2.指针的赋值运算intx;int*px;…px=&x;/*赋值运算*/7.2.2指针变量的引用指针运算*和取址运算&intx;int*px=&x;*px=5;…...…...2000200420062005整型变量x5变量px2001200220032000指针变量例7-2判断一个整数是否为偶数,用指针完成。程序代码如下:#includestdio.h{intx=10;charres;int*px;px=&x;/*将已定义的变量x的地址赋给指针px*/if(*px%2==0)res=’Y’;/*用指针运算访问指针px的目标变量,判断其奇偶性*/elseres=’N’printf(“%c”,res);}例main(){inti=10;int*p;*p=i;printf(“%d”,*p);}危险!main(){inti=10,k;int*p;p=&k;*p=i;printf(“%d”,*p);}–特别注意:指针变量p…...…...2000200420062005整型变量i10200120022003随机指向一块随机的空间指针变量必须先赋值,再使用7.2.3指针变量的应用程序代码如下:#includestdio.hvoidmain(){intx=10,y=20,*px,*py,t;px=&x;py=&y;printf(x=%d\ty=%d\n,x,y);t=*px;*px=*py;*py=t;printf(x=%d\ty=%d\n,x,y);}例7-3使用指针交换两个整型变量的值。若本问题写成7-4所示的形式,会怎样?程序代码如下:#includestdio.hvoidmain(){intx=10,y=20,t,*px,*py,*pt;px=&x;py=&y;pt=&t;printf(x=%d\ty=%d\n,x,y);pt=px;px=py;py=pt;printf(x=%d\ty=%d\n,x,y);}例7-4使用指针交换两个整型变量的值。intm[5]={0};int*p;p=&m[0];指针加减一个常数运算对于指向某个数组元素的指针,当指针加减一个常数a时,不是进行简单的加减a的操作,而是将指针的指向移动了a个元素,即指针加减了a*sizeof(数组元素)。例如:p+1m[1]p+3m[3]7.3指针与数组7.3.1指向数组元素的指针m[i]p[i]*(m+i)*(p+i)可见,引用数组元素可以有指针法和下标法两类方法,如下四种情况:指针法和下标法例7-6将含有8个元素的整型数组中的每个元素值增1后输出。程序代码如下:#includestdio.hvoidmain(){inti,a[8]={1,2,3,4,5,6,7,8};int*pa;for(pa=a;paa+8;pa++)/*指针pa做循环控制变量*/*pa=*pa+1;/*用pa引用各元素*/pa=a;for(i=0;i8;i++)printf(“%d”,*pa);}pa第一个循环结束后pa7.3.2指针和字符串程序代码如下:#includestdio.hvoidmain(){charstr[128],*cp;intdigit=0;gets(str);for(cp=str;*cp!='\0';cp++)if(*cp='0'&&*cp='9')digit++;printf(Thenumberofdigitis%d,digit);}例7-7从键盘输入一个字符串,统计其中数字字符的个数。用字符指针处理字符串的几种形式:1.字符指针指向字符数组charstr[128],*cp;cp=str;2.直接用字符串为字符指针初始化char*s=CharacterPoint;3.字符指针定义后,用字符串为其赋值。char*s;s=CharacterPoint;7.3.3指针与二维数组的关系程序代码如下:#includestdio.hvoidmain(){inti;inta[4][3]={{1,5,9},{2,6,10},{3,7,11},{4,8,12}};int*p=&a[0][0];for(i=0;i12;i++)printf(%3d,*(p+i));}1.指向二维数组元素的指针例7-9用指向二维数组元素的指针输出数组全部元素。7.3.3指针与二维数组的关系2.指向一行元素的指针类型说明符(*指针名)[M];指向一行元素的指针,也就是指向了一个由多个元素组成的一维数组,这种指针称为行指针。相应的,原来的指向数组元素的指针就对应的称为列指针。行指针定义的基本形式如下:行指针的运算1)行指针加减常数运算:2)行指针与列指针的相互转换:3)行指针的赋值运算inta[4][3];int(*p)[3];p=a例7-10使用行指针输出例7-9数组的全部元素。程序代码如下:#includestdio.hvoidmain(){inti,j,x[4][3]={{1,5,9},{2,6,10},{3,7,11},{4,8,12}};int(*p)[3];p=x;/*行指针常量x赋值给行指针变量p*/for(i=0;i4;i++)for(j=0;j3;j++)printf(%3d,*(*(p+i)+j));}行指针转换成列指针用于访问二维数组元素:程序代码如下:#includestdio.hvoidmain(){inti,j,x[4][3]={{1,5,9},{2,6,10},{3,7,11},{4,8,12}};int(*p)[3];p=x;/*行指针常量x赋值给行指针变量p*/for(i=0;i12;i++)printf(%3d,*(*p+i));}7.4指针与函数7.4.1指针作为函数的参数程序代码如下:#includestdio.hvoidswap(int*x,int*y)/*指针作为函数的参数*/{intz;z=*x;*x=*y;*y=z;}voidmain(){inta,b;scanf(%d%d,&a,&b);printf(A=%d\tB=%d\n,a,b);swap(&a,&b);printf(A=%d\tB=%d\n,a,b);}例7-11编写函数,交换两个变量的值。例7-12编写函数,计算Fibonacci数列前20项,并在主函数中输出程序代码如下:#includestdio.h{int*px,x[20]={1,1},i;px=x;voidGenFib(int*m);GenFib(px);for(i=0;i20;i++)printf(%d,x[i]);}voidGenFib(int*m){inti;for(i=2;i20;i++)*(m+i)=*(m+i-1)+*(m+i-2);}指针或数组作函数参数的各种调用形式本质上是:地址作函数的参数7.4.2返回值为指针的函数类型说明符*函数名(形参表){函数体}基本形式如下:例7-13求某个一维数组所有元素中最大值的下标,用返回指针值的函数来实现。程序代码如下:#includestdio.h#includestdlib.hint*MaxValue(intt[],intn){int*p=t;inti;for(i=0;in;i++)jif(*pt[i])p=&t[i];returnp;}voidmain(){intx[5][5],j,k,*pl=x[0];int(*px)[5]=x;for(j=0;j25;j++)*pl++=rand();for(j=0;j5;j++,px++){pl=MaxValue(*px,5);printf(%d\t,*pl);}}7.4.3函数指针类型说明符(*指针变量名)(参数列表)指向函数的指针存放的是某个函数的首地址,这种能够保存函数地址的指针也称为函数指针。定义函数指针的一般形式如下:(*指针变量名)(实参列表)函数指针在调用时的一般形式如下:例7-14定义两个函数,分别求和与求差,使用函数指针调用函数求解。程序代码如下:#includestdio.hintsub(intx,inty){returnx-y;}intadd(intx,inty){returnx+y;}voidmain(){inta=3,b=9,j;int(*p)(int,int);p=add;j=(*p)(a,b);printf(Add=%d\n,j);p=sub;a=-7;b=4;j=(*p)(a,b);printf(Sub=%d\n,j);}7.5指针数组和指向指针的指针7.5.1指针数组指针数组定义的一般形式如下:类型说明符*指针变量名[数组元素个数]例7-15给指针数组赋值程序代码如下:#includestdio.hvoidmain(){intx[3]={123,456},y[2][2]={7,8,9},z=10,i;int*px[5];px[0]=x;px[1]=&x[1];px[2]=y[0];px[3]=&y[1][0];px[4]=&z;for(i=0;i5;i++)printf(%d\t,*px[i]);}例7-16用字符指针数组完成多个字符串的打印程序代码如下:#includestdio.hvoidmain(){inti;charch[3][128]={ThisisaPoint,ThisisaString,ItisaArray};char*cp[4];chars='A';for(i=0;i3;i++)cp[i]=ch[i];cp[3]=&s;for(i=0;i3;i++)puts(*(cp+i));putchar(*cp[3]);}7.5指针数组和指向指针的指针7.5.2指向指针的指针指向指针的指针变量定义的一般形式为:类型说明符**指针变量名指针的指针、指针以及普通变量之间的关系:指向指针的指针变量基本用法例7-17#includestdio.hvoidmain(){intx[5]={1,3,5,7,9},y[2][2]={2,4,6,8},z=10;int*px,*py,*pz,**p;inti,j;pz=&z;p=&pz;printf(*pz=%d\t**p=%d\t*(*p)=%d\n,*pz,**p,*(*p));px=x;p=&px;for(i=0;i5;i++)printf(%d\t,*(*p+i));printf(\n);py=y[0];p=&py;接下页指向指针的指针变量基本用法for(i=0;i2;i++){for(j=0;j2;j++)printf(%d\t,*(*p+i*2+j));printf(\n);}for(i=0;i2;i++){py=y[i];p=&py;for(j=0;j2;j++)printf(%d\t,*(*p+j));printf(\n);}}7.5指针数组