C++课件 第9章 指针、引用和链表.ppt_第1页
C++课件 第9章 指针、引用和链表.ppt_第2页
C++课件 第9章 指针、引用和链表.ppt_第3页
C++课件 第9章 指针、引用和链表.ppt_第4页
C++课件 第9章 指针、引用和链表.ppt_第5页
已阅读5页,还剩148页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第 9 章 指针、引用和链表,本章主要内容,9.1 指针和指针变量 9.2 指针作函数参数 9.3 指针和指向数组的指针 9.4 指针数组 9.5 指向指针的指针 9.6 指针和函数 9.7 指针小结 9.8 引用、const型变量和const型指针 9.9 存储空间的动态分配和释放 9.10 链表及其应用 9.11 用typedef定义新类型名, 内存中的一个字节为一个存储单元( Byte)。 存储单元的编号称为地址。 变量的地址是指该变量所在存储区域的第一个 字节(单元)的地址。,9.1 指针和指针变量 9.1.1 指针的概念,例:int a; float b; char c;,这三个地址

2、就称为变量a、b、c的指针。,指针也是一个数值, C+提供了一种类型的变量用于存放地址值, 即存放指针,这种变量就是指针变量。,9.1.2 指针变量的定义,指针变量的定义格式:类型说明符 *指针变量名;,例:int *pi ; 定义 pi 为指向 int 类型变量的指针变量 float *pf ; 定义 pf 为指向 float 类型变量的指针变量,int * 为int型指针类型标识符。 float * 为float型指针类型标识符。,几点说明: 一个指针变量只能指向同一数据类型的变量,该 数据类型是在定义指针变量时明确给定的。 C+语言规定有效数据的指针不指向0单元(为非0值), 如果指针变

3、量值为0,即NULL(在ios.h中已定义), 表示空指针,即不指向任何变量。 不要把地址值与整数类型值相混淆。 例如:地址2000与整型量2000是两个不同的概念。,1、 /将整型变量 m 的地址值赋给指针变量 p,9.1.3 有关指针的运算符 p= 将 100 赋给指针变量 p 所指向的变量 m,n,9.1.4 指针变量的初始化 初始化格式:类型说明符 *指针变量名=初始地址值 ; 例:char c, *p1 ; p1=/* 指针初始化,定义时进行 */,两种方式等效,9.1.5 直接访问和间接访问,在C+中定义的所有变量,编译器都会记录它们的属性, 便于以后对它们的访问, 如在例9.1中

4、定义的两个变量m和p, 编译器记录的属性如下表:,表9-1 变量及其属性,1. 直接存取方式(直接访问) 按变量地址存取变量值的方式称为直接存取方式, 在程序中体现为直接使用变量名来存取变量值,2. 间接存取方式(间接访问),如果变量 p 存放着变量 m 的地址,那么, 对变量 m 的访问可以首先访问变量 p,取得 变量 m 的地址,然后按该地址进行对 m 的存取 操作, 称为间接存取方式。 在程序中体现为通过 p 来存取变量 m 的值。,例: m=5,n=m 直接存取 m *p=5,n=*p 间接存取 m,间接存取的前提是什么?,总结: char *cp= ,输出:? AA BB aa,例9

5、.4 变量的直接访问和间接访问 int a=1; float b=5.2; char c=A; int *p1; float *p2; char *p3; p1=,运行结果:?,1, 5.2, A 1, 5.2, A,续:*p1=*p1+1; *p2=*p2+2; *p3=*p3+3; cout a , b , c endl;,运行结果:?,2, 7.2, D,关于指针使用的几点说明: 指针变量必须通过初始化或赋值获得值后(即必须明确指向某一变量),才可以利用它进行间接访问。 若有 int m ; int *p = 是无意义的。,关于指针使用的几点说明(续): 同类型指针变量之间可以相互赋值,

