kj-第9章指针课件.ppt

上传人:春哥&#****71; 文档编号:15609851 上传时间:2022-05-13 格式:PPT 页数:86 大小:573KB
返回 下载 相关 举报
kj-第9章指针课件.ppt_第1页
第1页 / 共86页
kj-第9章指针课件.ppt_第2页
第2页 / 共86页
点击查看更多>>
资源描述

《kj-第9章指针课件.ppt》由会员分享,可在线阅读,更多相关《kj-第9章指针课件.ppt(86页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、第1页第章第章 指针指针 本章概述 本章的学习目标主要内容第2页本章概述本章概述n指针是指针是C语言的特色之一,灵活运用指针可语言的特色之一,灵活运用指针可使程序更加高效、简洁。使程序更加高效、简洁。n指针就是内存地址,不同于通过变量名引指针就是内存地址,不同于通过变量名引用内存单元的直接访问方式,使用指针可用内存单元的直接访问方式,使用指针可实现对内存单元的间接访问。实现对内存单元的间接访问。n本章介绍指针的有关概念,介绍指针与数本章介绍指针的有关概念,介绍指针与数组的关系,介绍与函数的关系。组的关系,介绍与函数的关系。第3页本章的学习目标本章的学习目标n本章教学目的:理解指针的概念和内存访

2、问的关系,掌握本章教学目的:理解指针的概念和内存访问的关系,掌握指针的定义、引用。熟练使用指针访问基本类型的数据。指针的定义、引用。熟练使用指针访问基本类型的数据。理解指针与数组的关系,运用指针实现对数组的访问,包理解指针与数组的关系,运用指针实现对数组的访问,包括对一维数组和二维数组处理。理解指针与字符串(字符括对一维数组和二维数组处理。理解指针与字符串(字符数组)的关系,运用指针操作字符串。理解指针数组的概数组)的关系,运用指针操作字符串。理解指针数组的概念,能运用指针数组处理相关的数据类型,尤其是运用字念,能运用指针数组处理相关的数据类型,尤其是运用字符指针数组处理多个字符串。理解指针与

3、函数的关系,运符指针数组处理多个字符串。理解指针与函数的关系,运用指针实现函数调用。理解带参数的用指针实现函数调用。理解带参数的main函数作用及各个函数作用及各个参数的含义。参数的含义。n本章教学重点:指针的概念,指针与数组的关系。本章教学重点:指针的概念,指针与数组的关系。n本章教学难点:指针数组,指针与函数,多重指针。本章教学难点:指针数组,指针与函数,多重指针。第4页主要内容主要内容9.1 指针的基本概念指针的基本概念 9.2 指针与一维数组指针与一维数组 9.3 指针与字符串指针与字符串 9.4 指针与二维数组指针与二维数组 9.5 指针数组与多级指针的概念指针数组与多级指针的概念

4、9.6 指针与函数指针与函数 9.7 命令行参数命令行参数 9.8 程序设计举例程序设计举例 第5页9.1指针的基本概念指针的基本概念 n内存是计算机的重要组成部分,在程序的执行过程中,内存是计算机的重要组成部分,在程序的执行过程中,所用到的数据都存于内存中。所用到的数据都存于内存中。n内存单元的基本单位是字节,为方便对内存的访问,内内存单元的基本单位是字节,为方便对内存的访问,内存单元的每个字节都有一个编号,存单元的每个字节都有一个编号,这个编号就是内存的这个编号就是内存的地址。地址。nC程序中的每一个变量,在内存中都占用一定数量的内程序中的每一个变量,在内存中都占用一定数量的内存单元。给变

5、量赋值就是将数据存入对应的内存单元,存单元。给变量赋值就是将数据存入对应的内存单元,使用变量时是按照变量所占用的内存单元的地址,从该使用变量时是按照变量所占用的内存单元的地址,从该地址所对应的内存单元中取出变量的值。地址所对应的内存单元中取出变量的值。n因为我们是通过变量的地址来找到存储变量值的内存单因为我们是通过变量的地址来找到存储变量值的内存单元,从而取得了变量的值,元,从而取得了变量的值,所以将变量的地址又称为变所以将变量的地址又称为变量的指针量的指针 。第6页9.1指针的基本概念指针的基本概念 n如右图所示,整型变量如右图所示,整型变量i占占2000、2001两两个字节的内存,整型变量

6、个字节的内存,整型变量j占占2002、2003两个字节的内存,其内存单元中存放的是两个字节的内存,其内存单元中存放的是整型数据。而变量整型数据。而变量p占占3000、3001两个字两个字节的内存,其内存单元中存放的是变量节的内存,其内存单元中存放的是变量i的的地址地址2000(一个变量占多个字节的内存单(一个变量占多个字节的内存单元时,以首地址表示该变量的地址)。这元时,以首地址表示该变量的地址)。这种存放另一个变量的地址的变量称为指针种存放另一个变量的地址的变量称为指针变量。称变量变量。称变量p指向变量指向变量i,p中存储的是变中存储的是变量量i的指针。的指针。n对一个变量的访问(访问是指取

7、出其值或对一个变量的访问(访问是指取出其值或向它赋值)方式有两种:向它赋值)方式有两种: (1)直接访问直接访问:通过变量名访问,如通过:通过变量名访问,如通过变量名变量名i直接访问直接访问i。 (2)间接访问间接访问:通过指向该变量的指针变:通过指向该变量的指针变量来访问,如通过量来访问,如通过p访问变量访问变量i。第7页指针变量的定义指针变量的定义 n指针变量是一类特殊的变量,其值是一个变量的地址。既指针变量是一类特殊的变量,其值是一个变量的地址。既然是变量,就需要在使用之前先对其定义,然后才可以使然是变量,就需要在使用之前先对其定义,然后才可以使用。用。n指针变量定义的一般形式:指针变量

8、定义的一般形式: 类型标识符类型标识符 * 标识符标识符;其中,其中,类型标识符类型标识符用于指出所定义指针变量可以指向用于指出所定义指针变量可以指向的变量类型,称为指针变量的的变量类型,称为指针变量的“基类型基类型”,标识符标识符是指针是指针变量名,变量名,“*”表示定义指针变量。表示定义指针变量。 第8页指针变量的定义指针变量的定义 例如:例如: int *p1; /*定义指针变量p1,指向整型变量*/ float *p2; /*定义指针变量p2,指向实型变量*/ char *p3; /*定义指针变量p3,指向字符型变量*/n指针变量定义的同时也可以对其初始化,例如:int i; int

9、*p=&i;这样定义的指针变量p,就指向整型变量i。第9页指针变量的定义指针变量的定义 n定义指针变量时应该: (1)标识符前的“*”只是一个符号,表示其后的变量是一个指针变量。 (2)指针变量的基类型必须与所指向的变量类型一致,否则会出错。例如: float x; int *p1=&x;是错误的。 因为p1的基类型为整型,而变量x 是单精度类型,数据类型不一致。第10页指针变量的引用指针变量的引用 n(1) &:取地址运算符:取地址运算符,用于取变量的地址。,用于取变量的地址。n例如:例如:int i,*p1; p1=&i;取取i的地址赋给指针变量的地址赋给指针变量p1。n (2) *:指针

10、运算符:指针运算符,用于访问指针变量所指向的变量。,用于访问指针变量所指向的变量。n例如:例如:int i,*p1; p1=&i;*p1=100;则则*p1与与i等价,访问等价,访问i时时,可以用间接方式,用可以用间接方式,用*p1代表代表i,语句语句“*p1=100;”与与“i=100;”相同,为相同,为i赋值赋值100。 第11页指针变量的引用指针变量的引用 若有:若有: int i=100; int *p1; p1 = &i;则指针变量则指针变量p1指向变量指向变量i,对变量,对变量i有如下两种访问方式:有如下两种访问方式: (1)直接访问。)直接访问。 如如 printf(“%d”,i

11、); (2)通过指针变量间接访问。)通过指针变量间接访问。 如如:printf( “%d”,*p1); 第12页9. 1. 2指针变量的引用指针变量的引用 # include int main() int i,j, *p; p=&i; /*p指向i */ i=10; printf(“%d,%dn”,i,*p); *p=100; printf(“%d,%dn”,i,*p); p=&j; *p=200; printf(“%d,%dn”,j,*p); return 0; 程序运行结果为:程序运行结果为:10,10100,100200,200程序说明:程序说明:(1)将变量将变量i的地址赋给了指针变量

