《间接访问指针》PPT课件.ppt

上传人:牧羊曲112 文档编号:5617457 上传时间:2023-08-02 格式:PPT 页数:109 大小:360.50KB
返回 下载 相关 举报
《间接访问指针》PPT课件.ppt_第1页
第1页 / 共109页
《间接访问指针》PPT课件.ppt_第2页
第2页 / 共109页
《间接访问指针》PPT课件.ppt_第3页
第3页 / 共109页
《间接访问指针》PPT课件.ppt_第4页
第4页 / 共109页
《间接访问指针》PPT课件.ppt_第5页
第5页 / 共109页
点击查看更多>>
资源描述

《《间接访问指针》PPT课件.ppt》由会员分享,可在线阅读,更多相关《《间接访问指针》PPT课件.ppt(109页珍藏版)》请在三一办公上搜索。

1、第7章 间接访问指针,指针的概念指针运算与数组动态内存分配字符串再讨论指针作为函数参数和返回值指针数组与多级指针指向多维数组的指针指向函数的指针,指针介绍,本章将介绍C+语言的一个重要的特性:指针,为了成为一个优秀的C+语言程序员,你必须掌握指针并熟练地使用它们。,指针是内存的地址并可作为数据是一个灵活和危险的机制允许共享处理数据允许内存动态分配(只要需要,而非预先定义),指针的概念,指针就是把地址作为数据处理指针变量:存储地址的变量变量的指针:当一个变量存储另一个变量的地址时,那我们说它就是那个变量的指针使用指针的目的:提供间接访问,指针的概念 续,如在某一程序中定义了 int x=2;如系

2、统给x分配的空间是1000号单元,则指向x的指针是另一个变量p,p中存放的数据为10001000号单元的内容有两种访问方式:访问变量x(直接访问)访问变量p指向的单元的内容(间接访问),定义指针变量,定义指针变量要告诉编译器该变量中存放的是一个地址。指针变量的主要用途是提供间接访问,因此也需要知道指针指向的单元的数据类型指针变量的定义 类型标识符*指针变量;如:int*intp;double*doublep;int*p,x,*q;,指针变量的操作,如何让指针指向某一变量?因为我们不知道系统分配给变量的真正地址是什么。用地址运算符“&运算符后面不能跟常量或表达式。如&2 是没有意义的,&(m*n

3、+p)。也是没有意义的如何通过指针变量处理和改变它所指向的单元的值?用引用运算符“*”解决。如*intp 表示的是 intp 指向的这个单元的内容。如:*intp=5 等价于 x=5在对 intp 使用引用运算之前,必须先对 intp 赋值,指针实例,如有:int X,*intp,Y;X=3;Y=4;intp=,如执行:*intp=Y+4;,注意:不能用 intp=100;因为我们永远不知道变量存储的真实地址,而且程序每次运行变量地址可能都不同。,指针使用,指针变量可以指向不同的变量。如上例中intp指向x,我们可以通过对intp的重新赋值改变指针的指向。如果想让intp指向y,只要执行int

4、p=&y就可以了。这时,intp与x无任何关系。同类的指针变量之间可相互赋值,表示二个指针指向同一内存空间。空指针指针没有指向任何空间空指针用常量NULL表示,NULL的值一般赋为0不能引用空指针指向的值,指针变量的使用,设有定义 int x,y;int*p1,*p2;,执行语句:x=23;y=234;,执行语句:p1=,执行语句:*p1=34;p2=p1;,指针实例,有以下结构,比较执行 p1=p2和*p1=*p2后的不同结果。,指针的初始化,指针在使用前必须初始化。和别的变量一样,定义指针不初始化是一个比较普通的错误。没有初始化的指针可能指向任意地址,对这些指针作操作可能会导致程序错误。N