6、不同类型的指针变量一般不能相互赋值,如在例9.4中,若出现 p1 = p2 ; 是无意义的。 允许将一个整型常数经强制类型转换后赋给指针变量,如: float *fpp ; fpp = (float *)5000 ; 其意义:将5000作为一个地址值赋给指针变量fpp 。,例9.5 交换两个指针的指向,int x=10, y=20; int *p1=,cout *p1 t *p2 endl; t=p1; p1=p2; p2=t; cout *p1 t *p2 endl;,例9.6 通过指针,交换两个指针所指向的变量的值,int x=10, y=20,t; int *p1 =,cout x ,

7、y endl; t=*p1;*p1=*p2; *p2=t; cout x , y endl;,9.1.6 地址值的输出,例9.7 #include void main(void) int a, *p1; float b, *p2; double d, *p3; p1= ,输出结果:p1=0 x0012FF7C p2=0 x0012FF74 p3=0 x0012FF68,如果希望输出 十进制地址值, 则改程序为:=, 地址值的输出(输出十进制地址值),例:#include void main( ) int a, *p1; float b, *p2; double d, *p3; p1= ,输出结

8、果:p1=6684148 p2=6684140 p3=6684132, 指针使用的常见错误 1、使用未初始化的指针变量 void main( ) int x,*p ; x=0 ;*p=x ; . 2、指针变量所指向的数据类型与其定义的类型不符 void main( ) float x,y ; int *p ; p= . ,#include /复习 void main( ) int x=10, y ; int *p1= ,例9.8 基本类型量作函数参数 #include void swap(int x,int y) int t; t=x; x=y; y=t; void main( ) int x

9、=3, y=9; swap(x,y); cout x , yendl; 输出?,局部动态变量,3,9,main( ) 工作区,swap1( ) 工作区,9.2 指针作函数参数 9.2.1基本类型量作函数参数,实参x、y 和形参 x、y 是不同的变量,占据不同的存储空间。 参数传递时:int x=x,int y=y;,例9.9指针作函数参数 #include void swap(int *px,int *py) int t; t=*px;*px=*py;*py=t; void main( ) int x=3,y=9,*p1,*p2; p1= 输出?,局部动态变量,9,3,指针作为函数参数, 可以

10、改变主调函数中 变量的值。,main( ) 工作区,swap2( ) 工作区,参数传递时, 有:int *px=p1; int *py=p2;,被调函数中参数的指针,相当于一只手,9.2.2 指针变量作函数参数,例9.10约简分数(用分子分母的最大公约数除分子分母) void lowterm(int *num ,int *den) int n ,d ,r ; n=*num ; d=*den ; while(d!=0) /*求分子分母的最大公约数*/ r=n%d ; n=d ; d=r ; if(n1) /* n 是最大公约数*/ *num=*num/n ; *den=*den/n ; /*直接

11、对主调函数中的实参进行间接访问操作*/ ,例:约简分数(续) #include void main(void) int a=14,b=21; cout “分数:”; cout a / b endl; cout “约减后:”; lowterm( ,输出:分数:14/21 约减后:2/3,假定: b = = 1000, 且两个数组连续存放 则:a = = ?,9.3 指针和指向数组的指针 9.3.1 一维数组与指针,1.数组名- 数组元素在内存中连续存放, 数组名是该存储区的起始地址, 是地址常量。,例:int a10; float b10; a 是 a0 元素的起始地址。 b 是 b0 元素的起

12、始地址。,1040,2.指向一维数组元素的指针变量,例:int a10; / 假定a的值为1040 int *p; / p是指向整型变量的指针, a数组的元素为整型变量, 那么 p 可以指向 a 数组的任意元素。,p=a;,/ 结果 p=1040,p 指向a0,p+;,/ 结果 p=1044,p+;,/ 结果 p=1048,p- -;,/ 结果 p2=1044,向下移动一个元素的位置,若 p = 则 *p 访问a6,3.指针可进行的运算(一般为加、减、比较运算),(1)指针数值 (2)指针-指针 (3)指针 比较 指针,(1)指针数值 运算的意义 如果:p 是指针,n 是数值 则:pn 表示