12、的地址赋给了指针变量p之后,之后,*p与与i等价。等价。(2) 语句语句“ *p=100;”的作用是将的作用是将100存入由存入由p所指向的变量中,即存所指向的变量中,即存入整型变量入整型变量i中。中。例例9.1:指针变量的引用指针变量的引用第13页9. 1. 2指针变量的引用指针变量的引用# include int main()int num1=12, *p1; float num2=3.14, *p2; char ch=p, *p3; p1=&num1; p2=&num2; p3=&ch; printf(“num1=%d, *p1=%dn”, num1, *p1); printf(“num

13、2=%4.2f, *p2=%4.2fn”, num2, *p2); printf(“ch=%c, *p3=%cn”, ch, *p3); return 0;程序的运行结果为:程序的运行结果为:num1=12, *p1=12num2=3.14, *p2=3.14ch=p, *p3=p例例9.2 写出以下程序的运行结果。写出以下程序的运行结果。程序说明:程序说明:从程序的运行结果可以从程序的运行结果可以看出看出num1和和*p1、num2和和*p2、ch1和和*p3是等价的是等价的 。第14页9. 1. 2指针变量的引用指针变量的引用 # include int main() int num1,n

14、um2; int *p1=&num1, *p2=&num2, *p; printf(“Input the first number: ”); scanf(“%d”,p1); printf(“Input the second number: ”); scanf(“%d”,p2); printf(“num1=%d, num2=%dn”, num1, num2); if( *p1 *p2 ) p= p1;p1= p2;p2=p; printf(“min=%d, max=%dn”, *p1, *p2); return 0; 程序运行结果:程序运行结果:Input the first number:9I