5、ULL是一个特殊指针值,称为空指针。它的值为0。它可被用来初始化一个指针,表示不指向任何地址。思考:int*p;*p=5;有什么问题?,第7章 间接访问指针,指针的概念指针运算与数组动态内存分配字符串再讨论指针作为函数参数和返回值指针数组与多级指针指向多维数组的指针指向函数的指针,指针运算和数组,指向数组元素的指针数组元素是一个独立的变量,因此可以有指针指向它。如:p=&a1,p=&ai数组元素的地址是通过数组首地址计算的。如数组的首地址是 1000,则第i 个元素的地址是1000+i*每个数组元素所占的空间长度,指针与数组,在C+中,指针和数组关系密切,几乎可以互换使用数组名可以看成是常量指

6、针,对一维数组来说,数组名是数组的起始地址,也就是第0个元素的地址如执行了p=array,则p与array是等价的,对该指针可以进行任何有关数组下标的操作,例如:有定义 int a10,*p 并且执行了 p=a,那么可用下列语句访问数组a的元素for(i=0;i10;+i)cout pi;,指针运算,指针+1表示数组中指针指向元素的下一元素地址;指针-1表示数组中指针指向元素的上一元素地址;合法的指针操作:p+k,p-k,p1-p2,指针保存的是一个地址,地址是一个整型数,因此可以进行各种算术运算,但仅有加减运算是有意义的。指针运算与数组有密切的关系,数组元素的指针表示,当把数组名,如 int

7、array,赋给了一个同类指针intp 后,intarray 的元素可以通过intp访问。第i个元素的地址可表示为 intp+i,第i个元素的值可表示为*(intp+i)。通过指针访问数组时,下标有效范围由程序员自己检查。如输出数组 a 的十个元素,方法3:for(p=a;pa+10;+p)cout*p;,方法2:for(i=0;i10;+i)cout*(a+i);,方法1:for(i=0;i10;+i)cout ai;,方法4:for(p=a,i=0;i10;+i)cout*(p+i);,方法5:for(p=a,i=0;i10;+i)cout pi;,下列程序段 有无问题?for(i=0;i

8、10;+i)cout*a;+a;,指针和数组的区别,虽然通过指针可以访问数组,但两者本质是不同的。在定义数组时为数组的各个元素分配了全部的存储区,而在定义指针时,仅仅分配四个字节的存储区存放指针地址。只有把一个数组名付给了对应的指针后,指针才能当作数组使用如有:int array5,*intp;,当执行了 intp=array后,第7章 间接访问指针,指针的概念指针运算与数组动态内存分配字符串再讨论指针作为函数参数和返回值指针数组与多级指针指向多维数组的指针指向函数的指针,动态分配,在C+语言中,每个程序需要用到几个变量,在写程序前就应该知道。每个数组有几个元素也必须在写程序时就决定。有时我们

9、并不知道我们需要多大的数组元素直到程序开始运行。因此希望能在程序中根据某一个当前运行值来决定数组的大小。如设计一个打印魔阵的程序,我们希望先输入魔阵的阶数,然后根据阶数定义一个矩阵,动态分配方法,这些问题的解决方案就是内存的动态分配。我们定义一个指针,并让它指向一个合适的内存。如:int*scores;scores=内存的起始地址;,动态内存分配与回收,中由new 和 delete两个运算符替代-运算符new用于进行内存分配:申请动态变量:p=new type;申请动态数组:p=new typesize;申请动态变量并初始化:p=new type(初值);-运算符delete 释放 new分配

10、的内存:释放动态变量:delete p;释放动态数组:delete p;,动态内存分配与回收,/为简单变量动态分配内存,并作初始化int main()int*p;p=new int(99);/动态分配内存,并将99作为初始化值赋给它 cout*p;delete p;return 0;,动态内存分配与回收,/动态字符串的使用int main()int*p;char*q;p=new int(5);q=new char10;strcpy(q,abcde);cout*p endl;cout q endl;delete p;delete q;return 0;,输出结果:5abcde,动态分配的检查,n

11、ew操作的结果是申请到的空间的地址当系统空间用完时,new操作可能失败new操作失败时,返回空指针,动态内存分配与回收,/动态分配检查int main()int*p;p=new int;if(!p)cout allocation failuren;return 1;*p=20;cout*p;delete p;return 0;,assert宏,assert()宏在标准头文件cassert中 assert()有一个参数,表示断言为真的表达式,预处理器产生测试该断言的代码。如果断言不是真,则在发出一个错误消息后程序会终止。,#include#include/包含assert宏的头文件using n

