指针田黎育C程序设计中使用指针可以:▲使程序简洁、紧凑、高效▲动态分配内存▲得到多于一个的函数返回值指针的概念◆变量与地址程序中:inti;floatk;内存中每个字节有一个编号-----地址…...…...2000200120022005内存02003ik编译或函数调用时为其分配内存单元变量是对程序中数据存储空间的抽象…...…...2000200420062005整型变量i10变量i_pointer200120022003◆指针与指针变量指针:一个变量的地址指针变量:专门存放变量地址的变量叫~2000指针指针变量变量的内容变量的地址指针变量变量变量地址(指针)变量值指向地址存入指针变量数组与指针的关系数组中的每个元素都可以通过下标唯一确定,即通过下标可以访问(操作)数组中的元素,称为下标方式(直接访问)。在C语言中,凡是可以通过数组下标方式完成的访问(操作)均可以通过指针方式实现。称为指针方式(间接访问)。§1数组与指针概念复习假设:inta[100];数组名:数组的标识a数组元素的地址:数组中1个具体元素的地址(&a[k])数组首地址(数组起始地址):数组中第1个元素(0号元素)的地址(&a[0]或用数组的名称a表示)。C语言规定:数组名就是数组的首地址常量。那么下面关系表达式成立:a==&a[0]§1数组与指针例:分析程序。#includestdio.hmain(){inta[]={1,2,3,4,5};intx,y,*p;/*指针变量p*/p=&a[0];x=*(p+2);y=*(p+4);printf(*p=%d,x=%d,y=%d\n,*p,x,y);}§1数组与指针/*指针p指向a[0],等价于p=a*//*取指针p+2的内容,等价于x=a[2]*//*取指针p+4的内容,等价于y=a[4]*/指针方式数组a*(p)=1*(p+1)=2*(p+2)=3*(p+3)=4*(p+4)=5&a[0]pp+2p+4下标方式a[2]a[1]a[0]a[3]a[4]指针方式数组a*(a+0)=1*(a+1)=2*(a+2)=3*(a+3)=4*(a+4)=5aa+2a+4例:分析程序。main(){inta[]={1,2,3,4,5,6};int*p;p=a;/*指针p为数组的首地址*/printf(%d,*p);printf(%d\n,*(++p));printf(%d,*++p);printf(%d\n,*(p--));p+=3;printf(%d%d\n,*p,*(a+3));}§1数组与指针指针初始化第一个输出第二个输出第三个输出第四个输出第五个输出p=a取p的内容p先加1再取内容p先加1再取内容取内容p再减1取p的内容p+=3pppppp12指针初始化345aa+1a+2a+3a+4a[0]a[1]a[2]a[3]a[4]语句执行指针p指向地址数组在函数之间传递整个数组◆实际参数用数组名。◆形式参数可以使用数组名或者指针。当形式参数使用指针时,在被调用函数的内部,就可用指针方式访问数组中的元素。特别说明◆由于数组名代表数组的首地址,传递数组名也就是将数组的首地址传递给被调用函数。§1数组与指针例:编写字符串复制函数。main(){chara[30],b[30];printf(Enterstring:);scanf(%s,a);strcopy(a,b);/*调用函数的实参为数组名*/printf(a=%s\nb=%s\n,a,b);}strcopy(str1,str2)/*将串str1拷贝到串str2中*/char*str1,*str2;/*形参为指向字符的指针*/{while((*str2=*str1)!=’\0’)/*通过指针操作数组*/{str1++;str2++;}}§1数组与指针-串复制例:改进字符串复制函数。改进一:strcopy(str1,str2)char*str1,*str2;{while(*str2=*str1){str1++;str2++;}}改进二:strcopy(str1,str2)char*str1,*str2;{while(*str2++=*str1++);/*通过指针操作数组*/}§1数组与指针-串复制对于指针的三种基本运算◆指针与正整数的加减运算◆两个指针的关系运算◆两个指针的减法运算与指针相关的运算操作◆取地址运算(&)◆取内容运算(*)§2指针的基本运算指针与正整数的加减法当指针p指向数组中的元素时,n为正整数:p+n表示:指针p所指向当前元素之后的第n个元素p-n表示:指针p所指向当前元素之前的第n个元素p++和++p含义:指针加1,指向数组中的下一个元素p--和--p含义:指针减1,指向数组中的前一个元素§2指针的基本运算-指针加减运算p-2p-1pp+1p+2............p-33002001000-100............400数组低地址高地址运行程序,分析运行结果。#include”stdio.h”#defineSIZE4main(){intdates[SIZE],*pti,index;floatbills[SIZE],*ptf;pti=dates;ptf=bills;for(index=0;indexSIZE;index++)printf(”pointer+%d:%10x%10x”,index,pti+index,ptf+index);}放大因子◆由于指针所指的对象不同,在进行加减运算时,C语言会根据所指对象计算出不同的放大因子。◆对于char,放大因子为1;对于int,放大因子为2;对于long,放大因子为4;对于double,放大因子为8。§2指针的基本运算-放大因子两个指针之间的关系运算◆当两个指针指向同一个数组中的元素时,才能进行、、=、=、!=、==的关系运算。◆例如:当指针p和指针q指向同一数组中的元素时,则:关系表达式“pq”:当p所指的元素在q所指的元素之前时,表达式成立;反之,表达式不成立。关系表达式“p==q”:当p和q指向同一元素时,表达式成立;反之,表达式不成立。◆任何指针p与NULL进行“P==NULL”或“P!=NULL”运算均有意义:判断指针p是否指向空。§2指针的基本运算-指针之间的关系运算例:编写函数,实现串反向。revstr(char*s)/*将串s反向*/{char*p=s,c;while(*p)p++;/*找到串结束标记'\0'*/p--;/*指针p指向串中的最后一个字符*/while(sp)/*当串前面的指针s串后面的指针p时*/{c=*s;/*交换两个指针所指向的字符*/*s++=*p;/*指针s向后(+1)移动,先赋值再+1*/*p--=c;/*指针p向前(-1)移动,先赋值再-1*/}}§2指针的基本运算-串反向两个指针之间的减法运算◆当两个指针指向同一数组中的元素时,才能进行指针间的减法运算,当两个指针分别指向不同数组的元素时,无意义。◆当两个指针指向同一数组中的元素时,p-q的物理意义是:指针p和q所指对象之间的元素的数量。§2指针的基本运算-求串长例:编写函数,求字符串的长度。strlen(char*s)/*求串s的长度*/{char*p=s;while(*p)p++;/*找到串结束标记\0*/return(p-s);/*两个指针相减法,求出串长*/}§2指针的基本运算-求串长abcdef\0sp=s+6串长=6指针数组数组中的元素均为指针类型,称之为指针数组。指针数组说明的形式为:数据类型*数组名[常量表达式]例如:int*pa[6];含义:定义一个由6个指针变量构成的指针数组,数组中的每个数组元素━━指针,都指向一个整数。§3指针数组整数整数整数整数整数整数pa[0]pa[1]pa[2]pa[3]pa[4]pa[5]指针数组pa数组指针指向数组的指针称为数组指针。数组指针的说明形式:数据类型(*指针变量名)[常量表达式]例如:int(*pb)[6];含义:定义了一个指向数组的指针pb,被指向的数组是一维的有6个元素的整型数组。§3指针数组整数整数整数整数整数整数(*pb)[0](*pb)[1](*pb)[2](*pb)[3](*pb)[4](*pb)[5]pbpb[1]是地址例:将week_day表用指针数组实现。char*week_day[8]={sunday,monday,tuesday,wednesday,thursday,friday,saturday,NULL};§3指针数组-输入字符串进行查找sunday\0monday\0tuesday\0friday\0thursday\0saturday\0wednesday\0数组week_dayweek_day[0]week_day[1]week_day[2]week_day[3]week_day[4]week_day[5]week_day[6]week_day[7]NULLweek_day在内存中的存放例:用指针数组实现输入字符串查找是星期几。char*week_day[8]={sunday,monday,tuesday,wednesday,thursday,friday,saturday,NULL};main(){intl;charstring[20];printf(Enterastring:);scanf(%s,string);l=lookup(string);printf(l=%d\n,l);}lookup(charch[])/*传递字符串(字符数组)*/{inti,j;char*pc;for(i=0;week_day[i]!=NULL;i++)/*完成查找工作*/{for(pc=week_day[i],j=0;*pc==ch[j]&&*pc!='\0';j++,pc++);if(*pc==ch[j]&&*pc=='\0’)return(i);/*找到*/}return(-1);/*若没有找到,则返回-1*/}§3指针数组-输入字符串进行查找main函数的参数main函数参数的一般形式:main(argc,argv)intargc;/*argc表示命令行参数个数*/char*argv[];/*argv指向命令行参数的指针数组*/在运行C程序时,可以使用命令行参数,向程序(main函数)传递参数。命令行参数的一般形式:运行文件名参数1参数2……参数n......argv[0]argv[1]argv[2].....argv[argc-1]文件名第1个参数第2个参数......第argc-1(n)个参数数组argv§3指针数组-main函数参数argc=n+1例:按数组方式引用命令行的参数。#includestdio.hmain(argc,argv)intargc;char*argv[];{inti;printf(argc=%d\n,argc);for(i=0;iargc;i++)printf(”%s\n”,argv[i]);/*按数组方式引用参数*/}§3指针数组-main函数参数实例例:按指针方式引用命令行的参数。#includestdio.hmain(argc,argv)intargc;char*argv[];{inti;for(i=0;iargc;i++)printf(”%s\n”,*argv++);/*按指针方式引用参数*/}有关指针的数据类型和指针运算小结int*p;int*q[4];int(*w)[4];int*g();int(*y)();p是一个指向整型数据的指针变量根据优先级,q先和[]结合,所以q是一个指针数组,该数组有4个元素。()内的*w指示出w是一个指针,指向一个含4个元素的一维数组。w是数组指针。根据优先级,g先和()结合,所以g是一个函数,*说明函数的返回值是指向整型数据的指针。(*y)说明y是一个指针,()表明此指针是指向函数的,函数的返回值是整型。申请内存函数(malloc)void*mall