15、nput the first number:9Input the second number:6Input the second number:6num1=9, num2=6num1=9, num2=6min=6, max=9min=6, max=9例例9.3 使用指针变量求解:输入使用指针变量求解:输入2个整数,按从小到大顺序输出。个整数,按从小到大顺序输出。第15页l程序说明:程序说明:l(1)程序中的)程序中的if语句,若语句,若*p1*p2 (即(即num1num2),则交换指针,使),则交换指针,使p1指向变量指向变量num2(较小值),(较小值),p2指向变量指向变量num1(较大

16、值)。(较大值)。l(2)“printf(“min=%d, max=%dn”, *p1, *p2);” 语句,通过指针变量,间接访问变量的值。语句,通过指针变量,间接访问变量的值。l 本例的处理思路是:交换指针变量本例的处理思路是:交换指针变量p1和和p2的值,的值,而不是交换变量而不是交换变量num1和和num2的值(变量的值(变量num1和和num2并未交换,仍保持原值),最后通过指针变并未交换,仍保持原值),最后通过指针变量输出处理结果。量输出处理结果。例例9.3 使用指针变量求解:输入使用指针变量求解:输入2个整数,按从小到大顺序输出。个整数,按从小到大顺序输出。第16页 数组和指针有

17、密切的关系,数组和指针有密切的关系,数组名代表数组数组名代表数组的首地址的首地址。 当一个指针指向数组后,对数组元素的访问,当一个指针指向数组后,对数组元素的访问,既可以使用数组下标,也可以使用指针。既可以使用数组下标,也可以使用指针。 用指针访问数组元素,程序的效率更高;用用指针访问数组元素,程序的效率更高;用下标访问数组元素程序更清晰。下标访问数组元素程序更清晰。第17页 在在C语言中,当一个数组语言中,当一个数组a被定义后,数组名被定义后,数组名a本身就代表了该数组的本身就代表了该数组的首地址,并且它是一个地址常量,数组元素的地址可以通过数组名首地址,并且它是一个地址常量,数组元素的地址

18、可以通过数组名a加下加下标值来取得。标值来取得。 a即即a+0代表数组元素代表数组元素a0的地址,的地址,a+1代表数组元素代表数组元素a1的地址,的地址,a+2代表数组元素代表数组元素a2的地址,的地址, 。 若定义一个指针变量,使其指向一个数组,则该指针变量称为指若定义一个指针变量,使其指向一个数组,则该指针变量称为指向数组的指针变量,其定义与指向普通变量的指针变量的定义方法是向数组的指针变量,其定义与指向普通变量的指针变量的定义方法是一样的。一样的。 例例如:如: int a10, *p; 则:则: pa;或者:或者:p=&a0;上面两个语句是等价的,都表示把数组上面两个语句是等价的,都