12、amespace std;int main()int*p;p=new int;assert(p!=0);/p等于0,则退出程序*p=20;cout*p;delete p;return 0;,内存分配的进一步介绍,静态分配:对全局变量和静态变量,编译器为它们分配空间,这些空间在整个程序运行期间都存在自动分配:函数内的局部变量空间是分配在系统的栈工作区。当函数被调用时,空间被分配;当函数执行结束后,空间被释放动态分配:在程序执行过程中需要新的存储空间时,可用动态分配的方法向系统申请新的空间,当不再使用时用显式的方法还给系统。这部分空间是从被称为堆的内存区域分配。,内存泄漏,动态变量是通过指针间接访

13、问的。如果该指针被修改,这个区域就被丢失了。堆管理器认为你在继续使用它们,但你不知道它们在哪里,这称为内存泄露。为了避免出现孤立的区域,应该明白地告诉堆管理器这些区域不再使用。可以采用delete操作,它释放由new申请的内存。当释放了内存区域,堆管理器重新收回这些区域,而指针仍然指向堆区域,但不能再使用指针指向的这些区域。要确保在程序中同一个区域释放一次。释放内存对一些程序不重要,但对有些程序很重要。如果你的程序要运行很长时间,而且存在内存泄漏,这样程序会耗尽所有内存,直至崩溃。,动态空间分配示例,输入一批数据,计算它们的和。数据个数在设计程序时尚无法确定。存储一批数据应该用数组,但C+语言

14、的数组大小必须是固定的。该问题有两个解决方案:开设一个足够大的数组,每次运行时只使用一部分。缺点:浪费空间用动态内存分配根据输入的数据量申请一个动态数组,#include using namespace std;int main()int*p,i,n,sum=0;cout n;if(!(p=new int n)exit(1);for(i=0;i pi;for(i=0;in;+i)sum+=pi;delete p;cout Number of elements:n endl;cout Sum of the elements:sum endl;return 0;,可改为:p=new int n;a

15、ssert(p!=NULL);,第7章 间接访问指针,指针的概念指针运算与数组动态内存分配字符串再讨论指针作为函数参数和返回值指针数组与多级指针指向多维数组的指针指向函数的指针,字符串再讨论,字符串的另一种表示是定义一个指向字符的指针。然后直接将一个字符串常量或字符串变量赋给它 如 char*String,ss=“abcdef”;String=“abcde”;String=ss;,String=“abcde”;的执行结果,字符串常量存储在一个称为数据段的内存区域里 将存储字符串”abcde”的内存的首地址赋给指针变量String。,String=ss的执行过程,将字符数组ss的起始地址存入St

16、ring,String=new char5;strcpy(String,“aaa”),动态变量存储在堆工作区 将存储字符串”aaa”的内存的首地址赋给指针变量String。,用指针表示的字符串的操作,可以直接作为字符串操作函数的参数。但必须注意,如果该指针指向的是一个字符串常量时,则使用是受限的。如不能作为strcpy的第一个参数由于在C+中,数组名被解释成指向数组首地址的指针。因此,字符串是用一个指针变量表示,我们可以把此指针变量解释成数组的首地址,通过下标访问字符串中的字符。如string3的值是d。,用指针处理串,目的:编写一个记录串中单词的个数的函数。关键技术:要传递一个字符串给函数,

17、字符串作为函数的参数,字符串作为函数的参数和数组名作为参数传递一样,可以有两种方法作为字符数组传递作为指向字符的指针传递两种传递方式的本质是一样的,都是传递了字符串的首地址字符串作为字符数组传递时不需要指定长度。因为字符串操作的结束是依据0,#include Using namespace std;int word_cnt(const char*s)int cnt=0;while(*s!=0)while(isspace(*s)+s;/跳过空白字符if(*s!=0)+cnt;/找到一个单词 while(!isspace(*s),统计字符串中单词数的函数,第7章 间接访问指针,指针的概念指针运算与

