面向对象程序设计.ppt_第1页
面向对象程序设计.ppt_第2页
面向对象程序设计.ppt_第3页
面向对象程序设计.ppt_第4页
面向对象程序设计.ppt_第5页
已阅读5页,还剩155页未读 继续免费阅读

下载本文档

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

文档简介

第三章 数据类型,我们将讨论的数据类型有:,整数类型、整数子类、浮点类型、数组、向量、指针等。,数据类型是程序设计语言的一个重要概念和重要内容。,首先复习已在第二章先行介绍的有关数据类型的一些基本概念,接着详细介绍C+定义的各种常用的数据类型,重点在于如何在程序设计中灵活地应用这些类型。,3.1 数据类型概述,1数据类型的定义,2数据类型的涵义,3数据类型的的重要性,4C+的数据类型一览,以上内容参见2.3,3.2 整数类型,整数类型简称整型,用来描述整型数值数据,其类型符是int。,整数类型是程序中最常用的类型之一。,整数类型的值域(值的集合)是无限整数集的子集。,例如: 123、678、10000,均是整型常量; int a,b,c; /a,b,c均被说明为整型变量。,1. 整数类型的分类,(1)依据其是否具有符号位,分为有符整型(signed int)和无符整型(unsigned int),默认形式为有符整型;,(2)依据其存储表示位数的不同又分为:标准整型(int)、短整型(short int)和长整型(long int)。,例如: int a,b,c; /a,b,c均为有符整型变量。 unsigned int num; /num为无符整型变量,(1)和(2)的组合,就产生了:有(无)符整型、有(无)符短整型、有(无)符长整型等六种形式,默认形式总是有符。,1. 整数类型的分类(续),下面给出整型分类表:,例如: usigned int x=23; int y=-67;/等价于signed int y=-67 unsigned int z=-43;/表示方式错误,2. 整型的表示范围,下表给出32位编译器(32位机)的各种整数类型的表示范围。,2. 整型的表示范围(续),例如: 1+5,a3, x0&y0, x=9。,3. 整数类型的操作集,算术运算,关系运算,整数类型所定义的操作包括:算术运算、关系运算、逻辑运算、位运算以及赋值操作等。,也即、允许对整型数据对象进行算术运算、关系运算、逻辑运算、位运算以及赋值操作等。,逻辑运算,赋值运算,3.3 整数子类(int Subtypes),整数子类型继承了整数类型的性质,但值域是整数类型值域的子集(一般比整数类型的值域小得多)。,例如字符的值是ASCII码,而ASCII码值实际上是整数,0255。,可以看出:,(1)字符类型的值域是整数类型值域的子集;,(2)字符类型继承了整数类型的操作集和机器内部表示。,C+定义的整数子类型有:字符型、枚举型、布尔型,3.3.1 字符类型,字符类型简称字符型,用来描述以单个字符作为其值的数据对象,也即描述字符数据。,类型标识符:char;,值域:是由语言定义的,与标准字符集有关的枚举集,例如ASCII字符集。,例如: a、A、x均是字符常量; char c1,c2;/c1,c2被说明为字符变量。,1. 字符类型的分类,依据其是否具有符号位,分为有符字符型(signed char)和无符字符型(unsigned char),默认形式为有符字符型。,例如: char int a,b,c; /a,b,c均为有符字符型变量。 unsigned char num; /num为无符字符型变量,2. 字符类型的表示范围,3. 字符类型的操作集,也即、允许对字符型数据对象进行算术运算、关系运算、逻辑运算、位运算、i/o操作、赋值操作等。,继承了整数类型的操作集,包括:算术运算、关系运算、逻辑运算、位运算、i/o操作、赋值操作等。,注意,字符型虽然继承了整数类型的操作集,但在输出操作上还是存在差异。对字符数据执行输出操作,输出的不是整数而是字符。,3. 字符类型的操作集(续),例如: int a=65; char b=65; cout a“ “bendl;,输出:65 A,对字符数据进行关系运算的比较依据是“字符集的对照排序”(元素的排序)。,例如:ab,运算结果为真。,4. C+的特殊字符,特殊字符也称为“转义字符”(escape character),它们是一些不可见的控制字符,例如控制回车、换行等等,其表示形式为:。,转义字符一览表,(1) n的用途,用来使输出流换行 cout”NamenAddrnTeln”;,4. C+的特殊字符(续),转义字符应用举例,(2) ”()的用途,输出加双(单)引号的串。 cout “aaaa”bbbb”ccccn”;,输出: Name Addr Tel,输出: aaaa”bbbb”cccc,3.3.2 枚举类型(enum Type),1. 枚举类型的概念,week:Sunday, Monday,Tuesday,Wednesday,Thursday, Friday,Saturday,请考察以下既常用又特殊的数据:,一周的天数七天,是可枚举的,我们可以用07表示SundaySaturday,也即用整数表示week。,这种表示法存在两个问题:(1)数据含义不明确,可读性差(2)无法实现区间限制以防止越界。,枚举类型简称枚举型,是一种特殊的数据类型,它的值域是某个整数区间,区间是可以指定的,而且区间中的所有整数都可以命名。,枚举类型的概念(续),对于程序中的这样一些特殊的数据对象,我们可以用枚举类型来描述。,enum weekSunday, Monday,Tuesday,Wednesday,Thursday, Friday,Saturday;,取哪个整数区间,如何给区间中的整数命名,这与实际的应用有关,因此枚举类型是可以由程序员自行定义的,属于自定义类型。,enum week Sunday, Monday,Tuesday,Wednesday,Thursday, Friday,Saturday;,枚举类型的概念(续),就该例的week而言,它的七个值对应整数区间0,6,也即,0取名为Sunday,1取名为Monday.。,由于没有指定区间(没有指定区间头),所以就以默认方式使用区间0,6。,如果将week的定义改为: enum week Sunday=10, Monday,Tuesday, Wednesday,Thursday, Friday,Saturday;,则Sunday=10,Monday=11,Saturday=16。 也即week所定义的整数区间为10,16,2. 定义枚举类型,枚举类型是非标准数据类型,需要程序员自行定义,其语法如下:,enum ,语法说明,enum:系统保留字;,枚举类型名:用户定义的标识符,值表:列出该类型的所有可能的取值(n个枚举常量)。,值表中的每个值都是一个命名的整型常量: 名=整数,例3-1 将由五种颜色组成的颜色集定义成枚举类型,其值对应的整数区间为1,5。,enum Colors Red=1,Blue,Green,White,Black。,2. 定义枚举类型,enum ,例3-2 将Word的一级菜单功能表定义为枚举类型。,enum WordMenu File,Edit,View,Insert,Format,Tools,Table, Reguirements,Windows,Help;,3. 声明枚举类型变量,在程序中定义了枚举类型后,可以用该类型来声明枚举变量,其语法与其它类型的变量之声明是一样的 。,enum Week Sunday=10, Monday,Tuesday, Wednesday,Thursday, Friday,Saturday; Week weekday = Sunday;,例3-3 声明Week类型变量weekday。,该语句说明了一个变量weekday,其类型是Week,被赋予的初值是Sunday。,试问变量weekday的可能的取值是什么?,3.3.3 布尔类型(bool Type),布尔类型简称布尔型,也称为逻辑型。布尔型数据对象只有两种取值:要么是“真”(True)要么是“假”(False)。,类型标识符:bool;,值域:只有两个值:True 1;False 0;可见其值域是整数的子集。,例3-4 考察下面的程序段,观察布尔变量如何声明。,bool a=3; /a的值为true bool b=1; /b的值为true bool bool c=a-b;/c的值为false;,因为c=1-1=0,3.4 浮点类型(float Type),浮点类型简称浮点型,用来描述实数。其值域(值的集合)为无限实数集的子集。,根据位数的不同,浮点类型又分为:单精度浮点型、双精度浮点型和长双精度浮点型。,因为位数多,再加上采用浮点表示,所以浮点类型的表示范围远远大于整数类型的表示范围,也即浮点类型不但可以表示小数,而且也可以表示大整数。,根据有无符号位,分为有符和无符浮点型;根据其长度又分为以下三种类型:,float :单精度浮点型,长度32位;,double :双精度浮点型,长度64位;,long double :长双精度浮点型,长度80位;,1. 浮点类型的分类,2. 浮点的书写格式及内部表示,浮点数既可以书写为十进制小数形式(定点形式),也可以书写成十进制指数形式(科学记数法)。,例如,实数35.623的浮点数字面值有以下两种格式: 35.623(十进制小数形式) 0.35623e+02(十进制指数形式),如果要表示成单精度型或长双精度型,则要在字面值后面加f或L。,直接写出的浮点数字面值默认为双精度型。例如上例的表示法,所表示的数都是双精度型。,2. 浮点的书写格式及内部表示(续),如果要表示成单精度型或长双精度型,则要在字面值后面加f或L。,例如,实数35.623表示成单精度型:其数字面值为:35.623f;表示成长双精度型,其字面值为:35.623L,例3-5 考察下面的程序段所声明的各种浮点类型数据。,float f1=19.2f; float f2=0.192e+02; double d1=19.2; double d2=0.192e+02f; long double ld1 =19.2L; long double ld2=0.192e+02;,单精度型数 将double型数转换成float; 双精度型数 将float型数转换成double 长双精度型数 将double型数转换成long double,3. 浮点类型的表示范围,下表列出了三种浮点类型的总长度、阶码位数、尾数位数和十进制有效位数。,4. 浮点类型的操作集,例如:double a,x,y; 1.0+5.5,a3.3, x0,算术运算,关系运算,浮点类型所定义的操作包括:算术运算、关系运算、逻辑运算、IO 操作、赋值操作等。,也即、允许对浮点型数据对象进行算术运算、关系运算、逻辑运算、I/O操作以及赋值操作等。,逻辑运算,赋值运算,3.5 数组(Arrays),3.5.1 什么叫数组,我们先分析几种与数组有关的特殊数据,通过分析,给出数组的几个基本概念,并讨论如何用程序语言提供的说明语句来定义数组(定义数组类型及声明数据)。,例3-6 一个包含n个字符的字符序列,例如“abcd“, 在程序中应该如何描述?,(1)常量表示,用双引号包围形成字符串“abcd”,该串由a b c d四个分量组成。,(2)变量表示,设置四个变量来分别表示串中的 四个字符(四个分量):,c1 a,c2 b,c3 c,c4 d,上述表示法存在的问题,(1)用四个独立的变量来表示一个整体中的四个分量,无疑支离了该整体,很难用统一的、有规律的方法去访问其中的任意分量。,(2)如果字符序列所包含的字符数(n)远远大于4,必将带来烦琐的重复描述。,什么叫数组 (续),(2)如果字符序列所包含的字符数(n)远远大于4,必将带来烦琐的重复描述。,例如n=1000,那么要声明1000个字符变量来表示: char c1,c2,c3,c4,c5,c6,c7,c8,c1000; 这显然是十分不现实的。,引入数组类型来描述之,char c1000;,c是一个字符数组,拥有1000个分量(数组元素),每个分量(ci,i=0n-1)相当于一个字符变量。这种表示法看起来十分简洁。,什么叫数组 (续),数组的概念,什么叫数组 (续),数组是一组相关的相同类型数据的集合。,它是由其它数据类型构造而成的新的、较为复杂的数据类型 构造类型。,数组所包含的n个相同类型的分量称为数组元素。每个元素由数组名加下标表达式来表示。,例如:a0表示a数组的第一个元素;ai表示a数组的第i+1个元素。 下标表达式是可以变动、可以计算的。,数组的维数,数组的维数与所描述的数据对象的组织结构有关。,数组的概念,什么叫数组 (续),就成绩表而言,如果要表示全班某门课的成绩,只需用一个一维数组float grade100来表示即可。,如果需要将全班同学多门课的成绩聚集在一起,就需要建立一个多维数组,例如表示二门课的成绩,则对应的数组是二维数组:float grade1002;,第一维(行)表示学生,第二维(列)则表示课程,行和列的交叉(数组元素)表示成绩。,实际上,我们仍旧可以将一个二维数组理解成一个更复杂的一维数组。,什么叫数组 (续),其复杂性表现在,它的每一个元素不是单个成绩,而是一个成绩集,也即它的每一个元素是一个一维数组。,也可以说,二维数组是一个基类型(元素的类型)是一维数组的一维数组。,直观地说,二维数组的每一行是一个一维数组。,3.5.2 定义一维数组,定义数组必须给出名称、成员的数据类型,维的长度(下标说明),有时还需要指定其存储类别。,语法,存储类别初始化值表;,解释,存储类别:与变量的存储类别一样,用来指明数组的存储特性,可以是extern、auto、static。,定义一维数组(续),存储类别 初始化值表;,类型:指明数组元素的数据类型,也称为数组的基类型。,数组的类型可以是基本数据类型,例如int、long int、double、float、char等,也可以是构造数据类型,例如数组、结构体等。,注意:同一数组的所有元素的数据类型均相同。,例如:float grade90; int num90,a33;,定义一维数组(续),存储类别 初始化值表;,数组名:用来标识数组,用标识符命名,其命名规则与变量名相同。,下标说明:说明数组包含的元素个数,下标说明必须是整型常量表达式。,例如:double grade90; /正确 int i,numi; /如果i为变量,则错误。,初始化值表:用来给数组元素赋初值。,例如:double grade=90.0,80.5,75.0;,定义一维数组(续),存储类别 初始化值表;,例3-7 下面给出几个定义一维数组的例子:,int a100,b200;/ a是整型数组,有100个整型元素 / b是整型数组,有200个整型元素 char name21; / name是字符数组,有21个字符 类型元素 char addr21*i /如果i是变量,则为错误的定义, 为什么?,3.5.3 一维数组的存储表示,数组的存储表示就是数组的逻辑存储结构,我们以int a100为例,给出示意性的表示:,一维数组的存储表示(续),一维数组的逻辑存储结构由两部分组成:,(1)数组描述符 :包括数组的基地址,下标上、下界,元素的数据类型以及元素的字节数等。,(2)元素的存储表示:数组元素的存储单元。,3.5.4 定义多维数组,定义多维数组必须给出数组的名称、成员的数据类型,各维的长度(下标说明),有时还需要指定其存储类别。,语法,存储类别 下标说明2下标说明n初始化值表;,例如: float grade1003;/该数组有100行,3列,如果将列视为课程、将行视为学生,则该数组可以存放100个学生3门课的成绩。,解释,定义多维数组(续),存储类别 下标说明2下标说明n初始化值表;,存储类别、类型标识符、数组名:其作用和语法规则与一维数组相同。,下标说明:多维数组必须有多个下标说明,分别说明各维的长度,各个下标说明同样必须为整型常量表达式,而且多维数组所包含的元素个数就是这些表达式的值的乘积。,初始化值表:用来给数组元素赋初值。,3.5.5 多维数组的存储表示,下面以 int a55为例,讨论二维数组的存储表示:,(1)该数组有五行、五列,包含的元素个数为5*5=25。,分析,(2)其默认的存储顺序是按行存放,即先依次存放第一行的五个元素,再存放第二行的五个元素,依此类推,此种存储方法称为“行主序”法。其逻辑存储结构如下图所示:,多维数组的存储表示(续),“行主序”法逻辑存储结构,按行读入数据并存放到数组中的程序段: int a55; for(int i=0;iaij; ,多维数组的存储表示(续),“列主序”法逻辑存储结构,按列读入数据并存放到数组中的程序段: int a55; for(int j=0;jaij; ,3.5.6 数组元素的引用,1一维数组元素的引用,数组中的每一个元素都可以像简单变量一样参加各种运算,例如输入、输出、赋值、计算等。这就是所谓数组元素的引用。,一维数组元素表示格式,例如:对于int a5有: a0,ai,ai+1。,下标表达式的值就是该元素在数组中的顺序号(0n-1),确切地说是相对于数组基地址的偏移量,也即相对地址。,几点注意事项,3.5.6 数组元素的引用(续),(1)下标表达式可以是整型常量 、整型变量、整型表达式。,a10用整型常量作为数组元素的下标; a i 用整型变量作为数组元素的下标; a i+50 用整型表达式作为数组元素的下标;,(2)下标表达式的取值范围是0 n-1。n是维长度,也即一维数组所包含的元素个数。,(3)数组第一个元素的下标值是0而不是1。,实例,3.5.6 数组元素的引用(续),例3-8 编写一个程序,用来输入30名学生的C+成 绩,并计算平均成绩。,分析,(1)学生成绩保存在文本文件中(d:datagrade.txt),(2)建立一个成绩数组,保存从文件读入的成绩。 double c_grade30;,(3)对该数组的30个元素进行累加,然后除以30即得到平均成绩。,程序,#include #include using namespace std; void main( ) int sum=0,i; double grade_c30; ifstream in(“d:datagrade.txt“); /从文件中输入成绩保存到数组中; for (i=0;igrade_ci; /计算总成绩 for (i=0;i30;i+) sum = sum + grade_ci; /输出平均成绩 cout “C+的平均成绩=“ sum/30endl; ,问题拓展:如果需要求30个成绩中的最高分、最低分,程序应如何改写?,2多维数组元素的引用,多维数组元素表示格式, ,例如:对于int a55有: a00,aij,ai+1j+1。,注意:各个下标表达式的规则与一维数组相同。,实例,2多维数组元素的引用(续),例3-9 编写一个程序,用来输入30名学生的C+、 高数、英语三门课程的成绩,存放到grade数组中, 并计算每个学生的总成绩,存放到total数组中。,分析,(1) 建立一个30*3的二维数组(30行*3列),每列存放30个学生一门课程的成绩。,(2) 建立一个具有30个元素的一维数组存放30个学生三门课程的总成绩。,程序,#include #include using namespace std; #define NUM 30 void main( ) int sum=0,i,j; double gradeNUM3,totalNUM; ifstream in(“d:datagrade3.txt“); /从文件中输入成绩保存到数组中; for (i=0;igradeij;,/计算三门课的总成绩 for (i=0;iNUM;i+) totali=0; for (j=0;j=2;j+) totali=totali+gradeij; /计算总成绩 /输出各个学生的总分绩 cout “学生成绩“; for (i=0;iNUM;i+) cout totali “ “; ,为什么要清零?,3.5.7 数组的初始化,所谓数组初始化就是在定义数组的同时直接给数组元素赋初值。可以给数组的所有元素赋初值,或仅给部分数组元素赋初值。,例如: char s5 = a,b,c,d,e;,该例在定义一维字符数组s的同时就对其初始化,也即给该数组的每一个元素都赋了初值:S0:a,S1: b,S2: c,s3: d , s4: e 。,3.5.7 数组的初始化(续),再如: int x10 = 0,0,0;,上面的说明语句在定义整型一维数组x的同时,给其中的前三个元素赋初值。,1. 一维数组的初始化,格式,存储类别 =;,解释,(1)在定义一维数组的同时,对该数组初始化。,(2)允许只对数组的部分元素赋初值。,(3) 值表是一个包含m(m=n)个元素的初值集合,元素之间用逗号分隔,每个元素必须是常量。,2二维数组的初始化,实例,例如: char s32 = a,b,c,d,e,f; 或 char s32 = a,b,c,d,e,f;,上面的说明语句在定义二维字符数组s的同时就对其初始化,也即给该数组的每一个元素都赋了初值,例如: a -s00; f - s21。,可以看出,二维数组的初始化是按“行主序”的顺序逐一给元素赋初值的。,2二维数组的初始化(续),格式,存储类别 =;,解释,(1)在定义二维数组的同时,对该数组初始化。,(2)允许只对二维数组的部分元素赋初值。,(3)二维数组的初始化值表是一个包含m * n个元素的初值集合,元素之间用逗号分隔,每个元素必须是常量。,2二维数组的初始化(续),例3-10 对指定二维数组的部分元素初始化。,char s32 = a,b,c,d;,或:char s32 = a,b,c,d;,在定义二维字符数组s的同时,按“行主序”的顺序给其中前二行的四个元素赋初值。,3.5 .7 数组应用实例,1实例一、排序问题(例3-11),所谓排序是对一组任意的数据序列,按关键字的序(大小)重新排列成有序的序列。,按关键字的序从大到小排列,称为降序;反之,如果按关键字的序从小到大排列,称为升序。,有多种排序方法,例如“冒泡”排序、“插入”排序、“选择”排序、“快速”排序、“堆排序”、“希尔”排序等等。,1)冒泡排序,算法的基本思想,“冒泡”法使一组原本无序的数据中,值较小者象气泡那样逐渐“上浮”,而值较大者挨个“下沉”,经过过若干轮处理后,其中的值最小着必定上浮至顶部,而值最大者必定下沉至底部。,每一轮处理都要对剩余的数据进行连续的比较和位置交换(当需要交换时),比较是在相邻的数据之间进行的;交换使得小者上浮、大者下沉,故形象地称之为“冒泡”。,4 9 8 7 3,原始序列,第1轮排序,第2轮排序,第3轮排序,第4轮排序,4 9 8 7 3,4 7 3 8 9,4 3 7 8 9,3 4 7 8 9,4 8 9 7 3,4 8 7 9 3,4 8 7 3 9,冒泡排序(续),下面的例子给出对由五个整型数据组成的任意序列4、9、8、7、3,采用“冒泡”法进行排序的全过程(经过四轮排序)。,4 9 8 7 3,原始序列,第1轮排序,第2轮排序,第3轮排序,第4轮排序,4 9 8 7 3,4 7 3 8 9,4 3 7 8 9,3 4 7 8 9,4 8 9 7 3,4 8 7 9 3,4 8 7 3 9,冒泡排序(续),排序过程分析,第一轮:五个数据中值最大者(9)沉底;,第二轮:剩下的四个数据中值最大者(8)沉底;,第三轮:剩下的三个数据中值最大者(7)沉底;,第四轮:剩下的二个数据中值最大者(4)沉底。,程序实现要点,冒泡排序(续),用一个数组来存放一组待排序的数据。,用一个二重循环结构来控制排序过程,其中外循环用来控制n-1轮排序,内循环用来控制每轮排序过程中,元素之间的连续比较和交换(让值最大者下沉)。,程序,#include void main() int array=4,9,8,7,3,15,1,2,6,5,temp; int len=sizeof(array)/sizeof(int);/计算数组元素个数,冒泡排序(续),for (int pass=1;passarrayi+1) /比较与交换 temp=arrayi; arrayi=arrayi+1; arrayi+1=temp; /if /外层for for (int i=0;i=len-1;i+) cout arrayi endl; ,2. 实例二、矩阵问题,最常见的矩阵问题包括矩阵运算,矩阵对角线元素的对调等等。,例3-12 对调m*m 方阵的两条对角线上的元素。,设m=5则5*5的方阵表示为:,a11 a12 a13 a14 a15 a21 a22 a23 a24 a25 a31 a32 a33 a34 a35 a41 a42 a43 a44 a45 a51 a52 a53 a54 a55,分析,用一个二维数组表示该方阵: int array55;,2. 实例二、矩阵问题(续),对角线元素对调,规律,当i=j并且i3,此时需要对调,也即:,对m*m的矩阵而言,则:,#include #include using namespace std; #define M 5 void main( ) int arrayMM; int i,j,temp; ifstream in(“d:dataphalanx1.txt“); ofstream out(“d:dataphalanx2.txt“); /输入方阵元素 for (i=0;i arrayij;,程序,for (i=0;iM;i+) for (j=0;jM;j+) if (i=j) /交换 temp=arrayij; arrayij=arrayi(M-1)-i; arrayi(M-1)-i=temp; /输出交换后的方阵 for (i=0;i=M-1;i+) for (j=0;j=M-1;j+) out arrayij“ “; out endl; ,2. 实例二、矩阵问题(续),for (i=0;iM;i+) for (j=0;jM;j+) if (i=j) /交换 temp=arrayij; arrayij=arrayi(M-1)-i; arrayi(M-1)-i=temp; /输出交换后的方阵 for (i=0;i=M-1;i+) for (j=0;j=M-1;j+) out arrayij“ “; out endl; ,实际上,程序中用来完成元素交换的二重循环可以简化为如下的一重循环:,for (i=0;iM;i+) /交换 temp=aii; arrayii=arrayi(M-1)-i; arrayi(M-1)-i=temp; ,为什么?,3.6 向量(Vectors),向量既是一种数据类型,又是一种对象实体(变量),象数组一样,它聚合(容纳)了一些类型相同的数据(对象实体),所以又称为容器。,1. 概念,向量与数组的不同之处在于:(1)向量自身封装了操作集(2)数组的体积是静态确定的,而向量的体积(容器的大小)是可以动态改变的。,向量是C+标准模板库(C+ SLT)的重要一员。 使用向量必须包含头文件vector: #include ,2. 定义向量,可以用以下四种方式定义向量(仅给出实例而没有讨论其语法)。,(1)vector a(10);,(2)vector b(10,1);,(3)vector c(b);,(4)vector d(b.begin(),b.begin()+3);,2. 定义向量(续),解释,四种形式的解释:,vector 是模板,此处的int表示向量的基类型(元素的类型)是整型;其一般形式是vetor ,表示向量的基类型可以是任何合法的数据类型。,形式1定义了可以容纳10个整数的向量a,但没有给元素赋初值;/int a10;,形式2定义了可以容纳10个整数的向量b,并且给每个元素赋初值为1;也即第一个参数表示元素个数,第二个参数表示初值。/int b10=1,1,1,1,1,1,1,1,1,1;,2. 定义向量(续),形式3用一个已存在的向量(b)来创建一个新向量c,c也包含10个整型元素,并且都被初始化为1,这一点是数组做不到的;,形式4同样是用向量b来创建新的向量d,它包含3个元素,并用b的前三个元素的值来初始化d的3个元素。,形式5,利用已存在的数组来创建(初始化)向量。,int a7=1,2,5,3,7,9,8; vector va(a,a+7);/va有7个元素,其初始值取自 于数组a的对应元素。,3. 向量的基本操作,获取向量元素个数,向量类提供了多种操作,例如获取向量元素位置,获取向量元素个数,元素操作(访问向量元素),插入、删除元素、清空向量等。这些操作大多是通过调用向量类的成员函数来实现的。,通过调用size()函数即可获取向量元素个数。,例如: vector c1(20,a); coutc1.size();/显示20,3. 向量的基本操作(续),访问向量元素,方式一、下标表达式,这种方式类似于访问数组元素。,例如: int a7=1,2,5,3,7,9,8; vector b(a,a+7); cout b5;/访问向量b的第6个元素,显示9,int a7=1,2,5,3,7,9,8; vector b(a,a+7); for (int i=0;ib.size();i+)/b.size()=7 cout bi“ “;/访问向量b的所有元素,3. 向量的基本操作(续),方式二、通过遍历器访问,通过调用begin()函数获取向量的第一个元素的位置,再通过位置指针(遍历器)的移动以及对指针的间接访问,即可遍历向量的所有元素。,例如: int a7=1,2,5,3,7,9,8; vector b(a,a+7); for (vector :iterator it=b.begin();it!=b.end();it+) cout *it“ “;/访问向量b的所有元素,3. 向量的基本操作(续),for (vector :iterator it=b.begin();it!=b.end();it+) cout *it“,说明,begin()函数:表示向量的第一个元素的位置,同时也表示该元素。,end()函数,表示向量的结束位置,即,最后一个元素之后。,vector :iterator:向量的遍历器类型,用来定义位置指针。,it:位置指针,*it:表示间接访问位置指针所指向的向量元素。,其它常用的操作,3. 向量的基本操作(续),例如: a.assign(b.begin(),b.begin()+3); /取b向量的前3个元素构成新的向量赋给a向量。,assign()函数:向调用该函数的向量赋值。,back()函数:访问向量的最后一个元素。,例如: int x=a.back();/将a的最后一个元素的值做为x的初值,3. 向量的基本操作(续),例如: a.clear(); couta.size();/显示0,clear()函数:清空向量,使向量中不再有元素。,例如: int x=a.front();/取a的第一个元素的值做为x的初值,front()函数:访问向量的第一个元素。,3. 向量的基本操作(续),例如: if (a.empty() cout“a is empty”,empty()函数:判断向量是否为空,返回值为布尔量。,例如: a.push_back(5);/在a向量最后一个元素之后插入5。,pop_back()函数:删除向量的最后一个元素。,push_back()函数:在向量的最后一个元素之后插入一个新元素。,3. 向量的基本操作(续),例如: a.resize(10); /将向量a的元素个数调至10,多则删,少则补 a.resize(10,2);/将向量a的元素个数调至10,多则删,少则补 增补的元素的值为2,resize()函数:调整向量空间(增加或减少元素个数)。,向量的关系运算:=、!=、=,例如: if (a=b) cout “向量a等于向量b“;,3. 向量的基本操作(续),例3-13 各种向量操作的程序验证。,#include #include using namespace std; main() vector c1(20,a); cout b(a,a+7); cout“b向量元素个数:”b.size()endl;/显示7 /以方式一访问向量元素 for (int i=0;ib.size();i+) cout bi“ “;/访问向量b的所有元素 coutendl;,/以方式二访问向量元素 for (vector :iterator it=b.begin();it!=b.end();it+) cout *it“ “;/访问向量b的所有元素 coutendl; /调整向量大小 b.resize(10,2); cout“b向量元素个数:“b.size()endl; for (i=0;ib.size();i+) cout bi“ “;/按方式一访问向量b的所有元素 coutendl; /插入新元素 b.push_back(3); cout“b向量元素个数:“b.size()endl; for (i=0;ib.size();i+) cout bi“ “;/按方式一访问向量b的所有元素 coutendl;,/充空向量 b.clear(); cout:iterator it1=c1.begin();it1!=c1.end();it1+) cout *it1“ ”;/按方式二访问向量c1的所有元素 coutendl; for (i=0;ic1.size();i+) cout c1i“ ”;/按方式一访问向量c1的所有元素 coutendl; ,4. 向量的应用举例,例3-14 文件aaa.txt中存放一些整数(个数不知),请统计这些整数中有多少两两相等,并输出统计结果。,12 3 45 67 8 9 56 232 12 23 12 1 8 1212 2312,分析,(1)按题意,存放在文件中的整数之中,共有四对整数两两相等,分别是第一、二、三行的12和第一、四行的8。,(2)必须将文件中的整数集读入到内存,方能进行判断和统计。,4. 向量的应用举例(续),12 3 45 67 8 9 56 232 12 23 12 1 8 1212 2312,(3)由于不能事先确定文件中的整数个数,所以用数组来存放这些整数显然不太合适。,(4)因为向量可以动态地改变大小,所以用向量来保存从文件读入的整数是比较合适的,这种方法可以视为“用向量来实现动态数组”。,(5)先创建一个空向量,然后伴随读文件操作,不断地往向量中添加所读入的整数。,(6)查找向量中两两相等的整数并计数。,程序,#include #include #include using namespace std; main() ifstream in(“aaa.txt“);/打开aaa文件 vector s;/创建空向量s int pair=0; /读文件并将读入的整数插入到向量s的末端 for (int a;ina;) s.push_back(a); /查找向量中两两相等的整数 for (int i=0;is.size()-1;i+) for (int j=i+1;js.size();j+) if (si=sj) pair+; cout pairendl; ,3.7 指针(Pointers),3.7.1 指针的概念,1. 什么叫指针,指针是C+ 提供的一种颇具特色的数据类型,允许直接获取和操纵数据地址,实现动态存储分配。,一个数据对象的内存地址称为该数据对象的指针 。,指针可以表示各种数据对象,例如:简单变量、数组、数组元素、结构体甚至函数。,换句话说:指针具有不同的类型,可以指向不同的数据存储体(存储其地址或首地址)。,1. 什么叫指针(续),例3-15 分析下面的说明语句和赋值表达式:,int *point1,a=123,b=567; double point220; point1=,point1和point2都是指针;,执行point1=&a操作后,point1存放变量a的地址,它指向变量a 的存储空间。如下图所示:,point2是数组名又是指向数组第一个元素的指针,如下图所示:,1. 什么叫指针(续),double point220; int a=123, b=567; point1=,注意:指针中的内容是可以动态改变的,例如point1原来指向变量a,当执行了point1 = &b操作后,即指向变量b:,2 指针的作用,(1) 实现复杂的数据结构,例如数组、链表、队列和堆栈等;,(2)能方便地表示和处理字符串;,例如: char s120=a,b,0,*sp1; sp1=s1;/s1和sp1都代表字符串 “ab”,2 指针的作用(续),(4) 在函数之间进行数据的双向传递,将函数的参数定义成指针类型,调用函数时对应的实参必须是某个数据对象的地址或首地址,也即采用传地址的方式,这样就可以实现数据的双向传递。,对于程序中所包含的大存储量的数据对象,一般用预先定义的指针变量来表示,当实际使用时才动态申请实际的存储空间,使用完毕立即释放。,(3) 实现动态存储分配,3指针类型,指针类型属于非标准类型,其取值是所表示的数据对象的内存地址,所以其值域是内存地址集,其长度与int类型相同。,语法, *,解释,类型,是指针类型的基类型,也即指针所指向的数据对象的类型,可以是任何合法的数据类型。,3指针类型 (续), *,定义指针类型和声明指针变量是同时进行的。,例如: int *a; 该语句既定义了整型指针int *,同时又声明了 整型指针变量a。,*,作用在各个标识符上,表示该标识符所标识的变量是指针变量。,3.7.2 声明指针变量,1. 指针变量,所谓指针变量就是类型为指针类型的变量。用说明语句来声明指针变量。,语法, *,*,*;,解释,类型:用来指明指针类型的基类型,可以是任何合法的数据类型。例如整型、字符型、浮点型、数组等等。,标识符:标识指针数据对象,被标识的对象可以是基本变量、数组、函数等。,举例,3.7.2 声明指针变量(续),例3-16 分析和比较下面的语句所声明的四种不同数据对象。 char s1,s2100=a,b,c,d,n,*s3,*s4100;,上面的语句声明了四个变量:,s1是字符型变量,只能存放单个字符 ;,s2是字符数组,最多可以存放100个字符,而数组名s2本身又是一个指针,它存放数组的首地址(也即存放第一个元素的地址);,s3是字符型指针变量,用来存放字符数据的内存地 址或字符串的首地址。如果其中存放的是字符串的 首地址,则它指向一个字符串,或者说它代表一个 字符串,例如,执行s3=s2后,则s2等价于s3:,3.7.2 声明指针变量(续),例3-16 分析和比较语句: char s1,s2100=a,b,c,d,n,*s3,*s4100; 所声明的四种不同数据对象。,s2,s3两者的关系如下图所示:,3.7.2 声明指针变量(续),例3-16 分析和比较语句: char s1,s2100=a,b,c,d,n,*s3,*s4100; 所声明的四种不同数据对象。,s4是字符型指针数组,最多可以存放100个字符串的指针(地址),也即每一个元素都可能指向一个字符串,如下图所示:,2. 指针变量的初始化,可以在定义指针变量的同时给其赋初值(赋予某个数据对象的内存地址或空值(NULL)。,指针初始化的过程也称为建立指针。,例如: int i=10; int *iptr = ,上面的说明语句在声明指针变量iptr的同时即赋予初值,其初值是i的地址。也即iptr指向整型变量i,对于iptr的访问(可以表示成*iptr)也就是对i的访问。,#include main() int i=10; int *iptr = ,3几点说明,(1)标识符前面的“*”并不是名称的一部分,而表示该数据对象的类型为指针类型,也即声明该数据对象是指针类型数据对象。,(2)指针变量可以和其它变量在同一语句中声明。,例如: double d1,*d2;,(3)指针变量只能存放相同基类型的数据对象的内存地址,例如整型指针只能存放整型变量的地址。换句话说,一个指针变量在任何时候都只能指向同一基类型的数据对象。, *,*,*;,这就是所谓“指针类型与实际存储的匹配”问题 ,例如:,3几点说明(续),(3)指针变量只能存放相同基类型的数据对象的内存地址。换句话说,一个指针变量在任何时候都只能指向同一基类型的数据对象。,例如: char *c; int i; c=,错误的赋值,因为c只能指向字符或字符串。,(4)由于指针类型的值域是内存地址集,实际上是整数的

温馨提示

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

评论

0/150

提交评论