19、表示把数组a的首地址赋给指针变量的首地址赋给指针变量p。第18页指针变量也可以指向数组的其它元素。例如:指针变量也可以指向数组的其它元素。例如: int *p1, *p2; int a10 = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10; 此后可以赋值:此后可以赋值: p1 = &a0; p2 = &a4;完成了赋值之后,指针完成了赋值之后,指针p1指向数组指向数组a的首元素,的首元素,p2指向数组元素指向数组元素a4。 对于上面所写对于上面所写&a0的表达形式,由于数组元素访问运算的表达形式,由于数组元素访问运算符符的优先级更高,所以这里不必写成的优先级更高,所以这里不必写成

20、&(a0)的形式。的形式。第19页 数组定义和初始化之后,数组元素可以通过数组的下标、数组名或指向数组的指针变量来引用。若定义一个一维数组: int a10 = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10; 可以通过数组的下标访问数组元素:如: printf(“%d”,a5); 也可以通过数组名访问数组元素:如:也可以通过数组名访问数组元素:如:*(a+0)即即*(a)与与a0相等,相等,*(a+1)与与a1相等,相等,*(a+2)与与a2相等,相等,*(a+i)与与ai相等,相等,。 但使用数组名时,注意不能用但使用数组名时,注意不能用a+的方式,因为的方式,因为a是是地址常

21、量,常量是不能被重新赋值的。地址常量,常量是不能被重新赋值的。第20页 同样,若定义指针变量同样,若定义指针变量p(int *p;),并使),并使p指向数指向数组组a(即(即p=a),则可以用指针变量来访问数组元素,),则可以用指针变量来访问数组元素,如右图所示。如右图所示。p指向数组的第一个元素指向数组的第一个元素a0,则,则p+1指向指向数组的下一个元素数组的下一个元素a1,p+2指向数组元素指向数组元素a2,p+i指向数组元素指向数组元素ai ,。 可以使用可以使用*(p+i)访问元素访问元素ai。 p+i等价于等价于a+i,都表示元素,都表示元素ai的地址。的地址。 指向数组的指针变量

22、也可以带下标,如指向数组的指针变量也可以带下标,如pi与与*(p+i)等价,表示元素等价,表示元素ai。数组元素数组元素ai的的4种引用方式:种引用方式: ai、*(a+i)、*(p+i)、pi 。引用数组元素引用数组元素ai地址的地址的4种方式为:种方式为: &ai、a+i、p+i、&pi。第21页 另外,在使用指向数组的指针变另外,在使用指向数组的指针变量时,注意对指针变量量时,注意对指针变量p+1的理解。的理解。 若数组元素是若数组元素是int型,型,p+1所表示所表示的地址是的地址是p的地址值加的地址值加2个字节;若个字节;若数组元素是数组元素是float型,型,p+1所表示的地所表示

23、的地址是址是p的地址值加的地址值加4个字节;若数组个字节;若数组元素是元素是char型,型,p+1所表示的地址是所表示的地址是p的地址值加的地址值加1个字节。个字节。第22页 当指针变量当指针变量p中存储的是数组中存储的是数组a的首地址的首地址(p=a)时,执行)时,执行p+后,后,p中存储的是数组元中存储的是数组元素素a1的地址,再执行的地址,再执行p+后,后,p中存储的是数中存储的是数组元素组元素a2的地址,的地址,。 若数组元素是若数组元素是int型,执行型,执行p+后,后,p中存中存储的地址是储的地址是p中原来存储的地址值加中原来存储的地址值加2个字节;个字节;若数组元素是若数组元素是

24、float型,执行型,执行p+后,后,p中存储中存储的地址是的地址是p中原来存储的地址值加中原来存储的地址值加4个字节个字节(如右图);若数组元素是(如右图);若数组元素是char型,执行型,执行p+后,后,p中存储的地址是中存储的地址是p中原来存储的地址值中原来存储的地址值加加1个字节。个字节。 若若p中存储的是元素中存储的是元素ai(i1)的地址,根的地址,根据上面的叙述,读者可以思考如何理解据上面的叙述,读者可以思考如何理解p-1、p-。float *pp-1pp+1p+2*(p-1)*p*(p+1)*(p+2)第23页int int main() int a10, *p=a, i,su