13、p 向后/向前移动 n 个元素位置。 即:结果 p 的值n*c,若 p 是 int 型指针,则 c 等于 4 若 p 是 char 型指针,则 c 等于 1 若 p 是 float 型指针,则 c 等于 4 .,例9.11 用指针间接访问数组元素 #include void main(void) int a10=1, 2, 3, 4, 5, 6, 7, 8, 9, 10 , *p = a ; int sum=0, i ; for( i=0; i10; i+) sum = sum + *(p+i); / *(p+i)piai for( i=0; i10; i+, p+) / 指针变量可进行自加、

14、自减运算 cout *p; cout sum= sum endl; ,指向相同数据类型的指针变量可以相减,其结果 为两指针所指向地址之间数据的个数。,例:int *px ,*py ,n ,a5 ; px=,(2)指针 - 指针 运算的意义,结果:n 值为3,= != =,(3)指针 比较 指针,指针的关系运算是两个指针所指向的地址之间的 比较运算,产生的结果为 0(假)和 1(真)。,例:有定义:double a5,*p1,*p2 ; p1,p2 的指向如图所示。, p1=NULL 判断p1是否为空指针?(NULL是系统定义的) 结果:0,计算: p1=p2 判断p1,p2是否指向同一变量?

15、结果:0, p1p2 判断p1的地址是否比p2的地址小? 结果:1, p1!=0 判断 p1 是否不为空指针? 结果:1,例9.12 改写例9.11,注意指针的比较运算。 #include void main(void) int a10=1, 2, 3, 4, 5, 6, 7, 8, 9, 10 , *p ; int sum=0 ; for(p = a ; p a+10; p+) sum = sum + *p ; for(p = a ; p a+10; p+) / 需重新给 p 赋初值 cout *p; cout sum= sum endl; ,以上定义等价于: int a10,*p; p=a

16、 ;,例:int a10,*p ; p=, int a10; int *p=, int a10; int *p=a ;,a p+ ; 正确 a=p+2; a+ ;错误,a+i,例9.12 P179 数组元素逆向存放 #include void main(void) int a10=1, 2, 3, 4, 5, 6, 7, 8, 9, 10, t ; int *p1=a, *p2=a+9 ; while(p1p2) t = *p1; *p1 = *p2; *p2=t; p1+ ; p2 - - ; for(p1 = a; p1 a+10; p1+) cout *p1 t ; cout endl

17、; ,void reverse(int b , int n) int i, j, t; i=0; j=n-1; while(ij) t=bi; bi=bj; bj=t; i+; j- -; ,void main(void) int a10=1,2,3,4,5,6,7,8,9,10, i; reverse(a, 10); for(i=0; i10; i+) cout ai t ; cout endl ; ,图,例9.14将数组元素逆向存放。,9.3.2一维数组元素指针作函数参数,在被调函数中数组元素 的值被改变后, 自动带回主函数, 不需要return语句返回。 注意:实参a是一个指针。,实参

18、a,main( ) 函数存储区内容,程序,例9.14将数组元素逆向存放。(续),*(b+0) *(b+1) *(b+2) . *(b+8) *(b+9) b0 b1 b2 . b8 b9 b+;,reverse( ) 函数存储区内容,在 reverse( ) 函数中, 将 b 处理成一个 int 型指针, (相当于:int *b) 通过指针 b 访问 a 数组中内容。,被调函数中参数的指针,相当于一只手,void reverse(int b , int n) / b是一个指针变量 int i, j, t; i=0; j=n-1; while(ij) t=*(b+i); *(b+i)=*(b+j

19、); *(b+j)=t; i+; j- -; / 原 t=bi; bi=bj; bj=t; ,void main(void) int a10=1,2,3,4,5,6,7,8,9,10, i; reverse(a, 10); for(i=0; i10; i+) cout ai t ; cout endl ; ,例9.14将数组元素逆向存放。( 改写 ), 一维数组名作函数参数 实参和形参的各种写法,void f( int b , int n ) . bi /或 *( b+i ) void main(void) int a10, *p; p=a; f( a , 10 ); ,例9.15分别求数组前