18、数组动态内存分配字符串再讨论指针作为函数参数和返回值指针数组与多级指针指向多维数组的指针指向函数的指针,指针作为函数参数和返回值,指针作为函数参数数组名作为函数参数返回指针的函数引用和引用传递返回引用的函数,指针作为函数参数,例:编一函数,交换二个参数值。,void swap(int a,int b)int c;c=a;a=b;b=c;,希望通过调用swap(x,y)交换变量x和y的值,新手可能会编出如下的函数:,因为C+采用的是值传递机制,函数中a、b值的交换不会影响实际参数x和y的值,void swap(int*a,int*b)int c;c=*a;*a=*b;*b=c;,交换x和y的值,

19、可以调用swap(&x,&y),用指针作为参数可以在函数中修改主调程序的变量值,即实现变量传递。必须小心使用!,正确的方法,能解一元二次方程的函数,目前为止我们了解到的函数只能有一个返回值,由return 语句返回。一个一元二次方程有二个解,如何让此函数返回二个解。答案是采用指针作为函数的参数。由调用程序准备好存放两个根的变量,将变量地址传给函数。在函数中将两个根的值分别放入这两个地址,函数原型,函数原型可设计为:void SolveQuadratic(double a,double b,double c,double*px1,double*px2)函数的调用 SolveQuadratic(1

20、.3,4.5,2.1,&x1,&x2)SolveQuadratic(a,b,c,&x1,&x2)函数的参数有两类:输入参数和输出参数。一般,输入参数用值传递,输出参数用指针传递。在参数表中,输入参数放在前面,输出参数放在后面。,原型的改进,并不是每个一元二次方程都有两个不同根,有的可能有两个等根,有的可能没有根。函数的调用者如何知道x1和x2中包含的是否是有效的解?解决方案:让函数返回一个整型数。该整型数表示解的情况,完整的函数,int SolveQuadratic(double a,double b,double c,double*px1,double*px2)double disc,sqr

21、tDisc;if(a=0)return 3;/不是一元二次方程 disc=b*b-4*a*c;if(disc 0)return 2;/无根 if(disc=0)*px1=-b/(2*a);return 1;/等根/两个不等根 sqrtDisc=sqrt(disc);*px1=(-b+sqrtDisc)/(2*a);*px2=(-b-sqrtDisc)/(2*a);return 0;,函数的调用,int main()double a,b,c,x1,x2;int result;cout a b c;result=SolveQuadratic(a,b,c,指针作为函数参数和返回值,指针作为函数参数数

22、组名作为函数参数返回指针的函数引用和引用传递返回引用的函数,数组传递的进一步讨论,数组传递的本质是地址传递,因此形参和实参可以使用数组名,也可以使用指针。数组传递是函数原型可写为:type fun(type a,int size);也可写为 type fun(type*p,int size);但在函数内部,a和p都能当作数组使用调用时,对这两种形式都可用数组名或指针作为实参建议:如果传递的是数组,用第一种形式;如果传递的是普通的指针,用第二种形式,#include using namespace std;void f(int arr,int k)cout sizeof(arr)sizeof(k

23、)endl;void main()int a10=1,2,3,4,5,6,7,8,9,0;cout sizeof(a)endl;f(a,10);,输出:,C+将数组名作为参数传递处理成指针的传递,即在main中,a是数组,占用了40个字节。而在函数f中,arr是一个指针,数组传递的灵活性,void sort(int p,int n).main()int a100;.sort(a,100);/排序整个数组 sort(a,50);/排序数组的前50个元素 sort(a+50,50);/排序数组的后50个元素.,实例,设计一函数用分治法在一个整数数组中找出最大和最小值具体方法是:如果数组只有一个元素