25、mi,sum; printf(“Input 10 numbers: ”); for(i=0; i10; i+) scanf(“%d”, p+i); /*使用指针变量来输入数组元素的值使用指针变量来输入数组元素的值*/ printf(“array array a: ”); for(i=0; i10; i+) printf(“%d ”, *(p+i) ; /*使用指向数组的指针变量输出数组元素的值使用指向数组的指针变量输出数组元素的值*/ sum=sum+ sum=sum+*(p+i) ; ; printf(“n sum=%d n sum=%d n”, sum, sum); return 0; r

26、eturn 0;程序运行情况:程序运行情况:Input 10 numbers: 0 1 2 3 4 5 6 7 8 9 array a: 0 1 2 3 4 5 6 7 8 9sum=45例例9.4 使用指向数组的指针变量来引用数组元素。使用指向数组的指针变量来引用数组元素。第24页# include int int main() int a10, *p=a, i,sum,sum; printf(“Input 10 numbers: ”); for(i=0; i10; i+,p+) scanf(“%d”, p); printf(“array array a: ”); p=a; /*使使p重新指

27、向数组的第一个元素重新指向数组的第一个元素*/ for(i=0; i10; i+,p+) printf(“%d”,*p); sum=sum+ sum=sum+*(p+i) ; ; printf(“n sum=%d n sum=%d n”, sum, sum); return 0; return 0; 程序说明:程序说明: (1) 用指针变量直接指向数组元用指针变量直接指向数组元素,不必每次都重新计算地址。这素,不必每次都重新计算地址。这种有规律地改变地址值(种有规律地改变地址值(p+)的)的方法能较好地提高执行效率。方法能较好地提高执行效率。 (2) 用下标法比较直观,能直接用下标法比较直观,

28、能直接知道操作的是数组的第几个元素。知道操作的是数组的第几个元素。例例9.4程序也可写为:程序也可写为:第25页1空指针空指针 空指针是个特殊的值,也是唯一对任何指针类型都合法的值。一个指针变空指针是个特殊的值,也是唯一对任何指针类型都合法的值。一个指针变量具有空值,表示它当时没有被赋予有意义的地址,处于闲置状态。空指针值量具有空值,表示它当时没有被赋予有意义的地址,处于闲置状态。空指针值用用0 0表示,这个值绝不会是任何程序对象的地址。但给一个指针变量赋值,说表示,这个值绝不会是任何程序对象的地址。但给一个指针变量赋值,说明该指针变量不再是一个不定值,而是一个有效的值。明该指针变量不再是一个

29、不定值,而是一个有效的值。 为了提高程序的可读性,标准库定义了一个与为了提高程序的可读性,标准库定义了一个与0等价的符号常量等价的符号常量NULL,程序里可以写:程序里可以写: p = NULL;或者:或者: p = 0; 这两种写法都将指针这两种写法都将指针p置为空指针值。前一种写法使读程序的人容易意置为空指针值。前一种写法使读程序的人容易意识到这里是一个指针赋值,采用前一种写法时必须通过识到这里是一个指针赋值,采用前一种写法时必须通过 #include 包含相应包含相应的标准头文件,即的标准头文件,即#include 。第26页2指针初始化指针初始化 在定义指针变量时,可以用合法的指针值对

30、它进行初始化。在定义指针变量时,可以用合法的指针值对它进行初始化。例如下面定义:例如下面定义:int n, *p = &n, *q = NULL; 执行p+(或 p+=1)后,p指向数组的下一个元素。*p+相当于*(p+)。因为,*和+同优先级,+是右结合运算符。*(p+)与*(+p)的作用不同。 *(p+):先取*p,再使p加1。 *(+p):先使p加1,再取*p。(*p)+表示p指向的元素值加1。 3设指针设指针p指向数组指向数组a(p=a),则有如下事实:),则有如下事实:第27页 *(p-)相当于ai-,先取*p,再使p减1。 *(+p)相当于a+i,先使p加1,再取*p。 *(-p)