20、十个元素和后十个元素之和,int fsum(int *array,int n) int i,s=0; for(i=0;in;i+) s+=(*array+) ; return(s); void main(void) int a15= 1,2,3 14,15 ; int shead, stail; shead=fsum(a,10); / 第 1 次调用 stail=fsum( ,例9.16 求出数组最大元素值和最小元素值 void max_min_value (int *array, int n, int *maxp, int *minp) / maxp指向主函数max变量,minp指向主函数m

21、in变量 int *p, *array_end; array_end = array + n ; *maxp=*minp=*array; for(p=array+1; p *maxp ) *maxp=*p; else if( *p*minp ) *minp=*p; ,例9. 16 续 void main(void) int i, number10, *p = number, max, min; for(i=0; i *( p+i ) ; / 输入数组元素值 max_min_value( p, 10, ,C+ 语言中通常用char型指针来处理字符串。 1. 字符数组和字符指针 (1) 定义一个字

22、符数组存放字符串 char str10=“Hello!”; str是一维字符数组名,即起始地址。 字符数组输入输出: cin str; /不可输入带空格字符串 cin.getline(str,80);/可输入带空格字符串 cout str; 字符数组赋值:strcpy(str, “ABCD”); 访问第i个字符 stri, 或 *(str+i) 第i个字符的地址 ,“Hello!”的值是该字符串的首地址,(3) 字符数组名(str)与字符指针(strp)的区别: char str10, *strp; str - 指针常量,不论是否对字符数组赋值, 数组空间已分配,str的指向明确。 strp

23、- 指针变量,若不赋初值,则其指向不确定。,输出字符串:cout strp ;,等价于:char *strp ; strp=“Hello!”;, 赋值: char str10, *strp; strcpy(str, “ABC”); str的指向不变,改变的是存储单元的内容。 strp=“Hello!”; 将 strp 指向字符串常量“Hello!”。 strp=str; 将 strp 指向字符串数组str。,使用字符串指针易犯的错误: (1) char str10; str=“Hello!”; str是指针常量,不能给常量赋值。,(2) char str10; str =“Hello!”; 不

24、能用赋值语句给数组整体赋值。,解1:用字符数组实现 #include #include void main( ) char a20=“ABCD”, b10=“EFG”; int i, j; i = strlen(a); / i是字符串a 结尾0的下标 for(j=0; bj!=0; i+,j+) ai=bj; ai=0; cout a endl ; ,例9.18将字符串b 的内容追加到字符串a 尾部。,输出:ABCDEFG,解2:用字符指针实现 #include void main( ) char a20=“ABCD”, b10=“EFG”; char *pa=a, *pb=b; /pa指向a

25、 ,pb指向b while(*pa!=0) pa+;/循环结束后,pa指向a尾部的0 while(*pb!=0) *pa=*pb; pa+; pb+; *pa=0; pa=a; cout pa endl ; ,2.字符串指针作函数参数 例9.19 int my_strlen(char *s) / 自定义函数 int n ; for(n=0 ;*s!=0 ;s+) n+ ; return(n); void main( ) char str =“Hello!” ; cout *str t; cout my_strlen(str) t; cout *str endl; ,运行结果: H 6 H,例9

26、.20 比较两个字符串的大小 int my_strcmp(char *s,char *t) / 自定义函数 for( ; *s=*t; s+,t+) if(*s=0) return(0); return (*s*t)0 ? 1 : -1; void main( ) char s1 =“Hello!”; char *s2=“Hello!”; cout my_strcmp(s1, s2) t; cout my_strcmp(“Hi”, s2)endl; ,说明:字符串作实参,传递的是字符串的首地址,输出:0 1,例9.21:字符串拷贝函数,比较以下几个函数: void copy_string(ch

27、ar to , char from ) int i=0 ; while(fromi!=0) toi=fromi;i+ ; toi=0 ; void copy_string(char to , char from ) int i=0 ; while(toi=fromi)!=0) i+ ; void copy_string(char *to, char *from) while(*to=*from)!=0) to+ ; from+ ; void copy_string(char *to, char *from) while(*to+ = *from+)!=0) ; void copy_string