24、,则最大最小都是他。如果数组中只有两个元素,则大的一个就是最大数,小的就是最小数。这种情况不需要递归。否则,将数组分成两半,递归找出前一半的最大最小值和后一半的最大最小值。取两个最大值中的较大者作为最大值,两个最小值中的较小值作为最小值。,设计考虑,函数的参数是要查找的数组,传递一个数组要两个参数:数组名和数组规模函数返回的是数组中的最大值和最小值,将它们作为指针传递的参数查找数组的前一半就是递归调用本函数,传给他的参数是当前的数组名,数组的规模是原来的一半查找数组的后一半也是递归调用本函数,传给它的参数是数组后一半的起始地址,规模也是原来的一半,伪代码,void minmax(int a,i

25、nt n,int*min_ptr,int*max_ptr)switch(n)case 1:最大最小都是a0;case 2:大的得放入*max_ptr,小的放入*min_ptr;Default:对数组a的前一半和后一般分别调用minmax;取两个最大值中的较大者作为最大值;取两个最小值中的较小值作为最小值,void minmax(int a,int n,int*min_ptr,int*max_ptr)int min1,max1,min2,max2;switch(n)case 1:*min_ptr=*max_ptr=a0;return;case 2:if(a0 a1)*min_ptr=a0;*ma

