c语言课件 第九章.ppt

上传人:sccc 文档编号:5383314 上传时间:2023-07-01 格式:PPT 页数:90 大小:861.01KB
返回 下载 相关 举报
c语言课件 第九章.ppt_第1页
第1页 / 共90页
c语言课件 第九章.ppt_第2页
第2页 / 共90页
c语言课件 第九章.ppt_第3页
第3页 / 共90页
c语言课件 第九章.ppt_第4页
第4页 / 共90页
c语言课件 第九章.ppt_第5页
第5页 / 共90页
点击查看更多>>
资源描述

《c语言课件 第九章.ppt》由会员分享,可在线阅读,更多相关《c语言课件 第九章.ppt(90页珍藏版)》请在三一办公上搜索。

1、共 90 页 第 1 页,第九章 指 针,C语言程序设计,共 90 页 第 2 页,本 章 要 点,1.理解指针与地址的概念;2.掌握指针的定义和运算;3.掌握指向基本类型、数组、字符串的指针的使用;4.充分理解指针和数组的等价性;5.掌握指针函数和函数指针的使用;6.了解指向指针的指针的概念及其使用。,共 90 页 第 3 页,预 备 知 识,内存:就是内部存储器,是由存储单元组成 的。它的特点是存储单元是线性连续 的。存储单元的最小单位是字节。,1.内存的概念,共 90 页 第 4 页,地址:为了访问内存中的某个存储单元,我们 要为它编号,这种编号称为内存地址。通过地址我们就能够访问该地址