28、(char *to, char *from) while(*to+ = *from+) ; ,9.3.4 二维数组与指针 1、二维数组的地址 (1) 行指针和元素指针 例:有定义:int a34;,二维数组名 a 指向 a0, a 是行指针, a+1指向下一行, 即指向a1。,a1和a2的意义类推!,注意: a和ai是两种类型不同的指针常量。 ai的类型是 int *,从元素指针的角度来看: 若欲访问aij,可以写成 *( ai+j ) 从行指针的角度来看: *(a+i) = ai 所以访问元素aij,也可写成 *(*(a+i)+j ),(2)二维数组中元素aij地址的表示: int sum=

29、0, i, j; for(i=0; i *(ai+j); /注意二维数组元素的访问方法 for(i=0; i3; i+) for(j=0; j4; j+) sum += *(*(a+i)+j); /B cout sum endl; ,2. 指向一维数组的指针变量(行指针) 例:int (*p)4; int a34;,注意:数组名 a 和 p 同为行指针,但 a 是指针常量, 而 p 是指针变量。,定义一个行指针p,指向一维数组,该一维数组 包含4个整型数值(相当于二维数组的一行元素)。,p=a ; / p和a的类型一样,类型为 int(*)4,比较: 与一维数组名等价的指针变量(指向数组元素的

30、指针) int a10, *p; / 类型是 int * p=a; 与二维数组名等价的指针变量(指向一维数组的指针) int a34; int (*p)4; p=a; / 类型是 int (*)4,例:输出一个指定行、列下标的二维数组元素值 void main( ) int a34=.; int (*p)4, i, j; p=a; cin i j; /输入行标、列下标 cout a i j = *(*(p+i)+j) endl; ,例9.24 求二维数组全体元素之和 int total(int(*p)4, int n) /n 行数 int i,j, sum=0; for( i=0 ;i *(a

31、i+j); sum = total( a, 3 ); cout sum endl; ,3. 二维数组名作函数参数,例9.24 改写 total( )函数 int total(int(*p)4,int n) /n 行数 int i, j, sum=0 ; for( i=0; in; i+, p+ ) for( j=0; j4; j+) sum += *( *p + j ) ; return sum; ,形参二维数组名的三种写法,void f( int b34 ) . *(*(b+i)+j) bij void main( ) int a34; f(a); ,4、将二维数组看成一维数组访问 (1)

32、通过元素指针访问二维数组元素 例9.25 输出二维数组全体元素的值。 void main(void) int a34=.; int *p ; for(p=a0;pa0+12;p+) if(p-a0)%4=0) cout endl ; cout setw(4) *p ; cout endl ; ,p,例9.26 编写通用二维数组输出函数。,void print(int *p, int row, int col) int i; for(i=0; irow*col; i+, p+) if(i%col=0) coutn; coutsetw(4) *p; coutn; void main(void) i

33、nt a34=1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12; int b23=1, 2, 3, 4, 5, 6; print(a0, 3, 4); print(b0, 2, 3); ,(2)已知一个二维数组为N行M列,即aNM, 将二维数组看成一维数组后, 求aij放在第几个位置?,二维数组按行存放, aij的前面有 i*M+j 个元素, 若序号从0开始, 则aij的序号是:i*M+j,若 int *p=a0; 则 p+i*M+j 是aij的地址。,void f( int b 4 ) . *(*(b+i)+j) bij void main( ) int a34;

34、f(a); ,解释二维数组作参数时,参数第一维可缺省原因,例9.27 输入二维数组任一行号 i, 任一列号 j, 输出其元素aij的值。 void main(void) int a34=.; int *p,i,j; p=a0; cin i j; cout a i j = *(p+i*4+j) endl; ,9.3.5 获得函数处理结果的几种方法 1、利用return语句返回值 (只能返回一个值) 例:int min(int a, int b) return(ab)?a:b); ,2、利用全局变量得到函数调用结果 (安全性欠佳) 例:int max, min ; /可得到多个结果 void fu