26、x_ptr=a1;else*min_ptr=a1;*max_ptr=a0;return;default:minmax(a,n/2,指针作为函数参数和返回值,指针作为函数参数数组名作为函数参数返回指针的函数引用和引用传递返回引用的函数,返回指针的函数,函数的返回值可以是一个指针 返回指针的函数原型:类型*函数名(形式参数表);当函数的返回值是指针时,返回地址对应的变量不能是局部变量。,实例,设计一个函数从一个字符串中取出一个子串。原型设计:从哪一个字符串中取子串、起点和终点返回值:字符串可以用一个指向字符的指针表示,所以函数的执行结果是一个字符串,表示一个字符串可以用一个指向字符的指针 返回值指

27、针指向的空间必须在返回后还存在。这可以用动态字符数组,char*subString(char*s,int start,int end)int len=strlen(s);if(start=len|end=len|start end)cout 起始或终止位置错 endl;return NULL;char*sub=new charend-start+2;strncpy(sub,s+start,end-start+1);subend-start+1=0;return sub;,指针作为函数参数和返回值,指针作为函数参数数组名作为函数参数返回指针的函数引用和引用传递返回引用的函数,引用传递,引用传递是

28、地址传递的另一种更简单明了的实现方法,引用的概念函数中的引用,C+中的引用,引用的定义:给一个变量取一个别名,使一个内存单元可以通过不同的变量名来访问。例:int i;int j是i的别名,i与j是同一个内存单元。C+引入引用的主要目的是将引用作为函数的参数。,引用传递,引用传递是地址传递的另一种更简单明了的实现方法,引用的概念函数中的引用,引用参数,C+引入引用的主要目的是将引用作为函数的参数。,指针参数void swap(int*m,int*n)int temp;temp=*m;*m=*n;*n=temp;调用:swap(&x,&y),引用参数void swap(int 调用:swap(x

29、,y),注意:实参必须是变量,而不能是一个表达式,调用swap(x,y)时,相当于发生了变量定义 int&m=x int&n=y即,形式参数m和实际参数x共享一块空间,形式参数n和实际参数y共享一块空间。在swap函数中交换了m和n的值,就相当于交换了x和y的值。,指针作为函数参数和返回值,指针作为函数参数数组名作为函数参数返回指针的函数引用和引用传递返回引用的函数,返回引用的函数的主要用途,将函数用于赋值运算符的左边,即作为左值。int a=1,3,5,7,9;int/函数是aj的一个引用,第7章 间接访问指针,指针的概念指针运算与数组动态内存分配字符串再讨论指针作为函数参数和返回值指针数组

30、与多级指针指向多维数组的指针指向函数的指针,指针数组与多级指针,指针数组Main函数的参数多级指针,指针数组,地址本身也是数据,他们也可以像其他数据一样组织成一个数组 一个数组,如果他的元素均为指针,则称为指针数组 一维指针数组的定义形式:类型名*数组名数组长度;例如,char*String10;定义了一个名为String的指针数组,该数组有10个元素,数组的每个成员是一个指向字符的指针,指针数组的应用,字符串可以用一个指向字符的指针表示,一组字符串可以用一个指向字符的指针数组来表示例:写一个函数用二分法查找某一个城市在城市表中是否出现。用递归实现关键问题:城市表的存储:用指向字符的指针数组查

31、找时的比较:用字符串比较函数,/该函数用二分查找在cityTable中查找cityName是否出现/lh和rh表示查找范围,返回出现的位置Int binarySearch(char*cityTable,int lh,int rh,char*cityName)int mid,result;if(lh 0)return binarySearch(cityTable,lh,mid-1,cityName);else return binarySearch(cityTable,mid+1,rh,cityName);return-1;/没有找到,函数的应用,#include using namespace

32、 std;int binarySearch(char*cityTable,int lh,int rh,char*cityName);int main()char*string10=aaa,bbb,ccc,ddd,eee,fff,ggg,hhh,iii,jjj;char tmp10;while(cin tmp)cout binarySearch(string,0,9,tmp)endl;return 0;,指针数组与多级指针,指针数组Main函数的参数多级指针,main函数的形参,如需要实现:copy a b之类的功能,可以用带有参数的main函数来实现 main函数有二个形式参数:int arg

33、c,char*argv argc 参数的数目(包括命令名本身)argv 指向每个参数的指针,是一个指向字符串的指针数组,把参数传递给main(),#include int main(int argc,char*argv)int i;cout argc=“argc endl;for(i=0;iargc;+i)cout argv“i“=“argvi endl;return 0;,假设生成的执行文件myprogram.exe,把参数传递给main()续,假设生成的执行文件myprogram.exe在命令行输入:myprogram 输出结果:argc=1 argv0=myprogram在命令行输入:m

34、yprogram try this 输出结果:argc=3 argv0=myprogramargv1=try argv2=this,main函数参数实例,编写一个求任意n个正整数的平均数的程序如果该程序对应的可执行文件名为aveg,则可以在命令行中输入 aveg 10 30 50 20 40 表示求10、30、50、20和40的平均值,对应的输出为30。,设计考虑,将这些数据作为命令行的参数从argc得到数据的个数从argv得到每一个数值,但注意数值是以字符串表示,要进行计算,必须把它转换成真正的数值由于每个数据都要转换,而且这个工作很独立,所以将它设计成一个函数,字符串形式的数字转换到真正的

35、数值,int ConvertStringToInt(char*s)int num=0;while(*s)num=num*10+*s-0;+s;return num;,计算程序,int main(int argc,char*argv)int sum=0;for(int i=1;i argc;+i)sum+=ConvertStringToInt(argvi);cout sum/(argc-1)endl;return 0;,指针数组与多级指针,指针数组Main函数的参数多级指针,多级指针,指针指向的内容还是一个指针,称为多级指针 如有定义:char*string10;string是一个数组,数组元素

36、可以通过指针来访问。如果p是指向数组string的某一个元素,那么p指向的内容是一个指向字符的指针,因此p就是一个多级指针。string也是一个多级指针,不过是一个常指针,多级指针的定义,两级指针:类型名*变量名;三级指针:类型名*变量名;如:int*q;表示q指向的内容是一个指向整型的指针。可以这样使用:int x=15,*p=表示s指向的内容是一个指向字符的指针,多级指针的应用,可以用指向指针的指针访问指针数组的元素。如#include using namespace std;int main()char*city=aaa,bbb,ccc,ddd,eee;char*p;for(p=city

37、;pcity+5;+p)cout*p endl;return 0;,输出结果:aaabbbcccdddeee,第7章 间接访问指针,指针的概念指针运算与数组动态内存分配字符串再讨论指针作为函数参数和返回值指针数组与多级指针指向多维数组的指针指向函数的指针,二维数组与指针,int a34;等价于定义了3个变量,指向一维数组的指针,a 是一个指针数组,它的每个元素是一个整型指针,指向每一行的第一个元素。a是一个指向一维数组的指针,指向a 的第一个元素。对a加1,事实上是跳到下一行 指向一维数组的指针可以这样定义:类型名(*指针变量名)一维数组的元素个数;注意:圆括号不能省略,如果省略了圆括号就变成

38、了指针数组,等价于aij的表达式,int a35;,用指向数组的指针输出二维数组a,int(*p)4,*q;for(p=a;p a+3;+p)/每一行 for(q=*p;q*p+4;+q)/每一列 cout*q t;cout endl;,注意:如果输出a和a0,这两个值是相同的。但是,这两个值的含义是不同的,前者是第0行的首地址,它的类型是指向由四个元素组成的一位数组的首地址,后者是第0行第一个元素的地址,它的类型是整型指针,动态的二维数组,方法一:用一维动态数组将它按行序转换成一维数组,用动态的一维数组存储。如一个3行4列的矩阵a可以存储为12个元素的一维数组访问i行j列的元素转换成访问一维

39、数组的第4*i+j个元素方法二:用指向指针的指针,可以用aij访问用指向指针的指针指向一个一维的指针数组指针数组中的每个元素指向矩阵的每一行的第一个元素,int main()int*a,i,j,k=0;a=new int*3;for(i=0;i 3;+i)ai=new int4;for(i=0;i 3;+i)for(j=0;j 4;+j)aij=k+;for(i=0;i 3;+i)cout endl;for(j=0;j 4;+j)cout aij t;for(i=0;i 3;+i)delete ai;delete a;return 0;,第7章 间接访问指针,指针的概念指针运算与数组动态内存分

40、配字符串再讨论指针作为函数参数和返回值指针数组与多级指针指向多维数组的指针指向函数的指针,函数的指针和指向函数的指针变量,定义:返回类型(*指针变量名)();使用:赋值 eg.int isdigit(int n,int k);.int(*p)(int,int);p=isdigit;引用:a=isdigit(n,k);a=(*p)(n,k);或 a=p(n,k),函数的指针:指向函数代码的起始地址,函数的指针的用途,菜单选择的实现作为函数的参数,函数指针的应用,用函数指针的数组实现菜单选择例如,在一个工资管理系统中有如下功能:1。添加员工;2。删除员工;3。修改员工信息;4。打印工资单;5。打印

41、汇总表;6。退出。在设计中,一般把每个功能设计成一个函数。如添加员工的函数为add,删除员工的函数为delete,修改员工信息的函数为modify,打印工资单的函数为printSalary,打印汇总表函数为printReport。主程序是一个循环,显示所有功能和它的编号,请用户输入编号,根据编号调用相应的函数。,int main()int select;while(1)cout select;switch(select)case 0:return 0;case 1:add();break;case 2:erase();break;case 3:modify();break;case 4:pri

42、ntSalary();break;case 5:printReport();break;default:cout input errorn;,利用指向函数的指针,int main()int select;void(*func6)()=NULL,add,erase,modify,printSalary,printReport;while(1)cout select;if(select=0)return 0;if(select 5)cout input errorn;else funcselect();,函数指针的应用,把函数指针作为函数的参数例:设计一个通用的快速排序函数,可以排序任何类型的数据

43、 关键问题如何表示要排序的数据:将快速排序设计成一个函数模板,将待排序的数据类型设计成模板参数 不同类型的数据有不同的比较方式:向排序函数传递一个比较函数来解决。,template void quicksort(T data,int low,int high,int(*comp)(T,T)int mid;if(low=high)return;mid=divide(data,low,high,comp);quicksort(data,low,mid-1,comp);quicksort(data,mid+1,high,comp);,template int divide(T data,int lo

44、w,int high,int(*comp)(T,T)T k=datalow;do while(low 0)-high;if(low high)datalow=datahigh;+low;while(low high,通用快速排序的应用,如果需要排序一组字符串,待排序的一组字符串保存在数组a中。a的定义如下:char*a=aaa,nnn,rrr,fff,sss,ggg,ddd;调用 quicksort(a,0,6,strcmp);,通用快速排序的应用,如果要排序一组整型数,则需要定义一个比较函数,如下所示:int intcmp(int a,int b)if(a=b)return 0;if(a b)return-1;else return 1;如果整型数组a定义如下:int a=7,9,4,3,8,1,2,5,6,0;调用quicksort(b,0,9,intcmp);,总结,本章介绍了指针的概念,指针变量的定义、运算采用指针,可以使数组有多种访问方式将指针作为形式参数可以使一个函数与其调用函数共享数据 动态分配内存,

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

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号