2、所标 识的存储单元。,2.地址的概念,共 90 页 第 5 页,变量的地址:变量的地址是变量在内存中占用连续字节的首地址。,2007,存储单元,共 90 页 第 6 页,以往对变量的访问:定义变量:int k;编译系统根据类型为k分配内存。输入变量的值:scanf(“%d”,通过指针间接访问:C提供了另一种方式,将变量 k的地址存放在另一个变量处(假定为pk),通过访问 pk,就可以间接地访问变量 k,这种方式称为间接访问。,变量的存取方法:直接存取和间接存取。,共 90 页 第 7 页,引入指针程序设计的优点,有效表示复杂的数据结构。方便使用字符串、数组。可以得到多个返回值。可以进行动态分配

3、内存。程序简洁、紧凑,执行效率高。,共 90 页 第 8 页,9.1.1 指针的基本概念,指针:一个变量的地址称为该变量的指针。指针变量:若一个变量专用于存放另一个变量的地址(指针),则称此变量为指针变量。若指针变量p的值等于变量x的地址,则说指针变量p指向变量x。,1000,35,1000,p,x,x的值,p的值,X的内存地址,9.1 指针的基本概念及指针变量的定义,共 90 页 第 9 页,指针的对象:当把变量的地址存入指针变量后,就可以说这个指针指向了该变量。,共 90 页 第 10 页,9.1.2 指针变量的定义,指针变量定义的一般形式:类型标识符*标识符,例:float*p1;int

4、*p2;作用:定义变量为指针类型,使之专门用于存放地址。,指针所指的变量的类型,指针变量名,共 90 页 第 11 页,说明:,(1)*用于定义指针变量,但指针变量名不带*。如 int*p1;float*p2;定义的指针变量为p1,p2(2)一个指针变量只能指向同一类型的变量。如 p1 只能用于指向整型变量 p2 只能用于指向实型变量(3)无论指针变量指向何种类型,指针变量本身都是整型的,指针变量本身也有自己的地址,占两个字节的存储空间。,共 90 页 第 12 页,1.取地址运算&,格式:让p指向b,使q指向a,p指向b,9.2 指针变量的引用和运算,C语言提供两种与指针有关的运算符:&*,

5、共 90 页 第 13 页,2.取内容运算*,格式:*指针表达式设p是一个指针表达式,则:(1)若*p出现在赋值号左边,表示给p所指变量赋值(2)若*p不出现在赋值号左边,表示p所指变量的值 若有变量说明:int a,*p;p=给变量a输入值*p+25 等价于a+25,共 90 页 第 14 页,3.为指针变量赋初值,指针变量使用前必须有值,指针变量的初值必须是地址值(不能是整数),方法:,在说明指针变量时同时初始化 int a,*p=,可以为指针赋空值(NULL),此时指针不指向任何 变量,如 p=NULL或 p=0;p=0;(p为空指针),共 90 页 第 15 页,对*及&的说明:(同级

6、运算,由右向左),若pa=&a(将 a 的地址送指针变量pa),则&*pa&(*pa)&(a)&a*&a*(&a)*pa a(*pa)+a+*pa+*(pa+)(先取*pa值,然后使pa加1)*+pa*(+pa)(先使pa加1,再取*pa值),注意:此时pa不再指向a,共 90 页 第 16 页,例 9-1 输出变量的值。main()int a,b;int*pa,*pb;a=100;b=10;pa=,定义指针变量pa,pb,将a的地址送pa,将b的地址送pb,输出所指向的变量,运行结果为100,10100,10,共 90 页 第 17 页,例9-2将两个整型数a,b按由大到小次序输出。,mai

7、n()int*p1,*p2,*p,a,b;scanf(“%d,%d”,注意:a和b并未交换,但p1和p2的值交换了,运行情况:5,9a=5,b=9larger=9,little=5,共 90 页 第 18 页,在C语言中,凡是可以通过数组下标方式完成的访问(操作)均可以通过指针方式实现。称为指针方式。,9.3指针与数组,数组中的每个元素都可以通过下标唯一确定,即通过下标可以访问(操作)数组中的元素,称为下标方式。如ai,访问数组的两种方式:下标方式,指针方式.,C语言规定:数组名就是数组的首地址常量.,于是:,a=&a0,语言系统内部处理机制,指针方式效率高,共 90 页 第 19 页,int

8、 a10,*p;p=a;(等价于 p=2.通过指针引用数组引用数组元素可以用下标法,也可以用指针法,即通过指向数组元素的指针变量找到所需元素。,P=&a0,1.数组元素的指针,9.3.1 指针变量与一维数组之间的联系,共 90 页 第 20 页,9.3.2 指针的运算,1.指针表达式与整数的加减运算形式:p+n 或 p-n其中:p是任意一个指针表达式,n 是任何一种整型表达式计算规则:表达式p+n的值=p的值+p所指类型长度*n 表达式p-n的值=p的值-p所指类型长度*n说明:只有当p和p+n或p-n都指向连续存放的同类型数据区域(数组)时,指针加、减才有实际意义。C语言规定:表达式p+n和

9、p-n的类型与p相同。,共 90 页 第 21 页,p,a,p+1,a+1,p+9,a+9,p+i,a+i,a0,a1,a2,ai,a9,a数组,例如:int a10,*p;p=a;,*(p+i),共 90 页 第 22 页,例如:设有变量定义:int a10,*p,*q;则p=a p指向a0q=a+6 q指向a6p=q-4 p指向a2,3,4,12,11,5,6,7,8,9,10,p=a,a0,a6,a9,q=a+6,q-4,1000,共 90 页 第 23 页,2.指针自增自减运算,语法:p+;p-;+p;-p;进行+p或p+运算后都使p指向下一个数据 p+与+p的区别:表达式p+的值等于

10、p的原来值;表达式+p的值等于p的新值;取内容运算符“*”、取地址运算符“&”和自增自减运算符都是单目运算符,运算的优先级相同,结合方向都是自右至左。,例如:int a=1,2,3,4,5,*p,*q;p=q=a?变成100,a3,a4,共 90 页 第 24 页,把值为0的指针变量称作空指针变量。空指针变量表示不指向任何地方,表示指针变量的一种状态。p=0;p=0;p=NULL;三个语句等价。其中p为指针变量;0的ASCII码值为0;NULL是在“stdio.h”文件中定义的符号常数,其值为0,代表地址0和空指针的概念。如果给空指针变量所指内存区域赋值,将会得到一个出错信息。,3.空指针,共

11、 90 页 第 25 页,p-2,p-1,p,p+1,p+2,.,.,p-3,当两个指针指向同一个数组中的元素时,才能进行、=、=、!=、=的关系运算。,任何指针p与NULL进行“P=NULL”或“P!=NULL”运算均有意义:判断指针 p 是否指向空。,4.指针的关系运算,指针的关系运算只有同类指针进行比较才有意义,共 90 页 第 26 页,p=q 两指针指向同一元素时为 1,反之为0。,p!=q 两指针不指向同一元素时为 1,反之为0。,假定指针p 和q指向同一个数组,则:,pq p指针所指元素位于q所指元素之后时为1,反之为0。,p=q p指针所指元素位于q所指元素之后(或两指针指向同

12、一元素)时为1,反之为0。,=和!=运算符,比较的是两个指针表达式是否指向同一个内存单元;、=,比较的是两个指针所指内存区域的先后次序语法格式:指针表达式 关系运算符 指针表达式,例:int a10;int*p=a,*q=a+3;判断以下表达式的值p=&a0 p=&a1 p=q p+4=q+2 pa+2 pq,共 90 页 第 27 页,5.同类指针相减,同类指针相减时,两个指针应该指向连续存放的同类数据区域。语法:p-q 说明:p-q 的值,等于(p的值-q的值)/所指类型长度,即p,q两个指针之间数据元素的个数。例如:若有 int a10,*p,*q;p=a;q=则p-q=5 表示p,q之

13、间数据元素的个数是5。,共 90 页 第 28 页,格式:(类型名*)指针表达式功能:将指针表达式的值转换成指定类型的指针。例如:int*p;double d,*q=,6.强制类型转换运算,共 90 页 第 29 页,9.3.3 通过指针引用数组元素,引用数组中的元素可以用以下方法:下标法:如 a3,ai 指针法:即通过指向数组元素的指针找到所需的元素.这种方法占内存少,运行速度快,程序代码质量高。假设p已定义为指针变量,并已赋了一个地址,它指向某一个数组元素.且有赋值语句p=则:p+1 表示数组中的下一个元素,a+i和p+i都是ai 的地址,或者说它们指向ai.*(a+i)或*(p+i)是a

14、+i或p+i所指向的数组元素。指向数组的指针变量也可带有下标,如pi与*(p+i)等价。,对下标为i的元素访问:ai,*(a+i),*(p+i),pi对ai的地址表示:&ai,a+i,p+i,&pi,共 90 页 第 30 页,例:用三种方法输出数组全部元素。,下标法:main()int a10,i;for(i=0;i10;i+)scanf(“%d”,地址法(通过数组名计算数组元素地址)for(i=0;i10;i+)printf(“%5d”,*(a+i);指针法for(p=a;p(a+10);p+)printf(“%5d”,*p);,共 90 页 第 31 页,例9-3 用指针访问数组元素。,

15、main()int a10,*pa,i;for(i=0;i10;i+)ai=i+1;pa=a;for(i=0;i10;i+,pa+)printf(“%d”,*pa);printf(“n”);,不要忘记赋初值,如何修改程序可以完成功能?,共 90 页 第 32 页,例9-4 给定10个整数,求最大值。,main()int a10=5,7,3,6,2,1,8,9,4,0;int i,*p,max;p=a;max=*p+;for(i=1;imax)max=*p;printf(“max=%dn”,max);,问题:如果修改语句for(i=1;imax)max=*p+;能实现程序功能吗?,问题:如果修改

16、语句for(;pmax)max=*p;能实现程序功能吗?,共 90 页 第 33 页,9.3.4 字符串指针与字符串,1.字符串的表示形式 用字符数组表示,如:main()char string=“I love China!”;printf(“%sn”,string);,数组名,用字符指针实现,如:mian()char*string=“I love China!”;printf(“%sn”,string);,把“I love China!”的首地址赋给指针变量string,特点:字符串的长度不受限制;字符指针指向别处,字符串将失踪.,共 90 页 第 34 页,2.字符指针变量与字符数组的比较

17、,字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是字符串的首地址。赋值方式:char str=“I am a boy!”或:char str20;scanf(“%s”,str);字符指针变量指向字符串首地址。赋值方法三种:(1)char*pa=“I am a boy!”(2)char*pa;pa=“I am a boy!”(3)char*pa,str20;pa=str;scanf(“%s”,pa);,共 90 页 第 35 页,例9-5 已知下面程序的输出结果:ABCDCD,请完善程序:main()char*chp=“ABCD”;for(;_A_;chp=chp+2)p

18、rintf(“%s”,_B_);printf(“n”);,A.*chp!=0,B.chp,共 90 页 第 36 页,作用:函数的参数不仅可以是整型、实型、字符型,还可以是指针型,它的作用是将一个变量的地址传送到另外一个函数中。,9.4 指针与函数,9.4.1 指针变量作函数参数,共 90 页 第 37 页,例:交换两个变量的值。注意函数调用形实结合方式.,swap(x,y)int x,y;int t;t=x;x=y;y=t;,main()int a,b;scanf(“%d,%d”,单向值传递!,调用函数时a的值传送给x,b值传送给y,可是执行完函数后,x和y的值是互换了,但a,b的值并未互换

19、。,共 90 页 第 38 页,swap(int*p1,int*p2)int p;p=*p1;*p1=*p2;*p2=p;,main()int a,b;int*pa,*pb;scanf(“%d,%d”,运行情况:5,99,5,交换指针所指向的变量的值,分析观察使用指针做形参和实参的结果,例:将两个数按从大到小顺序输出(交换两个变量的值)。,结论:被调用函数不能改变实参指针变量的值,但可以改变实参指针变量所指向的变量的值。,共 90 页 第 39 页,函数调用过程如下图所示:,调用swap函数之前:,共 90 页 第 40 页,执行函数语句,p1、p2所指向的变量的值相互交换,*p1,*p2,共

20、 90 页 第 41 页,函数调用结束后,p1、p2所占用的内存单元被释放,,共 90 页 第 42 页,swap(int*p1,int*p2)int*p;p=p1;p1=p2;p2=p;,main()int a,b;int*pa,*pb;scanf(“%d,%d”,C语言中,实参和形参间的数据是单向值传递方式。指针做函数参数也遵循该原则.,改变指针形参的值,也不能改变指针实参的值.,结果为:?,交换了两个指针中的内容。,共 90 页 第 43 页,9.4.2 数组名作函数参数,当用数组名作为参数时,如果形参数组中元素的值发生变化,实参数组元素的值也随之变化,为什么?若有一个实参数组,想在函数

21、中改变此数组的元素的值,实参与形参的对应关系有以下4种情况:形参与实参都用数组名 实参用数组名,形参用指针变量 实参形参均用指针变量 实参为指针变量,形参为数组名,都是地址传递,只是形式不同!,共 90 页 第 44 页,指针作函数参数应注意的问题,指针变量在作实参时,必须有确定的值,即指向一个已定义的单元。如:main()int*p;f(p,10);int f(int x,int n),如何修改?,共 90 页 第 45 页,例9-6:用选择法对10个整数由小到大排序。方法1:形参和实参都用数组名(在函数中介绍的),main()int i,a10;void sort();for(i=0;i1

22、0;i+)scanf(%d”,void sort(int x,int n)int i,j,t;for(i=0;ixj)t=xi;xi=xj;xj=t;,形参是数组名,实参也是数组名,共 90 页 第 46 页,方法2:形参是数组名,实参是指针变量。,main()int*p,i,a10;void sort();p=a;for(i=0;i10;i+)scanf(%d,p+);sort(p,10);for(p=a,i=0;i10;i+)printf(%d,*p+);,void sort(int x,int n)int i,j,t;for(i=0;ixj)t=xi;xi=xj;xj=t;,p=a;,形

23、参是数组名,实参是指针,当用数组名作函数参数时,由于数组名代表的是数组首元素地址,因此传递的是地址,所以要求实参为指针变量。,共 90 页 第 47 页,方法3:实参是数组名,形参是指针变量。,void sort(int*x,int n)int i,j,t;for(i=0;i*(x+j)t=*(x+i);*(x+i)=*(x+j);*(x+j)=t;,实参是指针,main()int i,a10;void sort();for(i=0;i10;i+)scanf(%d”,形参是指针,实参是数组名,共 90 页 第 48 页,方法4:实参和形参都是指针变量。,void sort(int*x,int

24、n)int i,j,t;for(i=0;i*(x+j)t=*(x+i);*(x+i)=*(x+j);*(x+j)=t;,实参是指针,main()int*p,i,a10;void sort();p=a;for(i=0;i10;i+)scanf(%d,p+);p=a;sort(p,10);for(p=a,i=0;i10;i+)printf(%d,*p+);,实参也是指针,形参是指针,共 90 页 第 49 页,例9-7 编写函数,删除字符串中的给定字符。delete(char d,char f)int j=0,k=0;while(dj!=0)if(dj!=f)dk+=dj;j+;dk=0;,共 9

25、0 页 第 50 页,main()char*str=How,are,you!,c=,;printf(original string is:%sn,str);delete(str,c);printf(compressed string is:%sn,str);程序执行结果:original string is:How,are,you!compressed string is:How are you!,本例主函数调用语句的实参分别是字符型指针变量和字符型变量,对应的子函数的形参分别是字符型一维数组名和字符型变量。程序的功能是删除逗号“,”字符。,共 90 页 第 51 页,strcopy(char

26、*str1,char*str2)/*形参为指向字符的指针*/while(*str2+=*str1+)!=0);main()char a30,b30;printf(Enter string:);scanf(%s,a);strcopy(a,b);printf(a=%snb=%sn,a,b);,例9-8 编写字符串复制函数,并调用。,共 90 页 第 52 页,返回指针的函数定义形式:类型说明符*函数名(形式参数表)说明部分 语句 说明:表示函数的返回值是一个指针.其他和一般函数相同.,9.4.3 返回指针的函数,如 int*f(int x,int y);,共 90 页 第 53 页,例9-9 在给

27、定的字符串s中寻找一个特定的字符x,若找到x,则返回x在s中第一次出现的地址,并把s中该字符和该字符之前的字符按逆序输出。,char*str(char*s,char x)int c=0;while(x!=sc,共 90 页 第 54 页,#include stdio.hmain()char s40,*p,x,*str();gets(s);x=getchar();p=str(s,x);if(*p)printf(%c,*p);do p-;printf(%c,*p);while(p-s);else printf(char%c not found,x);,共 90 页 第 55 页,9.4.4 函数的

28、指针和指向函数的指针变量,1.函数的指针 函数名字的值等于该函数存储的首地址,即等于该函数的入口地址。一个函数在编译时被分配一个入口地址,这个入口地址称为函数的指针。,共 90 页 第 56 页,2.指向函数的指针变量的定义和功能(1)定义形式,数据类型标识符(*指针变量名)(形式参数表);,函数返回值的类型,(2)功能 定义一个指向函数的指针变量,该指针变量所指向的函数的返回值是“类型说明符”的类型,该函数的参数个数及类型由“形式参数表”确定。定义指向函数的指针变量时,形式参数表只写出各个形式参数的类型即可,也可以省略形式参数表。,共 90 页 第 57 页,3.指向函数的指针变量允许的操作

29、将函数名或指向函数的指针变量的值赋给指向同一类型函数的指针变量。函数名或指向函数的指针变量作为函数的参数。即将函数名传给形参。,(3)可以利用指向函数的指针变量调用函数,调用形式是:(*变量名)(实际参数表)调用结果:使程序的执行流程转移到指针变量所指向函数的函数体。函数指针经定义和赋初值后,就可以引用该指针,调用被指针所指的函数.增加了函数调用的方式。,共 90 页 第 58 页,例9-10 求a和b中的大者。main()int max();int(*p)();int a,b,c;p=max;scanf(%d,%d”,max(x,y)int x,y;int z;if(xy)z=x;else

30、z=y;return(z);,指向函数的指针,指向max函数,共 90 页 第 59 页,在一个程序中,一个指针变量可以先后指向不同的函数;例如:int(*p)();int max();int min();p=max;c=(*p)(a,b);p=min;c=(*p)(a,b);,P先于*结合,是指针变量,然后再与()结合,表示此指针变量指向函数。,共 90 页 第 60 页,实参函数名f1 f2 sub(x1,x2)int(*x1)(),(*x2)();int a,b,i,j;a=(*x1)(i);b=(*x2)(i,j);,定义x1,x2为函数指针变量,调用f1函数,调用f2函数,指向函数的

31、指针变量作函数参数:,共 90 页 第 61 页,9.5 指针与二维数组,9.5.1 二维数组的结构 数组的名代表该数组的首地址,并可看成是地址常量,这一规定对二维数组或更高维数组同样适用。若有定义:float*p,d35;d0,d1,d2 分别是一维数组名,表示一维数组的首地址,p=d0是正确的。,可以把d看成是由3个一维数组组成,即d0,d1,d2,共 90 页 第 62 页,a代表整个二维数组的首地址,即第0行的首地址a+1是数组a第1行首地址(208)a0,a1,a2是二维数组中三个一维数组的名字(地址),是第0行,第1行,第2行的首地址,即:a0=a+0、a1=a+1、a2=a+2a

32、i+j是第i行j列的地址*(ai+j)是该地址存储的值,即aij考虑*(a2+3)=?,假设数组名为a,起始地址设为200,按行优先存放,int a34=1,3,5,7,9,11,13,15,17,19,21,23;则:,9.5.2 二维数组元素及其地址,共 90 页 第 63 页,注意:,ai和*(a+i)无条件等价a+i、ai、*(a+i)、&ai0均表示第i行首地址;&aij、ai+j、*(a+i)+j都是第i行j列元素的地址;aij、*(ai+j)、*(*(a+i)+j)都是第i行j列元素的值;,共 90 页 第 64 页,int i,j;main()int*p,a34,b34,c34

33、;printf(The value of a:n);for(i=0;i3;i+)for(j=0;j4;j+)scanf(%d,ai+j);printf(The value of b:n);for(i=0;i3;i+)for(j=0;j4;j+)scanf(%d,*(b+i)+j);,例9-11:将a矩阵与b矩阵相加,计算结果存入c矩阵。,表示a数组第i行第j列元素的地址,表示b数组第i行第j列元素的地址,共 90 页 第 65 页,matrix(*a,b0,matrix(int*x,int*y,int*z)for(i=0;i3;i+)for(j=0;j4;j+)*(z+i*4+j)=*(x+i

34、*4+j)+*(y+i*4+j);,数组元素在内存中按“行优先”的顺序存放,因此可用x+i*4+j表示二维数组各元素的地址,相当于&xij,*(x+i*4+j)就是取该元素的值。,*a相当于*(a+0),即a0表示a数组第0行第0列元素的地址。b0表示 b数组第0行第0列元素的地址。&c00表示 c数组第0行第0列元素的地址。,计算aij在数组中相对位置的计算公式为:i*m+jm为二维数组的列数,共 90 页 第 66 页,例9-12 将矩阵A转置后存放到矩阵B中,即:bji=aij(下标法),main()int a34,b43,i,j;for(i=0;i3;i+)for(j=0;j4;j+)

35、scanf(%d,共 90 页 第 67 页,指针法(方法1),main()int a34,b43,i,j,*p,*q;p=,将指针变量p,q指向两数组的开始位置,利用指针p为数组a输入数据,利用指针q输出数组b,这里的指针变量p和q都是用int*p,*q定义的是指向整型数据的,p+1是指向p所指向的下一个元素。能否使p不是指向整型变量,而是指向一个包含m个元数的一维数组呢?,共 90 页 第 68 页,9.5.3 指向数组的指针变量,1.定义格式 类型说明符(*变量名)正整型常量表达式2.功能 定义一个名为“变量名”的指针变量,这个指针变量所指的对象是一个有“正整型常量表达式”个元素的一维数

36、组。例如:int a34,(*p)4=a;定义p是一个指针变量,它指向包含4个整型元素的一维数组。p的值就是该一维数组的起始地址。,共 90 页 第 69 页,例9-13:输出二维数组任一行任一列元素的值,main()int a34=1,3,5,7,9,11,13,15,17,19,21,23;int*p,i,j;p=a;scanf(“%d,%d”,输入1,2运行结果:a12=13,这里的指针变量p是定义为指向整型数据的,aij在数组中的位置用相对于数组起始位置的相对移位量计算,共 90 页 第 70 页,例9-14 输出二维数组任一行任一列元素的值,main()int a34=1,3,5,7

37、,9,11,13,15,17,19,21,23;int(*p)4,i,j;p=a;scanf(“%d%d”,输入1,2运行结果:a12=13,第i行j列元素的地址为:*(p+i)+j第i行j列元素的值为:*(*(p+i)+j),这里的指针变量p不是指向整型变量,而是指向一个包含4个整型元素的一维数组。,共 90 页 第 71 页,例9-15 阅读下面程序。main()int i;int*q,(*p)4,a34=2,4,6,8,10,12,14,16,18,20,22,24;q=a0;for(i=1;i=0;i-)printf(%dt,*(pi+i);printf(n);,程序运行结果:2 6

38、10 14 22 12 2,第i行j列元素的地址为:pi+j第i行j列元素的值为:*(pi+j),q是定义为指向整型数据的,P指向一个包含4个整型元素的一维数组。,共 90 页 第 72 页,定义一个由 6个指针变量构成的指针数组,数组中的每个数组元素都是一个指向一个整数的指针变量。,指针数组:数组中的元素均为指针类型。适合用来指向字符串,1.定义形式:,数据类型*数组名常量表达式,例如:int*pa6;,2.功能:,9.6 指针数组,共 90 页 第 73 页,3.指针数组的初始化,必须用地址值为指针数组初始化,int a33=1,2,3,4,5,6,7,8,9,*pa3;pa0=a0;pa

39、1=a1;pa2=a2;,指针数组*pa3 相当于有三个指针,*pa0,*pa1,*pa2,初始化的结果:,共 90 页 第 74 页,对指针数组中的任意一个pai,移动j个元素,有:,pai+j=ai+j=,指针与数组的等价性:*(a+i)=*(pa+i)=a i;,*(pa i+j)=*(a i+j)=*(*(a+i)+j)=a i j,指针数组与二维数组是等价的,通过指针数组可以引用二维数组中的元素。,注意:int*p5 与 int(*p)5 不同,共 90 页 第 75 页,字符串数组:数组中的每个元素都是存放字符的数组。字符串数组的每一行可存放一个字符串。用赋初值的方式给字符串数组赋

40、值:直接给字符串数组赋初值若有定义:char b48=Turbo C,FORTRAN,BASIC,Foxpro;此定义还可以写成:char b8=Turbo C,FORTRAN,BASIC,Foxpro;由于字符串长短不一,定义时应考虑最长的串和结束标志的位置。,9.7 指针与字符串数组,共 90 页 第 76 页,用给字符型指针数组赋初值的方式构成字符串数组若有定义:char*f4=Turbo C,FORTRAN,BASIC,Foxpro;此定义还可以写成:char*f=Turbo C,FORTRAN,BASIC,Foxpro;则数组f中的每个元素都存放着对应的一个字符串的首地址,各字符串依

41、次存入各相应的首地址开始的连续存储单元中。,节省内存空间!,共 90 页 第 77 页,例9-16,#include“stdio.h”main()char*s4=“dog”,“cat”,“pig”,“all animals”;int i;for(i=0;i 4;i+)printf(“%sn”,*(s+i);,指针数组S各元素的内容是指向各字符串的首地址。,运行结果:dogcatpigall animals,共 90 页 第 78 页,问 题,二维数组的元素与地址如何使用指针与字符串数组?指针数组的作用,如何使用?如何使用指向数组的指针变量访问二维数组?(指向数组的指针变量,所指的对象是一个一维

42、数组,具有M个元素,是有构造的)。,共 90 页 第 79 页,9.8 二级指针,指向指针的指针:指向指针数据的指针变量。通常用于指向字符型指针变量。说明格式:类型说明符*指针变量名例如:char*p;定义指针变量p,用于存储另一个指针变量的地址。,共 90 页 第 80 页,例如:,main()char*s=“China”,“Japan”,“English”,”Franch”;char*p;int i;p=s+2;printf(“%sn”,*p);,*p=*(s+2)=s2存放的是English的首地址,打印p指针内的内容,即指针指向的字符串,共 90 页 第 81 页,9.9 用指针实现内

43、存动态分配,1.动态内存分配的步骤 了解需要多少内存空间 利用C语言提供的动态内存分配函数分配所需要的存储空间;使指针指向获得的内存空间,以便实施运算或操作;当使用完毕内存后,释放这一空间。,2.动态内存分配函数 动态存储分配函数:malloc()原型是:void malloc(unsigned size)功能:在内存中动态分配一连续空间,其长度为size.申请成功,返回一个指针,否则,返回NULL.,共 90 页 第 82 页,int*p;p=(int*)malloc(n*sizeof(int);申请能保持n个整型数据的连续内存空间,使p指向该区域。,共 90 页 第 83 页,计数动态存储

44、分配函数:calloc()原型是:void*calloc(unsigned n,unsigned size)功能:在内存中动态存储区分配n个连续空间,并初始化为0,每一空间其长度为size.申请成功,返回一个指针,否则,返回NULL.,动态存储释放函数:free()原型是:void free(void*ptr)功能:释放由动态存储分配函数申请到的整块内存空间,ptr为指向要释放空间的首地址。如果ptr是空指针,则free()什么也不做,无返回值。若不需要时,及时释放。,共 90 页 第 84 页,9.9 main()函数的命令行参数,main函数也可以带参数,如:main(argc,argv)

45、int argc;char*argv;,字符型指针数组,其各指针分别指向命令行中命令名和各个参数的字符串。argv 0指向命令名字符串。,参数计数命令行参数个数,参数值,共 90 页 第 85 页,main 函数的实参是和命令一同给出的,即在一个命令行中包括命令名和需要传给 main 函数的参数命令行的一般形式为:命令名 参数1 参数 2.参数n,假设目标文件名为“F”,需向函数传递的参数为字符串“X”和“Y”,则命令行可写为:F X Y,命令行及命令行参数提供了C程序与操作系统间的接口。,共 90 页 第 86 页,若有一个函数,其所在文件名为“F”:,main(argc,argv)int

46、argc;char*argv;while(argc1)+argv;printf(“%sn”,*argv);-argc;,若输入的命令行参数为F ABC DEF则执行结果为ABCDEF,共 90 页 第 87 页,有关指针数据类型的小结,定义:int*p;.p为指向整型数据的指针变量;int*pn;.定义指针数组p,它由n个指向整型数据指针元素组成;int(*p)n;定义指向含n个元素的一维数组的指针变量p;int f();f为带回整型函数值的函数;int*p();p为带回一个指针的函数,该指针指向整型数据;int(*p)();.p为指向函数的指针,该函数返回一个整型值;int*p;.p是一个指

47、针变量,它指向一个指向整型数据的指针变量。二级指针。指针在使用前一定要赋值,指针可以指向任何数据类型,指向谁,就存谁的地址必须用地址值为指针变量初始化(&变量名,&a,或数组名),不允许用整数相同类型的指针可以相互赋值优缺点:快速灵活、可实现动态存储分配;易出大错。,共 90 页 第 88 页,P173-1:使用指针编写程序,删除字符串的所有尾部空格。#include“stdio.h”main()char*p,s20;int i,j;p=s;gets(p);for(;*p!=0;p+);for(p-;*p=;p-);p+;*p=0;printf(“%sn”,s);,共 90 页 第 89 页,

48、P173-1.使用指针编写程序,删除字符串的所有尾部空格。#include“stdio.h”del(char*p)for(;*p!=0;p+);for(p-;*p=;p-);*+p=0;main()char s20;gets(s);del(s);printf(“%sn”,s);,共 90 页 第 90 页,P173-2:使用指针编写程序,对具有10个元素的char类型的数组,从下标为6的元素开始全部设置#号,保持前6个元素中的内容不变。main()char*p=abcdefghij;int j;for(j=0;*p!=0;p+,j+)if(j=6)*p=#;printf(“%sn”,p);,运行结果正确吗?如何修改?,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 建筑/施工/环境 > 农业报告


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号