35、n(int a, int b) max=(ab)?a:b ; min=(ab)?a:b ; void main( ) fun(5, 8); coutmax,minendl; ,3、利用指针变量作为函数参数来取得函数调用的结果。 (较好,可安全地得到多个结果值) 涉及参数空间的分配 (1)普通变量指针作参数 例:void fun(int a, int b, int *pmax, int *pmin) *pmax=(ab)?a:b ; *pmin=(aab; fun(a, b, ,(2)数组名作参数 数组名作参数时,传递的是数组首地址, 在被调函数中可以通过首指针访问数组元素, 本质上与普通变量指

36、针作参数是一样的。回顾例9.14 void reverse( int b , int n ) 等价于 int *b, int n int t; int *p2 = b+n-1; 下页图 while(b p2) t = *b; *b = *p2; *p2=t; b+; p2- ; void main(void) int a10=1,2,3,4,5,6,7,8,9,10, i; reverse(a, 10); for(i=0; i10; i+) cout ai t ; cout endl ; ,实参 a,main( ) 函数局部变量,reverse( ) 函数局部变量,4、利用引用作为函数参数来取

37、得函数调用的结果 (较好,可安全地得到多个结果值) 不涉及参数空间的分配 例:void fun(int a, int b, int ,形参变量是实参的别名, 使用起来较方便、直观。,9.4 指针数组,数组元素 的值为:,数组元素值为指针的数组称为指针数组,9.4.1 指针数组的定义和使用,1. 基本概念,2. 指针数组的定义和说明 定义格式:类型说明符 *指针数组名元素个数 例:int *p10 ; 数组p 的10个元素 p0, p1 p9 都是指向 int 型数据的指针。 数组的10个元素都是 int * 类型的。,例:int a=6, b=8, c=2; int *p10; p0 = ,输

38、出:6, 8, 2,例9.28利用指针数组输出另一个数组中各元素的值 。 #include void main( ) float a5= 2, 4, 6, 8, 10 ; float *p5= ,输出:2 4 6 8 10,9.4.2 使用指针数组处理二维数组 例:int a33,*p3,i ; ( p3是指针数组 ) for(i=0;i3;i+) pi=ai;,说明:p 数组的三个元素 分别是指向整型变量的指 针(元素指针)。,例9.29输出二维数组全体元素的值 void main(void) int a23=1,2,3,4,5,6; int *pa =a0,a1; int i ,j ; f

39、or(i=0;i2;i+) for(j=0;j3;j+) cout *(pai+j) t; cout n; 运行结果:1 2 3 4 5 6,9.4.3 利用字符指针数组处理字符串,char *name =George, Mary, Susan, Tom, Davis;,括号中的每一个字符串都是一个地址值。,#include #include void main( ) char *name = George, Mary, Susan, Tom, Davis ; char *ptr; int i, j, k, n=5;,例9.30 按字典序将上述5个字符串排序,输出。 此程序主算法是选择法排序,

40、 通过交换指针的指向来达到排序的目的。,for(i=0; i0 ) /字符串比较, k=j; /记住最小字符串指针的下标。 if(k!=i) ptr=namei; namei=namek; namek=ptr; /交换指针数组元素值 for(i=0; in; i+) /输出结果 cout namei endl; ,结果指针的指向:,运行结果是: Davis George Mary Susan Tom,指针数组元素指向的是字符串常数, 每个字符串的长度都不一样, 所以只能通过交换指针的指向 实现排序。,例9.31改写例9.30,学习如何使用指针数组作函数参数。 #include #include

41、 void main( ) void sort(char * , int), print(char * , int); /函数原型说明,因为函数定义在后 char *name =George, Mary, Susan, Tom, Davis; int n=5 ; sort( name, n); print( name, n); ,void sort(char *name , int n)/函数定义,注意参数的写法 char *ptr; int i, j, k; for(i=0; i0 ) k=j; if(k!=i) ptr=namei;namei=namek;namek=ptr; void p

42、rint(char *name , int n) /函数定义,注意参数的写法 for(int i=0; in; i+) cout namei endl; ,(1)int *p; 一般指针,可与一维数组名等价。 如有:int a10; p=a; 可用pi访问数组元素。 (2)int (*p)M; 指向含有 M 个元素的一维数组, 可与二维数组名等价。p 是一个行指针。 如有:int a4M; p=a; 可用pij访问数组元素。,相应的数据类型 int (*)M int * int int (*)M int *,指针小结:,float a5=100, 200, 300, 400, 500; flo

43、at *p5= ,(3)int *pM; 指针数组,有M个元素, 每个元素都是指针,即有M个指针。,如何访问ai?,9.4.4 指针数组作 main 函数的形参 main( )函数的参数格式: void main(int argc, char *argv ) . ,形参argc:命令行中参数的个数 形参argv:指针数组的各元素分别指向命令行中 各字符串的首地址。,例9.32 了解 main 函数参数的意义 void main(int argc, char *argv ) cout argc= argc endl; cout Command name: argv0 endl; for(int

44、i=1;iargc;i+) cout argvi endl; ,源程序文件名: Li0932.cpp 源程序文件存放位置: D:cpp 可执行程序位置: D:cppDebug 可执行程序文件名: Li0932.exe,(1)通过DOS命令行执行程序,程序的一种执行方式,命令行: D:cppDebug Li0932 par1 par2 /p /w ,Project | Settings | Debug | Program arguments,该程序运行后的结果如下: argc=5 Command name=D:cppDebugLi0932.exe par1 par2 /p /w,演示在集成环境和

45、 DOS环境中的运行情况,(2)在集成环境中设置命令行参数,main 函数参数的意义,9.5 指向指针的指针(二级间接访问) 指向指针的变量称为指针的指针。 其定义的一般格式:类型说明符 *指针变量名,int x=3, *p1, *p2; p1=,一级间接访问 x: *p 二级间接访问 x: *p1;,例9.33 void main( ) char *p ; char *s = up, down, left, right ; int i ; p=s ; for( i=0; i4; i+ ) cout *p+ t; ,运行结果:up down left right,图,指针数组名本质上就是指向指

46、针的指针。,1. 函数指针的定义和说明 一个函数被编译后生成一段二进制代码,该段代码的首地址称为函数的入口地址,即函数指针。 C+将函数名的值处理成函数的入口地址,函数名即函数指针。 可以定义一个指针变量,用于存放函数的入口地址,该指针称为函数指针变量。,9.6 指针和函数 9.6.1 函数指针,例: int (*fp)(int,int); 定义函数指针 fp 指向具有两个 整型参数,并且返回值为整型数据的函数。 int max(int,int); 说明函数 max。 fp=max ; 将函数 max 的入口地址赋给指针变量fp, fp 和 max 都指向函数的入口, 即fp 和 max 的值

47、都是函数的入口地址。, 函数指针定义格式: 类型说明符 (*函数指针名)(参数类型表);,void main( ) int max(int,int); / 函数原型说明 int (*fp)(int, int); / 定义函数指针 fp fp = max; int max(int x,int y) return(xy?x:y); ,函数指针变量的意义,max 的值为 2000! fp 是一个变量! fp 得到的值也是2000!,函数可以通过函数名调用,也可通过函数指针调用。 如果 fp=max,则对函数 max 的调用方式是: max(实参表); / 通过函数名调用 fp(实参表); / 通过函

48、数指针调用 (*fp)(实参表);/ 通过函数指针调用,2. 函数指针的使用,void main( ) int max(int,int),min(int,int); / 函数原型说明 int (*fp)(int, int); / 定义函数指针 fp int a,b,c,d; cin a b ; fp=max; / fp 指向 max( ) 函数 c=fp(a,b); / 通过 fp 调用 max( ) 函数 fp=min; / fp 指向 min( ) 函数 d=(*fp)(a,b); / 通过 fp 调用 min( )函数 couty?x:y); int min(int x,int y) r

49、eturn(xy?x:y); ,例9.34 通过函数指针变量调用函数,例9.35函数名作参数,通过一个公用接口调用三个函数 void main( ) int max(int,int),min(int,int),sum(int,int); int process(int, int, int (*)(int,int); int a,b ; cout a b ; cout “max=” process(a,b,max) endl; cout “min=” process(a,b,min) endl; cout “sum=” process(a,b,sum) endl; int process(int

50、 x,int y, int (*fun)(int,int) return fun(x,y); ,例9.35 续 int max(int x, int y) return( xy ? x :y ); int min(int x, int y) return( xy ? x :y ); int sum(int x, int y) return( x + y ); ,运行时:输入 4 8 输出 max=8 min=4 sum=12,例9.36 编写一个通用的积分函数求下列三个定积分的近似值 用梯形法求定积分的通用公式为:,#include 例9.36 #include double f1(doubl

51、e x) return(sin(x)+1); double f2(double x) return(1 + x + x*x + x*x*x); double f3(double x) return x/(1+x*x); /通用的求积分函数 double integral(double(*f)(double),double a,double b,int n ) double s, h; int i; h=(ba)/n; s=(f(a)+f(b)/2; for(i=1; in; i+) s+=f(a+i*h); return(s*h); ,void main( ) 例9.36 coutf1积分值:

52、integral(f1, 0, 1, 3000)endl; coutf2积分值:integral(f2, 0, 2, 1000)endl; coutf3积分值:integral(f3, 1, 2.5, 2000)endl; 程序运行结果: f1积分值:1.4597 f2积分值:10.6667 f3积分值:0.643927,9.6.2 返回指针值的函数(指针函数),通常 int f1( ); 返回 int 型数 float f2( ); 返回 float 型数 char f3( ); 返回 char 型数,有时需要一个函数的返回值为指针, 称该函数为指针型函数。 定义指针型函数的格式: 类型说明

53、符 *函数名(参数表) 函数体 ,例 :int * f1( ); 返回 int 型指针 float * f2( ); 返回 float 型指针 char * f3( ); 返回 char 型指针,#include char *find(char *str, char ch) while(*str!=0) if(*str=ch) return(str); else str+; return(NULL); /若找不到,返回空指针 void main( ) char s =warrior; char *p; p=find(s, r); if(p) cout p endl; p=find(s, i);

54、 if(p) cout p endl; p=find(s, b); if(p) cout p endl; ,例9.37在一个字符串中找出某个字符第一次出现时的地址,/ 输出 rrior / 输出 ior / 不输出,9.7 指针小结: int *p; 一般指针,可与一维数组名等价。 int (*p)M; 指向含有 M 个元素的一维数组, 可与二维数组名等价。 int *pM; 指针数组,有M个元素,每个元素都是指针。 int *p; 指向指针的指针。 int (*p)(int, int); 函数指针,指向参数是两个整型值、 并且返回整型值的函数。 int *p( ). 返回整型指针值的函数。,

55、9.8 引用和其他类型的指针 9.8.1 引用类型变量的说明及使用,例:int a; int ,意义:给变量 a 定义了一个别名 ref 。,例:int a; int ,输出:88 1010,例9.38 为指针类型变量定义引用 #include void main( ) int a; int *p= 程序运行后,输出: 8, 8, 8,除了基本类型的变量可以定义引用外, 指针类型也可以定义引用。,注意事项:,一个变量可定义多个引用: int i; int ,可定义引用的引用: int i; int ,不能将数组定义为引用,但可为数组元素定义引用 int a10; int ref2 a5,9.8.2 引用和函数 引用类型变量主要用作函数参数,1基本类型变量和指针变量作函数参数 回顾一下用基本类型变量和指针变量作函数参数 的两个例子:,例9.8 基本类型量作函数参数 #include void swap(int x, int y) int t ; t = x ; x = y ; y = t ; void main( ) int x=3, y=9; swap(x, y); cout

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论