程序设计郑莉实用教案

上传人:辰*** 文档编号:77036697 上传时间:2022-04-19 格式:PPTX 页数:99 大小:520.91KB
返回 下载 相关 举报
程序设计郑莉实用教案_第1页
第1页 / 共99页
程序设计郑莉实用教案_第2页
第2页 / 共99页
程序设计郑莉实用教案_第3页
第3页 / 共99页
点击查看更多>>
资源描述
1本章(bn zhn)主要内容 数组 指针(zhzhn) 指针(zhzhn)与数组 指针(zhzhn)与函数 动态存储分配 字符串第1页/共98页第一页,共99页。2数组的概念(ginin)数组是具有一定顺序关系的若干相同类型变量的集合体,组成数组的变量称为该数组的元素。因此当需要多个同类型变量时就要考虑(kol)定义数组。 数 组第2页/共98页第二页,共99页。3数组的说明(shumng)与使用 数组的声明 一般形式:类型说明符 标识符 常量表达式1 ; 例如: int a10; 表示(biosh) a 为整型数组,有10个元素:a0.a9 数 组l引用l必须先声明,后使用(shyng)。l只能逐个引用数组元素,而不能一次引用整个数组例如:a0=a5+a7-a2*3数组的名称 数组元素的类型 数组维数,每一维的大小第3页/共98页第三页,共99页。4数组的说明(shumng)与使用 数 组 数组的使用 使用数组时,只能(zh nn)分别对数组的各个元素进行操作。数组的元素是由下标来区分的,对于一个已经声明过的数组,其元素的使用形式为:数组名 下标表达式1 下标表达式2 使用数组注意(zh y):(1)数组元素的下标表达式可以是任意合法的算术表达式,其结果必须为整型数。(2)数组元素的下标值不得超过声明时所规定的上下界,否则运行时数组越界错误。第4页/共98页第四页,共99页。5 例:给出下面程序(chngx)的输出结果。 #include int count5=1,2; void main() int i;char c =hello!;for (i=0;i=4;i+) coutcountiendl;coutcendl;coutsizeof(c)endl;coutcountendl;coutsizeof(count) endl;coutsizeof(count)/sizeof(int)endl;运行结果为:1 /count02/count10/count20/count30/count5hello!/输出(shch)字符串c7/字符串c长度为70 x00408040 /数组count首地址20 /数组count占总字节数5 /数组count元素个数第5页/共98页第五页,共99页。6一维数组的存储(cn ch)顺序数组元素在内存中顺次存放,它们的地址是连续的。例如(lr):具有10个元素的数组 a,在内存中的存放次序如下:数组名字是数组首元素(yun s)的内存地址。数组名是一个常量,不能被赋值。a0 a1a2 a3 a4a5 a6 a7a8 a9a 数 组第6页/共98页第六页,共99页。7一维数组的初始化可以在编译阶段( jidun)使数组得到初值:在声明数组时对数组元素赋以初值。可以只给一部分元素赋初值。在对全部数组元素赋初值时,可以不指定数组长度。 数 组例如例如(lr):static int a10=0,1,2,3,4,5,6,7,8,9;例如例如(lr):static int a10=0,1,2,3,4;例如:例如:static int a=1,2,3,4,5第7页/共98页第七页,共99页。8二维数组的声明(shngmng)及引用数据类型 标识符常量表达式1常量表达式2 ;例: int a53; 表示a为整型二维数组,其中(qzhng)第一维有5个下标(04),第二维有3个下标(02),数组的元素个数为15,可以用于存放5行3列的整型数据表格。 数 组第8页/共98页第八页,共99页。l存储顺序(shnx)l按行存放,上例中数组a的存储顺序(shnx)为: 二维数组的声明 类型(lixng)说明符 数组名常量表达式常量表达式 例如:float a34;a00 a01 a02 a03 a10 a11 a12 a13 a20 a21 a22 a23a0a00 a01 a02 a03a1a10 a11 a12 a13a2a20 a21 a22 a23a可以理解为:l引用(ynyng)l例如:b12=a23/2二维数组的声明及引用 数 组第9页/共98页第九页,共99页。 分行给二维数组赋初值 例如:static int a34=1,2,3,4,5,6,7,8,9,10,11,12; 将所有数据(shj)写在一个 内,按顺序赋值 例如:static int a34=1,2,3,4,5,6,7,8,9,10,11,12; 可以对部分元素赋初值 例如:static int a34=1,0,6,0,0,11;二维数组的初始化 数 组第10页/共98页第十页,共99页。11数组作为(zuwi)函数参数 数组元素作实参,与单个变量一样(yyng)。 数组名作参数,形、实参数都应是数组名,类型要一样(yyng),传送的是数组首地址。对形参数组的改变会直接影响到实参数组。 数 组第11页/共98页第十一页,共99页。12例6-2 使用(shyng)数组名作为函数参数例:主函数中初始化一个(y )矩阵并将每个元素都输出,然后调用子函数,分别计算每一行的元素之和,将和直接存放在每行的第一个(y )元素中,返回主函数之后输出各行元素的和。 数 组第12页/共98页第十二页,共99页。#include void RowSum(int A4, int nrow)int sum;for (int i = 0; i nrow; i+)sum = 0;for(int j = 0; j 4; j+)sum += Aij;cout Sum of row i is sum endl; 第13页/共98页第十三页,共99页。void main(void)int Table34 = 1,2,3,4,2,3,4,5,3,4,5,6;for (int i = 0; i 3; i+)for (int j = 0; j 4; j+)cout Tableij ;cout endl;RowSum(Table,3);第14页/共98页第十四页,共99页。运行(ynxng)结果:1 2 3 42 3 4 53 4 5 6Sum of row 0 is 10Sum of row 1 is 14Sum of row 2 is 18第15页/共98页第十五页,共99页。16对象(duxing)数组 声明: 类名 数组名元素个数; 访问(fngwn)方法: 通过下标访问(fngwn) 数组名下标.成员名 数 组第16页/共98页第十六页,共99页。17对象(duxing)数组初始化 数组中每一个元素对象被创建时,系统都会调用(dioyng)类构造函数初始化该对象。 通过初始化列表赋值。 例:Point A2=Point(1,2),Point(3,4); 如果没有为数组元素指定显式初始值,数组元素便使用缺省值初始化(调用(dioyng)缺省构造函数)。 数 组第17页/共98页第十七页,共99页。18数组元素(yun s)所属类的构造函数 不声明构造函数,则采用缺省构造函数。 各元素对象的初值要求为相同的值时,可以声明具有(jyu)缺省形参值的构造函数。 各元素对象的初值要求为不同的值时,需要声明带形参(无缺省值)的构造函数。 当数组中每一个对象被删除时,系统都要调用一次析构函数。 数 组第18页/共98页第十八页,共99页。19例6-3 对象数组应用(yngyng)举例/Point.h#ifndef _POINT_H#define _POINT_Hclass Point public: Point(); Point(int xx,int yy); Point(); void Move(int newX,int newY); int GetX() return x; int GetY() return y;static void showCount(); private: int x,y;#endif 数 组第19页/共98页第十九页,共99页。/Point.cpp#include#include “Point.h“using namespace std;Point:Point () x=y=0; coutDefault Constructor called.endl;Point:Point (int x,int y):x(x),y(y)cout Constructor called.endl;第20页/共98页第二十页,共99页。Point : Point() coutDestructor called.endl;void Point :Move(int newX,int newY)cout“Moving the point to (“newX“,”newYendl; x=newX; y=newY;第21页/共98页第二十一页,共99页。/6_3.cpp#include “Point.h”#includeusing namespace std;int main() coutEntering main.endl; Point a2; for(int i=0;i2;i+) ai.Move(i+10,i+20); coutExiting main.endl; return 0;第22页/共98页第二十二页,共99页。运行(ynxng)结果:Entering main.Default Constructor called.Default Constructor called.Moving the point to (10,20)Moving the point to (11,21)Exiting main.Destructor called.Destructor called.第23页/共98页第二十三页,共99页。24关于(guny)内存地址 内存(ni cn)空间的访问方式 通过变量名访问 通过地址访问 地址运算符:& 例: int var; 则 &var 表示变量var在内存(ni cn)中的起始地址 指 针第24页/共98页第二十四页,共99页。25声明例:static int i; static int *i_pointer=&i; 指向(zh xin)整型变量的指针指针变量(binling)的概念概念指针:另一个变量(binling)的地址, 用于间接访问变量(binling)指针变量(binling): 用于存放地址的变量(binling)20003i_pointer*i_pointeri2000内存用户数据区变量 i变量 j变量 i_pointer362000200020043010引用例1: i=3;例2: *i_pointer=3; 指 针第25页/共98页第二十五页,共99页。26与地址相关(xinggun)的运算 “*”和“&” *:指针运算符,表示指针所指向的变量的值 &:取地址运算符,用来得到一个对象的地址 注意: (1)当“*”出现在执行语句中或声明(shngmng)语句的初值表达式中表示访问指针所指对象的内容。 例如:cout*p; /p所指对象的内容 (2)当“&”在给变量赋值时出现在等号右边或执行语句中表示取对象地址。 例如:int a,b; int *pa, *pb=&b; pa=&a; 指 针第26页/共98页第二十六页,共99页。27与地址(dzh)相关的运算 “*”和“&” 如果(rgu)已经执行了 int a,b; int *point_1,*point_2; point_1=&a; point_2=&b; (1)&*point_1的含义? (2)*&a的含义? 指 针&a&bpoint_1point_2ab(1)先进行*point_1运算,它就是变量a,再执行&运算。因此,&*point_1与&a相同。 coutpoint_1; cout&*point_1; cout&a;其结果一致,都是变量a的地址(2)*&a与*point_1的作用(zuyng)是一样的,它们等价于变量a。即*&a与a等价第27页/共98页第二十七页,共99页。28指针(zhzhn)变量的初始化l语法(yf)形式l 存储类型 数据类型 *指针名初始地址;l 例: int *pa=&a; 指 针注:存储类型是指数据在内存中存储的方式(fngsh)。分为两类:静态存储类和动态存储类。具体包含四种:自动的(auto),静态的(static),寄存器的(register),外部的(extern)。自动的”auto”可以省略。注意事项:(1)用变量地址作为初值时,该变量必须在指针初始化之前已说明过,且变量类型应与指针类型一致一致。(2)可以用一个已赋初值的指针去初始化另一去初始化另一 个指针变量个指针变量。第28页/共98页第二十八页,共99页。29指针(zhzhn)(zhzhn)变量的赋值运算指针名=地址“地址”中存放的数据类型与指针类型必须相符。向指针变量赋的值必须是地址常量或变量,不能是普通整数。但可以赋值为整数0,表示空指针。指针的类型是它所指向变量的类型,而不是指针本身数据值的类型,任何(rnh)一个指针本身的数据值都是unsigned long int型。允许声明指向 void 类型的指针。该指针可以被赋予任何(rnh)类型对象的地址。例: void *general; 指 针第29页/共98页第二十九页,共99页。30例6-5 指针(zhzhn)的声明、赋值与使用#includeusing namespace std;void main() int i;int *ptr=&i;i=10;couti=iendl; cout“*ptr=*ptrendl; 指 针/取取i的地址的地址(dzh)赋给赋给ptr/输出输出(shch)int型数型数的值的值/输出输出int型指针所指地址的内容型指针所指地址的内容第30页/共98页第三十页,共99页。程序运行的结果( ji gu)是:i=10*ptr=10第31页/共98页第三十一页,共99页。32几种特殊的指针(zhzhn)类型 指 针(1)可以声明指向常量的指针,此时(c sh)不能通过指针来改变所指对象的值,但指针本身可以改变,可以指向另外的对象。例:P164例:int n1=3; int const n2=5; const int *pn= &n1; pn=&n2; *pn=6; /正确正确(zhngqu)/错误错误第32页/共98页第三十二页,共99页。33 指 针(2)可以(ky)声明指针类型的常量,这时指针本身的值不能被改变。例:P164例:int n1=3;int const n2=5;int *const pn= &n1; pn=&n2; /错误*pn=6; /正确第33页/共98页第三十三页,共99页。34例6-6 void类型指针(zhzhn)的使用void main() /void vodObject; /错,不能声明void类型的变量void *pv; /对,可以声明void类型的指针(zhzhn)int i=5;pv = &i; int *pint = static_cast(pv); cout“*pint=“*pintendl; 指 针/void类型类型(lixng)指针指向整型变指针指向整型变量量/ void指针赋值给指针赋值给int指针需要类型强制指针需要类型强制(qingzh)转换转换:(3)一般情况下,指针的值只能赋给相同类型的指针。但是有一种特殊的void类型指类型指针针,可以存储任何类型的对象地址第34页/共98页第三十四页,共99页。35指针(zhzhn)运算 指针与整数的加减运算 指针 p 加上或减去 n ,其意义是指针当前指向位置(wi zhi)的前方或后方第 n 个数据的地址。 这种运算的结果值取决于指针指向的数据类型。 指 针第35页/共98页第三十五页,共99页。36指针变量的算术(sunsh)运算 指针加一,减一运算 指向下一个或前一个数据(shj)。 例如:y=*px+ /*相当于 y=*(px+) */ /*相当于y=*px; px+*/ 指 针(后置(hu zh)+运算符优先级高于*)详细分析:详细分析:* *px+px+相当于相当于* *(px+)(px+),但(,但(px+px+)的值为)的值为px,px,因而因而* *与与pxpx结合成结合成* *px,px,继续运算将继续运算将* *pxpx的值赋值给的值赋值给y,y,表达式运算结束后,再为表达式运算结束后,再为pxpx值增值增1 1。 第36页/共98页第三十六页,共99页。papa-2pa-1pa+1pa+2pa+3*(pa-2)*pa*(pa+1)*(pa+2)*(pa+3)*(pa-1)short *pa第37页/共98页第三十七页,共99页。pb-1pbpb+1pb+2*(pb-1)*pb*(pb+1)*(pb+2)long *pb第38页/共98页第三十八页,共99页。39关系运算指向相同类型数据(shj)的指针之间可以进行各种关系运算。指向不同数据(shj)类型的指针,以及指针与一般整数变量之间的关系运算是无意义的。指针可以和零之间进行等于或不等于的关系运算。例如:p=0或p!=0赋值运算向指针变量赋的值必须是地址常量或变量,不能是普通整数。但可以赋值为整数0,表示空指针。 指 针第39页/共98页第三十九页,共99页。40用指针处理(chl)数组元素 声明与赋值 例:int a6=10,20,30,40,50,60, *pa; pa=&a0; 或 pa=a; 当指针变量(binling)指向该数组后可以通过指针引用数组元素 指 针102030405060int a6数组a各元素a0a1a2a3a4a5数组a的地址aa+1a+2a+3a+4a+51000pa第40页/共98页第四十页,共99页。41由此可见如下(rxi)的等价关系成立: paa &a0 /表示数组元素(yun s)的首地址 pa+i a+i &ai /表示第i+1个数组元素(yun s)的地址 *(pa+i) *(a+i) ai /表示第i+1数组元素(yun s) 指 针访问数组元素的三种方式(fngsh):(1)下标方式(fngsh) 形式: 数组名下标(2)地址方式(fngsh) 形式: *(地址)(3)指针方式(fngsh) 形式: *指针变量注意:(1)pa与a的区别:两者同样是表示数组a的地址,但本质不同,pa是变量变量,而a是常量常量.所以对pa进行pa+,pa等赋值运算,改变pa的值;但不能对a进行a+,a-等赋值运算.第41页/共98页第四十一页,共99页。42注意:(2)*pa+与(*pa)+区别(qbi)*pa+的+运算符作用于指针变量,即取指针所指对象的值后,再对指针进行+运算,改变的是指针变量的值;而 (*pa)+的+运算符作用于指针变量所指对象,即取指针所指对象的值,加1后再赋值给对象 指 针*pa+的+运算1000pa10201004pa1020*pa+(*pa)+的+运算1000pa10201000pa1120(*pa)+第42页/共98页第四十二页,共99页。43例6-7设有一个int型数组a,有10个元素。用三种方法输出(shch)各元素:使用数组名和下标使用数组名和指针运算使用指针变量 指 针第43页/共98页第四十三页,共99页。main() int a10; int i; for(i=0; iai; coutendl; for(i=0; i10; i+) coutai;使用(shyng)数组名和下标第44页/共98页第四十四页,共99页。main() int a10; int i; for(i=0; iai; coutendl; for(i=0; i10; i+) cout*(a+i);使用(shyng)数组名指针运算第45页/共98页第四十五页,共99页。使用(shyng)指针变量main() int a10; int *p , i; for(i=0; iai; coutendl; for(p=a; p(a+10); p+) cout*p;第46页/共98页第四十六页,共99页。47 数组的每个元素是指针变量(binling),这个数组就是指针数组,指针数组的每个元素都是同一类型的指针 声明一维指针数组的语法形式: 类型名 *数组名下标表达式 例:int *p_i3; 指 针声明(shngmng)了一个int 型指针数组p_i,数组有3个元素,每个元素都是一个指向int型数据的指针.第47页/共98页第四十七页,共99页。48例6-8 利用指针(zhzhn)数组输出单位矩阵#include void main() int line1 =1,0,0; /声明数组,矩阵的第一行int line2 =0,1,0; /声明数组,矩阵的第二行int line3 =0,0,1; /声明数组,矩阵的第三行int *p_line3; /声明整型指针(zhzhn)数组p_line0=line1;/初始化指针(zhzhn)数组元素p_line1=line2;p_line2=line3; 指 针第48页/共98页第四十八页,共99页。/输出单位矩阵 coutMatrix test:endl;for(int i=0;i3;i+)/对指针数组元素循环(xnhun) for(int j=0;j3;j+)/对矩阵每一行循环(xnhun) coutp_lineij ; coutendl;输出输出(shch)(shch)结果为:结果为:Matrix test:Matrix test:1,0,01,0,00,1,00,1,00,0,10,0,1第49页/共98页第四十九页,共99页。50例6-9 二维数组举例(j l)#include void main() int array223=11,12,13,21,22,23; for(int i=0;i2;i+) cout*(array2+i)endl; for(int j=0;j3;j+) cout*(*(array2+i)+j) ; coutendl; 指 针第50页/共98页第五十页,共99页。51 如果以指针作为形参,在调用时实参将值传递给形参,使得指针变量指向同一内存地址。这样在子函数(hnsh)运行过程中,对形参指针所指变量值的改变也同时影响实参指针所指向的变量的值。 指针作为函数(hnsh)的形参有三个作用:P209(了解) 指针(zhzhn)与函数第51页/共98页第五十一页,共99页。52例6.10:读入三个浮点数,将整数部分和小数部分分别输出#include using namespace std;void splitfloat(float x, int *intpart, float *fracpart) /形参intpart、 fracpart是指针(zhzhn) *intpart = static_cast(x);/ 取x的整数部分 *fracpart = x - *intpart; /取x的小数部分 void main(void) int i, n; float x, f; cout Enter three (3) floating point numbers endl; for (i = 0; i x;splitfloat(x,&n,&f); /变量地址做实参cout Integer Part is n Fraction Part is f endl; 指针(zhzhn)与函数第52页/共98页第五十二页,共99页。53运行(ynxng)结果:Enter three (3) floating point numbers 4.7Integer Part is 4 Fraction Part is 0.78.913Integer Part is 8 Fraction Part is 0.913-4.7518Integer Part is -4 Fraction Part is -0.7518第53页/共98页第五十三页,共99页。54除了void类型的函数之外,函数在调用结束后都会有返回值,指针同样可以作为函数的返回值。当一个函数的返回值是指针类型时,这个函数就是指针型函数。通常(tngchng)非指针型函数调用结束后,可以返回一个变量或对象,但这样每次调用只能返回一个数据,而指针型函数在函数结束时把大量的数据从被调函数返回到主调函数中。 指针(zhzhn)与函数指针型函数的一般定义形式:数据类型数据类型 *函数名函数名(参数表参数表)函数体函数体第54页/共98页第五十四页,共99页。55例:#includeint *fun( );void main() int *p;p=fun();while (*p!=-1)cout*p+endl;int *fun() int *h=new int4;h0=1; h1=2; h2=3; h3=-1;return h;第55页/共98页第五十五页,共99页。56 含义: 数据(shj)指针指向数据(shj)存储区,而函数指针指向的是程序代码存储区。实际上函数名就表示函数的代码在内存中的起始地址。指向(zh xin)函数的指针 指针(zhzhn)与函数声明形式声明形式: 数据类型数据类型 (*函数指针名函数指针名)(形参表形参表);注意:注意:函数指针在使用之前也要进行赋值,使指针指向一个已经存在的函数代码的起始地址。一般语法为:函数指针名函数指针名 = 函数名;函数名;P212 例6-11第56页/共98页第五十六页,共99页。57#include using namepsace std;void printStuff(float data_to_ignore) coutThis is the print stuff function.“endl;void printMessage(float list_this_data) coutThe data to be listed is “list_this_dataendl;void printFloat(float data_to_print) coutThe data to be printed is “ data_to_print成员名成员名第60页/共98页第六十页,共99页。61对象指针应用(yngyng)举例注意:(1)对象是包含了数据和函数两种成员,但对象所占据的内存空间只用于存放数据成员。(2)对象指针在使用之前一定要先进行初始化,让它指向一个(y )程序已经声明过的对象,然后再使用。通过对象指针,可以访问到所指对象的公有成员。 对 象 指 针例:例: P213 例例6-12int main()Point a(4,5);Point *pl=&a;coutgetX()endl;couta.getX()x; 每一个非静态成员函数都有一个this指针,当对象调用成员函数时,该成员函数的this指针便指向这个对象。这样,当不同的对象调用同一个成员函数时,编译器将根据(gnj)该成员函数的this指针指向的对象确定引用哪个对象的成员函数。 成员函数访问类中数据成员的形式为:this - 成员变量 对 象 指 针第62页/共98页第六十二页,共99页。63 指向对象成员的指针使用前要先声明,再赋值,然后引用(ynyng)。声明形式为: 类型说明符类名:*指针名; 类型说明符 (类名:*指针名)(参数表); 对数据成员指针赋值形式为: 指针名=&类名:数据成员名; 注意:不能对类的私有成员取地址 对函数成员指针赋值形式为: 指针名=&类名:函数成员名;指向类的非静态成员(chngyun)的指针第63页/共98页第六十三页,共99页。64 访问(fngwn)数据成员形式为: 对象名.*成员指针名; 或 对象名-*成员指针名; 访问(fngwn)函数成员时,由于需要确定this指针,因而必须通过对象来调用非静态成员函数,形式为: (对象名.*类成员指针名)(参数表) (对象名-*成员指针名) (参数表) 指向(zh xin)类的非静态成员的指针(续)第64页/共98页第六十四页,共99页。65指向(zh xin)类的非静态成员的指针 对 象 指 针例:例: P216 例例6-13int main()Point a(4,5);Point *pl=&a;int (Point:*funcPtr)( ) const = & Point:getX;cout(a.*funcPtr)( )endl;cout*funcPtr)( )endl;couta.getX( )endl;coutgetX( )endl;return 0;第65页/共98页第六十五页,共99页。66 对类的静态成员(chngyun)的访问不依赖于对象,因此可用普通指针来指向和访问静态成员(chngyun),参见P216218页例6-14和例6-15:指向类的静态(jngti)成员的指针第66页/共98页第六十六页,共99页。67#include using namespace std;class Pointpublic:Point(int x=0, int y=0) : x(x) , y(y) count+; Point(Point &p)X=p.x;Y=p.y;count+;Point ( ) count - - ; int getX( ) return x; int getY( ) return y; static int count;例6-14 通过指针访问(fngwn)类的静态数据成员第67页/共98页第六十七页,共99页。68private:int x,y;int Point:count=0; /静态数据成员(chngyun),初始化int main() int *ptr = &Point:count;Point a(4,5);coutPoint A,a.getX(),a.getY(); cout“object count=“*ptrendl;Point b(a);coutPoint B,b.getX(),b.getY(); cout“object count=“*ptrendl; return 0;第68页/共98页第六十八页,共99页。69#include using namespace std;class Pointpublic:Point(int x=0, int y=0) : x(x) , y(y) count+; Point(Point &p)X=p.x;Y=p.y;count+;Point ( ) count - - ; int getX( ) return x; int getY( ) return y; static void showCount ( ) cout Object count=countendl; 例6-15 通过指针访问(fngwn)类的静态函数成员第69页/共98页第六十九页,共99页。70private:int x,y;static int count;int Point:count=0; /静态数据成员(chngyun),初始化int main() void (*funcPtr)( ) = Point:showCount;Point a(4,5);coutPoint A,a.getX(),a.getY();funcPtr();Point b(a);coutPoint B,b.getX(),b.getY(); funcPtr(); return 0;第70页/共98页第七十页,共99页。71动态(dngti)申请内存操作符 new 动态内存分配(fnpi) 堆对象:在程序运行过程中申请和释放的存储单元,该过程称为建立(new)和删除(delete) new:在程序执行期间,申请用于存放T类型对象的内存空间,并依初值列表赋以初值。若成功(chnggng),返回指向新分配的内存;否则,抛出异常 new 数据类型(初始化参数列表); int *point; point = new int(2); 区别: point = new int; 和 point = new int( ); 区别:若类存在默认构造函数,“new ”T和“new T( )”效果相同;否则, “new T( )”会为基本数据类型和指针类型的成员用0赋初值第71页/共98页第七十一页,共99页。72释放(shfng)内存操作符delete delete 指针名;功能:释放指针P所指向的内存。P必须是new操作 的返回值。注意:若被删除的是对象,则其析构函数将被调用;对于(duy)用new建立的对象,只能使用delete进行一次删除操作 动态存储分配第72页/共98页第七十二页,共99页。73例6-16 动态(dngti)创建对象#includeclass Point public: Point() X=Y=0; coutDefault Constructor called.n; Point(int xx,int yy) X=xx; Y=yy; cout Constructor called.n; Point() coutDestructor called.n; int GetX() return X; int GetY() return Y;void Move(int newX,int newY) x=newX; y=newY; private: int x,y; 动态存储分配第73页/共98页第七十三页,共99页。74int main() coutStep One:endl; Point *Ptr1=new Point; delete Ptr1; coutStep Two:endl; Ptr1=new Point(1,2); delete Ptr1; return 0;运行运行(ynxng)结果:结果:Step One:Default Constructor called.Destructor called.Step Two:Constructor called.Destructor called.第74页/共98页第七十四页,共99页。75例6-17动态(dngti)创建对象数组#includeusing namespace std;class Point /类的声明(shngmng)同例6-16,略;int main() Point *Ptr=new Point2; /创建对象数组 Ptr0.Move(5,10); /通过指针访问数组元素的成员 Ptr1.Move(15,20); /通过指针访问数组元素的成员 coutDeleting.endl; delete Ptr; /删除整个对象数组 return 0; 动态存储分配第75页/共98页第七十五页,共99页。76运行(ynxng)结果:Default Constructor called.Default Constructor called.Deleting.Destructor called.Destructor called.第76页/共98页第七十六页,共99页。77 利用动态内存分配操作可实现数组的动态创建。另一种更好的方法是将数组的建立和删除过程封装起来,形成动态数组类 动态数组中,为防止访问数组时下标(xi bio)越界,应使用断言assert(包含在头文件cassert中)。当assert判断为假,则程序中止第77页/共98页第七十七页,共99页。78例6-18动态(dngti)数组类#include#includeusing namespace std;class Point /类的声明(shngmng)同例6-16,略;/动态数组类class ArrayOfPointspublic: ArrayOfPoints(int size) : size(size)points=new Pointsize; ArrayOfPoints( )cout“Deleting”= 0 & indexsize);return pointsindex;private:Point *points;int size;第78页/共98页第七十八页,共99页。79int main()int count;coutcount;ArrayOfPoints points(count);points.element(0).move(5,0);points.element(1).move(15,20);return 0;运行(ynxng)结果:Please enter the count of points :2Default Constructor called.Default Constructor called.Deleting.Destructor called.Destructor called.第79页/共98页第七十九页,共99页。80动态分配数组时应注意(zh y):用new创建多维数组:new 类型(lixng)名T下标表达式1下标表达式2;如果内存申请成功,new运算返回一个指向新分配内存首地址的指针,是一个T类型(lixng)的数组。例如:char (*fp)3;fp = new char23;第80页/共98页第八十页,共99页。81char (*fp)3;fpfp+1fp00fp01fp02fp10fp11fp12第81页/共98页第八十一页,共99页。82例6-18动态创建多维数组#includevoid main() float (*cp)98;int i,j,k;cp = new float898;for (i=0; i8; i+)for (j=0; j9; j+)for (k=0; k9; k+) *(*(*(cp+i)+j)+k)=i*100+j*10+k; /通过指针(zhzhn)访问数组元素 动态存储分配第82页/共98页第八十二页,共99页。83for (i=0; i8; i+)for (j=0; j9; j+) for (k=0; k8; k+) /将指针cp作为数组名使用(shyng), /通过数组名和下标访问数组元素 coutcpijk ; coutendl;coutendl;第83页/共98页第八十三页,共99页。84动态存储分配函数(hnsh)(c语言) void *malloc( size ); 参数size:欲分配的字节数 返回(fnhu)值: 成功,则返回(fnhu)void型指针。 失败,则返回(fnhu)空指针。 头文件: 和 动态存储分配第84页/共98页第八十四页,共99页。85动态内存释放函数(hnsh)(c语言) void free( void *memblock ); 参数(cnsh)memblock:指针,指向需释放的内存。 返回值:无 头文件: 和 动态存储分配第85页/共98页第八十五页,共99页。86用vector创建(chungjin)数组对象 C+标准库提供了被封装的动态数组vector,且具有各种类型 vector是一个类模板,使用形式为: vector数组对象名(数组长度); 例如:int x=10; vectorarr(x); 用vector定义的数组对象的所有元素都会被初始化。若元素为基本(jbn)数据类型,则以0初始化;若元素为类类型,则调用类的默认构造函数初始化第86页/共98页第八十六页,共99页。87 当为元素指定初值时,则所有元素具有相同初值,形式为: vector数组对象名(数组长度,元素初值); vector数组对象元素与普通数组元素具有相同的访问形式: 数组对象名下标表达式 vector数组对象是封装了数组的对象,对象名表示一个数组对象,而非数组的首地址 vector数组对象的成员(chngyun)函数size()的作用是返回数组的大小第87页/共98页第八十七页,共99页。88例6-20 vector应用(yngyng)举例#include#includeusing namespace std;double average(const vector& arr) double sum=0; for(unsigned i=0;iarr.size();i+) sum+=arri;return sum/arr.size();int main()unsigned n;coutn;vectorarr(n);cout“Please input”n“real numbers:”endl;for(unsigned i=0;iarri;cout“Average=“average(arr)endl;return 0;第88页/共98页第八十八页,共99页。89#include#includeusing namespace std;class Point /类的声明(shngmng)同例6-16,略 ;class ArrayOfPoints /类的声明(shngmng)同例6-18,略 ;int main()int count;coutcount;ArrayOfPoints pointsArray1(count);pointsArray1.element(0).move(5,10);pointsArray1.element(1).move(15,20);例6-21 对象(duxing)的浅复制 深复制(fzh)与浅复制(fzh)第89页/共98页第八十九页,共99页。90ArrayOfPoints pointsArray2=pointsArray1;cout“copy of pointsArray1:”endl;cout“point_0 of array2: “pointsArray2.element(0).getX()“,” pointsArray2.element(0).getY()endl;cout“point_1 of array2: “pointsArray2.element(1).getX()“,” pointsArray2.element(1).getY()endl;pointsArray1.element(0).move(25,30);pointsArray1.element(1).move(35,40);cout“After the moving of pointsArray1:”endl;cout“point_0 of array2: “pointsArray2.element(0).getX()“,” pointsArray2.element(0).getY()endl;cout“point_1 of array2: “pointsArray2.element(1).getX()“,” pointsArray2.element(1).getY()endl;ruturn 0;例6-21 对象(duxing)的浅复制(续) 深复制(fzh)与浅复制(fzh)根据P227页的运行结果,发现当移动pointsArray1中的点后,pointsArray2中的点也被移动。这是与预期不相符(xingf)的,原因是只是浅复制(参见P222页ArrayPoints类的定义和P228页图6-11)。第90页/共98页第九十页,共99页。91#include #includeusing namespace std;class Point /类的声明(shngmng)同例6-16,略 ;class ArrayOfPointspublic:ArrayOfPoints(const ArrayOfPoints& v);/类的声明(shngmng)同例6-18,略 ;ArrayOfPoints:ArrayOfPoints(const ArrayOfPoints& v)size=v.size;points=new Pointsize;for(int i=0;isize;i+)pointsi=v.pointsi;int main()/同例6-21例6-22 对象(duxing)的深复制 深复制(fzh)与浅复制(fzh)根据P229页的运行结果,发现当移动pointsArray1中的点不再影响pointsArray2中的点。原因是深复制(参见P222页ArrayPoints类的定义、P110页深复制的定义和P229页图6-12)。第91页/共98页第九十一页,共99页。92 字符串以0作为结尾标记 可将字符串常量(chngling)赋值给指向常量(chngling)的指针: const char * STRING1=“This is a string. ”; coutSTRING1; 以下三种写法等价: char str8=p,r,o,g,r,a,m,0; char str8=program; char str =program; 当使用字符串处理函数时,应包含头文件cstring 字 符 串用字符数组存储(cn ch)和处理字符串第92页/共98页第九十二页,共99页。93字符串处理函数strcat(连接),strcpy(复制(fzh)),strcmp(比较),strlen(求长度), strlwr(转换为小写),strupr(转换为大写)头文件 字 符 串第93页/共98页第九十三页,共99页。94 构造函数的原型 string(); string(const string& rhs); string(const char* s); string(const string& rhs,unsigned int pos,unsinged int n); string(const char* s,unsigned int n); string(unsigned int n,char c); 使用string类需要包含头文件string,可用如下(rxi)形式给string对象初始化(原因参见P231页提示): string str=“Hello world!”; 字 符 串string类第94页/共98页第九十四页,共99页。95 string类的操作符:参见P231页表6-1(操作符重载) 常用成员函数(hnsh)介绍(参见P232页) append()、assign()、insert()、substr()、find()、length()、swap() 字 符 串string类(续)第95页/共98页第九十五页,共99页。96#include#includeusing namespace std;/根据(gnj)value的值输出true或false,title为提示文字inline void test(const char* title , bool value)couttitle“returns”(value?”true”:”false”endl;int main()string s1=“DEF”;cout“s1 is”s1endl;例6-23 string类应用(yngyng)举例 字 符 串第96页/共98页第九十六页,共99页。97string s2;couts2;cout“length of s2:”s2.length()endl;/比较运算符的测试(csh)test(“s1=”ABC”, s1=”ABC”);test(“”DEF”=s1”, ”DEF”=s1);/连接运算符的测试(csh)s2+=s1;cout“s2=s2+s1:”s2endl;cout“length of s2: “s2.length()endl;return 0; 字 符 串第97页/共98页第九十七页,共99页。98感谢您的观看(gunkn)!第98页/共98页第九十八页,共99页。NoImage内容(nirng)总结1。不声明构造函数,则采用缺省构造函数。(2)当“&”在给变量赋值时出现在等号右边或执行语句中表示取对象地址。自动的”auto”可以省略。例6.10:读入三个浮点数,将整数部分和小数部分分别输出。若被删除的是对象,则其析构函数将被调用。C+标准库提供了被封装的动态数组vector,且具有各种类型。s
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


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