31、相当于a-i,先使p减1,再取*p。4如果如果p当前指向数组当前指向数组a的第的第i个元素,则有如下事实:个元素,则有如下事实:q1 p1表示q1 所指元素位于p1 所指元素之后,q1 p1 表示q1 所指元素位于p1 所指元素之前。如果两个指针不指向同一个数组,对它们的比较也没有意义。5如果两个指针如果两个指针q1和和 q1指向同一个数组,那么可以对指向同一个数组,那么可以对两个指针进行比较:两个指针进行比较:例如 “n = p2 p1;” ,当两个指针不指向同一数组时,求它们的差就完全没有意义了。6当两个指针指向同一数组时,可以求它们的差,得到的结当两个指针指向同一数组时,可以求它们的差,

32、得到的结果是对应的数组元素的下标之差果是对应的数组元素的下标之差(可能是一个负数)。第28页 在语言中,既可以用字符数组表示字符串,也可用字符指针变量来表示字符串。 既可以逐个字符引用字符串,也可以整体引用字符串。 字符串在内存中的起始地址称为字符串的指针,可以定义一个字符指针变量指向一个字符串。第29页 在在C语言中,有两种方式可以操作字符串:语言中,有两种方式可以操作字符串:1. 使用字符数组使用字符数组 #include int main() char string = “she is our teacher “; printf(%sn,string); return 0;例例9.5 使

33、用字符数组来输出一串字符串。程序运行输出: she is our teacher第30页2. 使用字符指针使用字符指针 # include int main()char *string =“she is our teacher”; printf(“%sn”,string); return 0;程序中程序中stringstring是一个指针变量,是一个指针变量,语句:语句:char char * *string = “she is our teacher”;string = “she is our teacher”; 等价于等价于: char * string; string = “she is

34、 our teacher”; 上面语句把字符串常量的首地址赋给指针上面语句把字符串常量的首地址赋给指针string。不能理解为把字符串常。不能理解为把字符串常量赋值给指针变量。若写成下面形式量赋值给指针变量。若写成下面形式是错误的是错误的: *string =“she is our teacher”; 例例9.6 使用字符指针来输出一串字符串。使用字符指针来输出一串字符串。第31页 从以上两个例子,可以看出: (1)字符数组和字符指针的概念不同。 (2)字符指针指向字符串,在C语言中,字符串按数组方式处理,因此,字符数组和字符指针的访问方式相同。 例如,无论使用字符数组或是字符指针引用字符串,

35、都可以使用例如,无论使用字符数组或是字符指针引用字符串,都可以使用%s格式控制符进行整体输入输出。格式控制符进行整体输入输出。 ,如果不是字符数组,而是整型、实型等数字型数组,不能用,如果不是字符数组,而是整型、实型等数字型数组,不能用%s,只能逐个元素处理。,只能逐个元素处理。 第32页 将一个字符串从一个函数传递到另一个函数,可以用字符数组名或字符指针变量作参数。有以下四种情况: 1实参和形参都为字符数组。实参和形参都为字符数组。 2实参为字符指针,形参为数组名。实参为字符指针,形参为数组名。 3实参和形参都为字符指针变量。实参和形参都为字符指针变量。 4实参为数组名,形参为字符指针变量。

36、实参为数组名,形参为字符指针变量。 第33页例例9.7 用函数调用实现字符串的复制用函数调用实现字符串的复制1.实参和形参都为字符数组实参和形参都为字符数组 # include v void copy_string(char str1 , char str2 ) int i=0; while(str1i != 0) str2i = str1i; i+; str2i = 0; int int main() char a2020 = “I love china!love china!”; char b2020 = “good!”; printf(“a =%sn b =%sn”, a,b); cop

37、y_string(a,b); printf(“a =%sn b =%sn”, a,b); return 0; return 0; 第34页2.实参为字符指针,形参为数组名实参为字符指针,形参为数组名 # include void copy_string(char str1, char str2) int i=0; while(str1i != 0) str2i = str1i; i+; str2i = 0; int int main()int i; char *a = “I love china!love china!”; char *b = “good!”; printf(“a =%sn b

