资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,第五章 指 针,Chapter 5 Pointer,第五章 指 针,Pointer,5.1,指针的概念,指针,是,C,语言的重要特征,是,C,语言访问内存数据和程序的灵活,和有效的手段。,C,语言的指针支持:,函数的地址调用;,动态分配内存;,数组的地址引用。,内存、地址、指针,(Memory,Address,Pointer),内存,存放了计算机正在运行的程序和程序正在使用的数据。内,存的基本单元是字节,(Byte),。,为了访问内存单元,,CPU,给每个内存单元一个编号,该编号称,为该内存单元的,地址,。,变量,是程序中可以改变的量,当说,明变量时,系统将为其在内存中开辟相,应得内存单元。由此确定变量的,地址,及,内存中的表示方式。,2000H,2001H,2002H,2003H,int a=0;,a,的,内,存,单,元,a,的地址,&a,如果有一变量,p,,,其内容存放了,a,的,地址,&a,,,通过,p,也可实现对,a,的访问,,p,称为指针,并指向,a,。,00H,20H,0,0,p,指针的说明,指针是特殊类型的变量,其内容是变量的地址。,在使用前必须,说明,说明某标识符是指针类型,并可指向某种类型的对象。,指针的说明格式:,type,*,pname1,*,pnamen,;,标识符命名的指针变量名。,指针标志。,指针指向对象的类型。,int *p,*q;,/*p,、,q,是指向整型变量的指针。*,/,float *pfValue,*pf;,/*pfValue,和,pf,是指向浮点型的指针。*,/,指针对变量的引用,定义指针的目的是通过指针引用内存对象,,,指针的引用应按如,下步骤进行:,说明指针,int a=0,*p;,指针指向对象,p=,通过指针引用对象,*p=*p+2;,指针操作的两种运算,:,取地址运算,&a,表示取变量,a,地址的运算。,间接运算 *,p,表示取指针,p,指向变量内容的运算。,int a,*p;,2000H,a,p,p=/*p,指向,a,。*,/,2000H,*p=2;,2,举例:,#include,void main(void),int x,*p;,x=55;,p=,printf(“%d,%u”,x,*p);,*p=65;,printf(“%d,%u”,x,*p);,2000H,x,p,2000H,55,65,关于指针的说明:,指针必须指向对象后,才能引用。,int *p;*p=2;/*Error!*/,&,和,*,为互补运算。,int a,*p;,p=,则:,&,*,p,p,*,&,a,a,指针的运算,指针是,特殊类型,的变量,其内容是,变量的地址,,因此,指针的运,算及结果一定要符合地址逻辑。,五种算术运算,int,a,b,*p1,*p2;,p1,=,p2,=,a,2000H,b,2400H,p1,p2,2000H,2400H,p1+;/*,含义指向,a,后的整型单元*,/,2002H,2002H,p1-;/*,指向,a,前的整型单元*,/,p1+n;/*,指向,a,后的第,n,个整型单元*,/,p1-n;/*,指向,a,前的第,n,个整型单元*,/,p2-p1;/*a,和,b,之间差的单元数*,/,结果,200H,p n,相当于,:,p,的实际内容,n,sizeof(*p);,六种关系运算,比较两个同类型变量之间的地址关系。,p1p2;,指针赋值运算,#include,void main(void),int a,b,*p1,*p2;,a=2;,b=3;,p1=,p2=,*p1=*p2;,printf(“%d,%dn”,a,b);,a=3;,b=5;,p1=p2;,printf(“%d,%d,”,*p1,*p2);,差别,a,&a,2000H,b,&b,2400H,p1,p2,2,3,2000H,2400H,5.2,指针与数组,数组是同类型的变量的集合,各元素按下标的特定顺序占据一,段连续的内存,,各元素的地址也连续,,指针对数组元素非常方便。,指针与一维数组,通过指针引用数组元素可以分以下三个步骤:,说明指针和数组,int *p,a10;,指针指向数组,p=a;/*,指向数组的首地址*,/,p=/*,指向数组的首地址*,/,通过指针引用数组元素,当指针指向数组的首地址时,则下标为,i,的元素地址为:,p+i,或,a+i,引用数组元素可以有三种方法:,下标法:,a i,指针法:*,(p+i),数组名法:*,(a+i),注意:数组名是地址常量,不能改变!,a=p;/*Error!*/,举例:打印数组中的奇数。,#include ,void main(void),int i,a 10;,for(i=0;i10;i+),scanf(“%d”,for(i=0;i10;i+),if (,a i%2,)printf(“%d”,a i);,数组元素法。,循环输入。,循环判断,满足条件输出。,数组名法。,a+i,*(a+i),指针法。,*p;,p=a;,p+,*(p+i),结果是否,正确?,p=a;*p=*,注意指针在运算时的变化。,指针与字符串(字符数组),字符串在内存中可以存储为两种形式:,字符数组,字符串常量,可以使指针指向字符数组或字符串常量,通过指针引用字符数,组或字符串的各个字符。,指针与字符数组:,char *,chp,str,=”Hello!”;,/*,说明字符指针和字符数组*,/,chp,=,str,;,/*,指针指向字符数组*,/,putchar(*(chp+2);,/*,通过指针引用数组元素*,/,指针与字符串:,char *,strp,;,/*,说明字符指针*,/,strp,=“Hello!”;,/*,指针指向字符串*,/,puts(strp,);,/*,通过指针引用字符串*,/,说明指针时,可以同时赋初值,如:,char *,strp,=“Hello!”;,赋值表示将字符串的地址赋给指针!,举例:将字符串中的大写字母转化对应的小写字母。,#include ,void main(void),char,*p,s80;,p=s;,gets(p);,for(;*p!=0,;p+),if(*p=A&*p=Z),*p+=32;,p=s;,puts(p);,将无符号的八进制字符串转换为十进制整数。,#include ,void main(void),char,*p,s6;,int i,n=0;,p=s;,gets(p);,for(;*p!=0;p+),n=n*8+*p-0;,printf(“%dn”,n);,p,指向,s,数组。,输入字符串。,s,p,s,5,5,6,0,n=0*8+5-0,5,n=5*8+5-0,45,n=45*8+6-0,366,Chap5ex5,思考题:将,4,位十六进值字符串转化为十进制字符串。,二维数组的地址,如下说明数组,int,a34=1,2,3,4,5,6,7,8,9,10,11,12;,其二维结构如下:,1,2,3,4,5,6,7,8,9,10,11,12,行,列,为了便于索引,,C,语言将数组分为两级管理。,a0,a1,a2,将,a,理解为一维数组,数组有三个元素,它们分别为,a0,、,a1,,,a2,。,各个元素又是一个有四个元素的一维数组。,从地址的角度看:,a,为,a0,第一行的首地址,a+1,为,a1,第二行的首地址,a+2,为,a2,第三行的首地址,a+1,地址一次加一行。,i,行,j,列数组元素的地址可以由,a i+j,得到。,数组名地址的两级管理,a,a0,a1,a2,a0,0,a0,1,a0,2,a0,3,a1,0,a1,1,a1,2,a1,3,a2,0,a2,1,a2,2,a2,3,等价地址及其管理方式,数组名是数组的地址,而且是常量,*运算不改变其值!,以下三种地址等价:,a+i,*(a+i),a i,加法按行递增,加法按列递增,(a+1)+1,*(a+1)+1,差别?,数组名表示数组元素,a i j,(*(,a+i,)j,*(,*(a+i),+j),*(a i+j),指针与二维数组,int *p,a34;,p=a;,aij,*(p+4*i+j),等价!,a00,a,a01,a02,a0,a10,a11,a12,a1,a20,a21,a22,a2,a+1,a1+2,举例:在数组,a,中查找输入的数,输出行列位置。,#include ,void main(void),int,a34=1,2,3,4,5,6,7,8,9,10,11,12;,int i,j,iS;,int *p;,p=a;,scanf(“%d”,for(i=0;i3;i+),for(j=0;j4;j+),if(iS=,a i j,),printf(“iS equal to a%d%d n”,i,j);,下标法。,*(a i+j),*(*(a+i)+j),*(p+4*i+j),5.3,指 针 数 组,指针是存放其它数据对象地址的,变量,。因此,指针可以构成,数,组,。每个数组元素为一个指针变量,且在内存中连续存放。,指针数组的说明,说明格式:,type,*,数组名,const exp,;,int *p 4;,含义是,在内存中开辟空间,并指明元素所指向的对象的类型。,p 0,p 1,p 2,p 3,数组名,p,为数组的地址。,使用前必须让各元素指向对象。,int i,a34,*p3;,for(i=0;i3;i+),p i,=a i;,*(,p2,+1)=2;/*,通过指针数组引用数组元素,a21*/,指针数组的应用举例,指针数组与多维数组,通过指针数组按数学方式输出数组的值。,#include,void main(),int i,j;,int,a34=1,2,3,4,5,6,7,8,9,10,11,12;,int *p3;,p0=a0;p1=a1;p2=a2;,for (i=0;i3;i+),for(j=0;j4;j+),printf(“%5d”,*(pi+j);,printf(“n”),;,1,2,3,4,5,6,7,8,9,10,11,12,p0,数组,a,的二维结构,p1,p2,a0,a1,a2,每输出一行,打印回车。,指针数组与多字符串,通过指针数组构成的菜单,执行,DOS,命令。,#include,void main(void),char*command =“dir”,“time”,“date”,ch;,for(;),do,printf(“1:directoryn”);,printf(“2:set timen”);,printf(“3:set daten”);,printf(“4:quitn”);,printf(nselection:”);,ch=getchar();,printf(“n”);,while (ch4);,if(ch=4)break;,system,(commandch-1);,内层循环输入选项,外层循环根据选项执行命令,执行系统命令函数,如,:system(“dir”);,d,i,r,0,t,i,m,e,0,d,a,t,e,0,command0,command1,command2,3-1 2,Chap5ex3,5.4,指向指针的指针,如果指针变量的内容存放其它指针的地址,称该指针为指向指,针的指针。,指向指针的指针的说明:,形式:,type *p;,int *p;,p,是一个指向整形指针的,指针,。,#include ,void main(void),int x,*p,*q;,x=10;,p=,q=,printf(“%d”,*,*,q);,p,为指向整型的指针。,q,为指向整型指针的指针。,x,p,q,2000H,3000H,10,2000H,3000H,指向指针的指针的应用,指向指针的指针一般用于多维数组和指针数组的操作。,多维数组,#include,void main(),int,a34=1,2,3,4,5,6,7,8,9,10,11,12,;,i
展开阅读全文