38、 =%sn”, a,b); copy_string(a,b); for (i=0; for (i=0;* *(a+(a+i)!=)!=00; i+) ; i+) putchar( putchar(* *(a+(a+i);); printf(“n”); for (i=0; for (i=0;* *(b+(b+i)!=)!=00; i+) ; i+) putchar( putchar(* *(b+(b+i);); return 0; return 0;例例9.7 用函数调用实现字符串的复制用函数调用实现字符串的复制 第35页3.实参和形参都为字符指针变量实参和形参都为字符指针变量 # includ

39、e void copy_string copy_string (char *str1, char *str2) for(; *str1str1 != 0; str1+, str2+) *str2 = *str1; *str2 = 0; 例例9.7 用函数调用实现字符串的复制用函数调用实现字符串的复制 int main() char *a = “I love china!”; char *b = “good!”; for (i=0;*(a+i)!=0; i+) putchar(*(a+i); printf(“n”); for (i=0;*(b+i)!=0; i+) putchar(*(b+i);

40、 printf(“n”); copy_string(a,b); puts(a); puts(b); return 0; 第36页4.实参为数组名,形参为字符指针变量实参为数组名,形参为字符指针变量 # include void copy_string (char *str1, char *str2) int i=0; for(; (*(str2+i)=*(str1+i)!= 0; i+) ; /*循环体为空语句循环体为空语句*/ int int main() char a a20= “I love china!love china!”; char b b20= = “good!good!”;

41、printf(“a =%sn b =%sn”, a,b); copy_string (a a, b b); pu uts s(a); puts(b);); puts(b); return 0;return 0; 程序说明:以上四种方式实现相同的功程序说明:以上四种方式实现相同的功能,即把能,即把a a中的字符串拷贝到中的字符串拷贝到b b中,不同的地中,不同的地方是拷贝函数参数的方式不同。方是拷贝函数参数的方式不同。 在第四种方式中,语句在第四种方式中,语句for(; (*(str2+i)=*(str1+i)!= 0; i+) ; 的执行过程为:首先将源串中的当前字符,的执行过程为:首先将源串

42、中的当前字符,复制到目标串中;然后判断该字符是否是字复制到目标串中;然后判断该字符是否是字符串结束标志。如果不是,则相对位置变量符串结束标志。如果不是,则相对位置变量i的值增的值增1,以便复制下一个字符;否则结束,以便复制下一个字符;否则结束循环。其特点是:先复制、后判断,循环结循环。其特点是:先复制、后判断,循环结束前,结束标志已经复制了。束前,结束标志已经复制了。例例9.7 用函数调用实现字符串的复制用函数调用实现字符串的复制 上述四个程序的运行结果都是:上述四个程序的运行结果都是:a=I love china!a=I love china!b=I love china!b=I love

43、china!第37页 虽然用字符指针变量和字符数组都能实现字符串的存储虽然用字符指针变量和字符数组都能实现字符串的存储和处理,但二者是有区别的:和处理,但二者是有区别的: (1)存储内容不同)存储内容不同 字符指针变量中存储的是字符串的首地址,而字符数组字符指针变量中存储的是字符串的首地址,而字符数组中存储的是字符串本身(数组的每个元素存放一个字符)。中存储的是字符串本身(数组的每个元素存放一个字符)。(2)赋值方式不同)赋值方式不同 对字符指针变量,可采用下面的赋值语句赋值:对字符指针变量,可采用下面的赋值语句赋值:char *pointer;pointer=This is a exampl

44、e.; 而字符数组,虽然可以在定义时初始化,但不能用赋值语而字符数组,虽然可以在定义时初始化,但不能用赋值语句整体赋值。下面的用法是非法的:句整体赋值。下面的用法是非法的:char char_array20;char_array=This is a example.; /*非法用法非法用法*/ 第38页(3)指针变量的值是可以改变的,字符指针变量也不)指针变量的值是可以改变的,字符指针变量也不例外;而数组名代表数组的起始地址,是一个常量,而例外;而数组名代表数组的起始地址,是一个常量,而常量是不能被改变的。常量是不能被改变的。例如:例如: char *a =“abcdefg”; a=a+3;

45、puts (a);执行后输出执行后输出“defg”。但下面的执行后却要出错:但下面的执行后却要出错: char a6=“china”; a=a+3;puts(a);因为因为a=a+3是非法的。是非法的。第39页 指针可以指向一维数组,同样也可以指向二维数组,或指向更高维数组,但指向二维数组或多维数组的指针更复杂一些。 第40页 二维数组是一个由类型相同的变量构成的集二维数组是一个由类型相同的变量构成的集合,其元素合,其元素以行优先顺序以行优先顺序存放在内存中。可以存放在内存中。可以将二维数组看成是由几个一维数组作为元素组将二维数组看成是由几个一维数组作为元素组成的一个一维数组。成的一个一维数组

46、。 例如下面定义的数组例如下面定义的数组a a: int a34=1=1,2 2,3,3,,44, 55,6 6,7 7,88, 99,1010,1111,1212;由由1212个整型变量构成,这个整型变量构成,这1212个数组元素按行顺个数组元素按行顺序存放,如右图所示。可以将序存放,如右图所示。可以将a a看成是一维数组,看成是一维数组,它由它由a0、a1、a2三个数组元素组成;且三个数组元素组成;且a0、a1、a2 也是一维数组,长度为。也是一维数组,长度为。 二维数组的地址或指针可以分成两种:一种二维数组的地址或指针可以分成两种:一种用来表示真实的数组元素的地址,称为用来表示真实的数组

47、元素的地址,称为元素地元素地址址,也就是元素指针;另一种用来表示数组的,也就是元素指针;另一种用来表示数组的每一行的地址,称为每一行的地址,称为行地址行地址,也就是行指针。,也就是行指针。第41页 二维数组二维数组a中元素中元素aij的地址或指针可以用的地址或指针可以用& &aij来表示。由于我们将二维数组看成是由来表示。由于我们将二维数组看成是由几个一维数组作为元素组成的一个一维数组,几个一维数组作为元素组成的一个一维数组,将二维数组的每一行看成是一个一维数组,将二维数组的每一行看成是一个一维数组,ai是一维数组名,由一维数组与指针的关系知,是一维数组名,由一维数组与指针的关系知,元素元素a

48、ij的地址或指针可以用的地址或指针可以用ai+j来表示来表示。 语言规定数组名代表数组的首地址。二维语言规定数组名代表数组的首地址。二维数组名数组名a是一个行地址,是一个行地址,a+0a+0、a+1a+1、a+2a+2分别是分别是下标为下标为0 0、1 1、2 2行的地址,即行的地址,即以以a0a0、a1a1、a2a2为一维数组名的行地址。为一维数组名的行地址。 即即a a(a+0a+0)是一维数组)是一维数组a0a0的首地址,的首地址,a+1a+1是一维数组是一维数组a1a1的首地址,的首地址,a+2a+2是一维数组是一维数组a2a2的首地址,的首地址,如右图所示。如右图所示。第42页 如果

49、如果b是一维数组名,是一维数组名,bi为为b数组的数组的一个元素,那么有一个元素,那么有bi等价于等价于*(b+i)。同。同样,样,a是二维数组名,是二维数组名,ai为为a数组的一个数组的一个元素(将元素(将a看成一维数组时,看成一维数组时,ai为为a数组数组的一个元素),也有的一个元素),也有ai 等价于等价于*(a+i)。 所以二维数组所以二维数组a中元素中元素aij的地址的地址或指针既可以用或指针既可以用ai+j来表示,也可以用来表示,也可以用*(a+i)+j来表示。来表示。 综上所述,二维数组综上所述,二维数组a中元素中元素aij的的地址或指针可以表示成以下几种形式:地址或指针可以表示

50、成以下几种形式: &aij、 ai+j、 *(a+i)+j 对应地,数组元素对应地,数组元素aij 可以表示成以可以表示成以下几种形式:下几种形式: aij、 *(ai+j)、 *(*(a+i)+j)第43页 二维数组是由相同类型的一维数组作为元素而构成的一二维数组是由相同类型的一维数组作为元素而构成的一维数组,所谓行指针变量就是用来存放维数组,所谓行指针变量就是用来存放“行地址行地址”的变量。的变量。 行指针变量的定义形式如下:行指针变量的定义形式如下: 类型标识符类型标识符 (*行指针变量名行指针变量名)数组长度数组长度; 注意:注意:“*行指针变量名行指针变量名”外的括号不能缺,否则成了

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 大学资料

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