《C自定义数据类型.pptx》由会员分享,可在线阅读,更多相关《C自定义数据类型.pptx(96页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、15.1 自定义数据类型概述 除了基本数据类型的数据外,程序还经常需要描述一些复杂的概念,如线性表、员工等,一个员工有多个属性需要描述,如姓名、工作部门、工资、职务等。因此仅仅使用一个基本数据类型的变量不能描述,必须要由多个基本数据类型变量一起才能描述一个较复杂的员工的概念。C+除了提供基本数据类型(int、char、float、double、bool)外,还提供了用基本数据类型构造自定义的数据类型的机制,使得程序能够对复杂数据如,员工等进行描述与处理。本章将对C+提供的自定义类型的构造机制进行分别介绍,他们包括:枚举、数组、结构、联合以及指针与引用。第1页/共96页25.2 枚举类型 1枚举
2、类型的定义C+基本数据类型变量的取值范围是语言预先定义好的,而枚举类型变量的取值范围是由程序定义的。在定义一个枚举类型时,需要列出其变量所能取的每个值。枚举类型的定义通过关键字enum实现,格式如下:enum ;例如,下面定义了两个枚举类型:enum Month JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC;enum Position LEFT,RIGHT,TOP,BOTTOM;第2页/共96页3枚举类型的每一个枚举值都对应着一个整型值,通常情况下,第一个枚举值对应常量0,第二个枚举值对应常量1,依次类推,如上述定义中JAN值为0,FEB值为1
3、,DEC值为11;LEFT值为0,RIGHT值为1,BOTTOM值为3。在定义枚举类型时,也可以给枚举值指定对应的整数值,例如:enum DAYSUN=7,MON=1,TUE,WED,THU,FRI,SAT;这时,SUN对应7,MON对应1,TUE对应2,WEB对应3,依次类型。可以给几个枚举值指定相同的整数值。如:enum ParameterMAX_ID_LEN=10,MAX_NAME_LEN=10;枚举值MAX_ID_LEN和MAX_NAME_LEN对应的整数值都是10。第3页/共96页4枚举类型变量定义的格式如下:;例如,下面是一些枚举类型变量的定义:Position p1,p2;DAY
4、 workday;Month v;除此之外,枚举类型的变量也可以在定义枚举类型的同时定义。例如下面定义了3个Color类型的变量c1、c2、c3:enum Color RED,BLUE,GREEN c1,c2,c3;定义枚举类型时,可以省略枚举类型名,此时,必须在定义枚举类型时,定义变量,否则以后无法定义。例如:enum RUNNING,STOPPING,PAUSE r1,r2;第4页/共96页52枚举类型的运算能够对枚举类型施与整型所能够进行的所有运算,只是有些运算过程中,会有些限制,如赋值运算和输入输出。(1)赋值运算可以使用一个枚举值对枚举变量赋值,例如:Position p1,p2;P
5、1=LEFT;P2=P1;第5页/共96页6(2)输入输出操作不能直接对枚举类型变量进行输入。例如,下面的操作是错误的:Day d;cin d;/错误通常采用输入整型值,然后强制转换到枚举类型。例如:int i;cin i;d=(Day)i;/强制转换对枚举变量输出的是该变量枚举值对应的整数值。Day d;d=SUN;cout d;/输出对应的整数值7第6页/共96页7(3)除(1)、(2)外的其他任何整型能够参与的运算除了赋值操作和输入/输出操作有所限制外,可以对枚举类型的值进行任何整型值能够进行的运算。在运算时,系统首先把它们转换成对应的整型值,然后按照整型的操作进行。如,可以对两个枚举值
6、进行大小比较:bool b=WEDTHU;/结果为true。系统利用WED对应的整数值3和THU对应的整数值4,进行比较。再如,可以对枚举类型进行算术运算,在运算时,枚举值将转换成对应的整型值,然后进行算术运算。对枚举类型进行算术运算的结果类型为算术类型。例如:Day d1,d2;d1=MON;d2=d1+1;/错误,因为d1+1的结果为int类型d2=(Day)(d1+1);/正确可以将枚举类型的每个枚举值当作一个整型符号常量。如:int const MAX_LEN1=20;enum MAX_LEN2=20;在使用MAX_LEN1的地方可以使用MAX_LEN2来代替。第7页/共96页85.3
7、 数组类型第8页/共96页95.3.1 一维数组一维数组通常用于表示由固定多个同类型的具有线性次序关系的数据。1.一维数组变量的定义一维数组变量定义时,的格式为:;例如,下面定义了一个由10个长整型数所构成的一维数组变量a:long a10;即a中可存放10个长整数。第9页/共96页102.一维数组元素的访问一个一维数组包含n多个相同类型的元素,每个元素都可以单独访问,访问一维数组元素的格式为:其中为一个整型表达式,它的值表示访问一维数组的第几个元素。C+中,一维数组的第一个元素的下标是0。例如,对于下面定义的一个一维数组变量d:double d10;d0表示该数组的第一个元素,d1表示第二个
8、元素,d9表示最后一个元素。一维数组的最后一个元素的下标是数组的-1。d0、d1、d2、d9都是double 型的变量.第10页/共96页11例 从键盘输入10个整数,统计并输出这10个整数的和。#include using namespace std;int main()int a10;int index=0;cout 输入10个整数值:;while(index aindex;index+;int sum=0;for(index=0;index10;index+)sum+=aindex;cout 你所输入的10个整数的和为:sum;return 0;第11页/共96页123.一维数组变量的初
9、始化程序中定义的每个变量在使用前都要有确定的值。在定义一维数组变量时,可以对其进行初始化,初始化值用一对大括号()括起来,有以下几种初始化方式。(1)定义数组变量时,对每个元素进行初始化。例如:int a5=11,13,14,15,16;各数组元素的初始化结果为:a0为11,a1为13,a2为14,a3为15,a4为16。大括号以及其内的值称为数组变量的初始化列表。(2)初始化表中的值可以少于数组元素个数,不足部分的数组元素初始化成0。例如:int b5=20,34;数组元素b0、b1、b2、b3、b4分别初始化成:20、34、0、0、0。(3)如果在定义数组时对每个元素都进行了初始化,则数组
10、元素个数可以省略,其元素个数由所提供的初始化值的个数决定。例如:int c=55,2,6,4;初始化的结果为:c0为55,c1为2,c2为6,c3为4。第12页/共96页134一维数组的存储对于一维数组变量,编译器将会在内存中为其分配连续的存储空间来存储数组的元素。例如,下面的一维数组变量a:int a10;其内存空间分配如图所示。a0a1a9一维数组所占用的存储单元大小可以用sizeof运算符来计算。例如,下面将输出一维数组a所占用的内存字节数。cout sizeof(a);第13页/共96页145.3.2 二维数组 1二维数组变量的定义二维数组变量的定义格式为:;例如:int a46;定义
11、了一个由46个整型数所构成的二维数组类型的变量a。第0行第1行第2行第3行第0列第1列第2列第4列第3列第5列第14页/共96页15访问二维数组元素的格式为:其中,和分别为一个整型表达式,它们分别表示所访问的元素在二维数组中的行与列,第一行与第一列的序号均为0。例如,对于前面的二维数组变量a,a00表示该数组中第0行和第0列的元素,aij表示第i行和第j列的元素,a35表示最后一行和最后一列的元素。这些元素都可以看成是一个int 型变量,可对它们实施int型所允许的所有操作。第15页/共96页16例 输入一个的矩阵,求出两条对角线元素值之和。解:一个矩阵有两条对角线,一条对角线的元素为:a00
12、、a11、an-1n-1。另外一条对角线的元素为:an-10、an-21、a0n-1。#include using namespace std;int main()const int n=4;int mnn;int i,j;cout 输入矩阵(n x n ):n;/遍历二维数组需要双重循环,给每个元素输入值for(i=0;in;i+)for(j=0;j mij;int sum=0;for(i=0,j=0;in;i+,j+)sum+=mij;/求对角线和for(i=n-1,j=0;jn;i-,j+)sum+=mij;/求对角线和 cout sum=sum;return 0;第16页/共96页17
13、3二维数组的初始化对二维数组变量的初始化可以采用以下的格式。(1)分行初始化。如:int a23=3,4,5,7,8,9 这种方式比较直观,用第一个括号3,4,5对第0行进行初始化,因为a0代表的是一个有3个元素的一维数组,用7,8,9对第1行a1进行初始化,依次类推。每个括号内的初始值列表都按照一维数组的方式对二维数组的对应行进行初始化。第17页/共96页18(2)可以将所有元素写在一个花括号内,系统按照数组元素排列的顺序对各元素进行初始化。如:int a23=3,4,5,7,8,9;(3)在定义二维数组时,若给出了所有元素的初始化值,则数组的行数可以省略,其行数由初始值的个数来决定。例如,
14、下面的二维数组a有3行:int a3=1,2,3,4,5,6,7,8,9;编译器知道数组每行有3列,则总共给出了9个元素,则编译器能够计算出数组有3行。初始化后数组各元素的值为:1 2 3 4 5 67 8 9第18页/共96页194.二维数组的存储对于二维数组变量,编译器也将在内存中分配连续的存储空间来存储数组元素。在C+中,二维数组是按照行的顺序连续存储的,即先是第0行元素,再是第1行元素,依次类推。例如,对于下面的二维数组变量a:int a104;其内存空间分配如图所示。a00a03a10a13a90a93用sizeof(a)可以计算出二维数组a所占用的内存字节数。第19页/共96页20
15、例 有一个45的矩阵,编程求出其中值最大的那个元素的值,以及其所在的行号和列号。解:可以采用“打擂台”的方式,程序中,将a00作为第一个人。#include using namespace std;int main()int max;int row=0,colum=0;/保存最大值的行和列int a45=3,10,3,50,45,11,47,39,29,45,33,4,23,-29,-23,1;max=a00;for(int i=0;i=2;i+)for(int j=0;j=3;j+)if(maxaij)max=aij;row=i;colum=j;cout 最大的值为:max 其所在的行:ro
16、w列:colum endl;return 0;第20页/共96页215.4 字符数组(字符串)程序中经常需要处理字符串数据,C+中提供了两种处理字符串的方式:cstring头文件中声明的处理以0结束的字符串的函数和string头文件中定义的string类描述的字符串。下面分别介绍这两种方式。第21页/共96页225.4.1 以0结束的字符串 一般使用char型的一维数组(即数组元素为char型的一维数组)来存储以0结束的字符串。例如下面的字符数组s可以用来存储字符串:char s10;s可以存储的字符串的最大长度(字符串中字符的个数)为9个字符。因为C+在数组中存储字符串时,在最后一个字符的后
17、面存储一个字符0(ASCII码为0的字符)作为字符串的结束标记。在定义字符数组变量时,可以对其进行初始化,如:char s110=w,e,l,c,o,m,e,0;char s210=welcome;char s310=welcome;char s4=welcome;第22页/共96页23也可以定义二维数组保存多个字符串,数组的每行保存一个字符串。如:char errmsg20=memory error,div 0 error,value is too big;“memory error”初始化第一行,“div 0 error”初始化第二行,“value is too big”初始化第三行。在C
18、+标准库的头文件cstring和string.h中也声明了一些用于对字符串进行整体操作的函数,这些函数处理的字符串都必须以0结束。下面介绍常用的操作。第23页/共96页241.计算字符串长度所谓字符的串长度是指字符串中的字符个数,但不包括字符串结束符。例如,字符串nanjing的长度为7。求字符串长度的函数原型为:int strlen(const char s);功能:计算以0结束的字符数组中字符的个数(不包括0)。其中的const表示函数strlen不会和不能修改参数的值。如:char s=”C+PROGRAMMER”;int len=strlen(s);/结果为14 第24页/共96页25
19、2.字符串复制要使字符变量ch的值为A,可以采用赋值的方法:ch=A。如果想使有10个元素的字符数组a中存储字符串“olympic”,也有很多方法,如:(1)字符数组初始化char a10=olympic;(2)逐个字符输入for(int index=0;index aindex;a7=0;(3)用C+的输入流cin a;第25页/共96页26(4)使用字符串复制函数strcpystrcpy函数原型为:char*strcpy(char dst,const char src);功能:将参数src表示的字符串复制到参数dst指定的字符数组中并自动在dst中加上一个0,dst中原来的字符串将会被自动
20、覆盖。函数返回的是dst的值。要注意,当src中的字符串长度大于dst中所对应的字符数组大小时,可能会出现意想不到的错误。如:char s10;char s2=”hello”;strcpy(s,s2);cout s;/输出为:hello第26页/共96页273.字符串拼接若要把两个字符串合二为一,连接成一个更长的字符串。可以利用字符串连接函数strcat,函数原型为:char*stcat(char dst,const char src);功能:把src表示的字符串内容增加到dst中原来字符串的后面,从dst最后的0的位置开始增加,最后在拼接的字符串后加0作为结束标记。如:char s20=”h
21、ello”;char s2=”world”;strcat(s,s2);cout s;/输出结果为:helloworld第27页/共96页284.字符串比较可以采用字符串比较函数strcmp来比较两个字符串的大小,函数原型为:int strcmp(const char s1,const char s2);功能:比较两个字符串s1、s2的大小。strcmp的返回值 例如:char a=china,b=beijing;cout strcmp(a,b);/输出1,大于0,因此,china大于beijing第28页/共96页295.字符串的大小写转换 我们可以将字符串中的每个字符独立进行大小写转换,以完
22、成整体字符串的大小写转换。也可采用两个库函数strlwr和strupr完成字符串的整体大小写转换。大写转换为小写的函数原型为:char*strlwr(char src);功能:将src指定的字符串中的小写字母转换成大写字母,其他字符不变。小写转换为大写的函数原型为:char*strupr(char src);功能:将src指定的字符串中的大写字母转换成小写字母,其他字符不变。第29页/共96页30例 将指定字符串转换成大写和小写。#include using namespace std;int main()char a15=China2008,b=Beijing Olympic;strupr(
23、a);cout a endl;strupr(b);cout b endl;strlwr(a);cout a endl;strlwr(b);cout b endl;第30页/共96页315.4.2 C+字符串string 1.字符串变量的定义和其他类型的变量一样,string类型的变量必须先定义后使用。例 字符串变量的定义和使用。#include#include using namespace std;int main()string str;cout str=str endl;/str为空string str1=Beijing;/定义一个字符串,同时初始化cout str1=str1 endl
24、;string str2(China);/定义一个字符串,同时初始化cout str1=str2 endl;string str3;str3=China Beijing;/重新赋值cout str3=str3 endl;str3=nanjing;cout str3=str3 endl;/输出:nanjing string str4;str4=str3;/用一个字符串变量给另一个赋值cout str4=str4 str;cout str;对str输入时,输入的字符串没有长度限制,系统会在str内部自动调节内存空间来存放输入的字符串。第32页/共96页333.字符串变量的操作 对string变量之
25、间的大小比较,可以直接使用简单的关系运算符.第33页/共96页34例 string字符串变量的大小比较。#include#include using namespace std;int main()string str1;string str2,str3;cout str1;/字符串输入,不限长cout str2;str3=str1+str2;/字符串拼接cout str1+str2=str3 endl;cout str2?=str2)endl;cout str1str2?=(str1str2)endl;cout str1=str2?=(str1=str2)endl;cout=str2?=st
26、r2)endl;cout str1=str2?=(str1=str2)endl;cout str1!=str2?=(str1!=str2)endl;return 0;第34页/共96页35例 string字符串变量的简单使用。#include#include using namespace std;int main()string str1;cout str1;int len=str1.length();/获取字符串的长度cout str1的长度为:len endl;for(int index=0;indexlen;index+)cout str1index;/单独访问字符串中的一个字符ret
27、urn 0;第35页/共96页365.5 结构 在实际生活中,有着大量由不同性质的数据构成的实体,如日期就是由年、月、日组成的,通信录就是由姓名、地址、手机号码、e_mail等组成的,对于像日期、通信录这样的实体,用数组是难于描述的。C+中可以用结构了描述这样的实体。结构是一组相关的不同类型的数据的集合。结构类型为处理复杂的数据提供了便利的手段。下面详细介绍结构的定义和使用。第36页/共96页375.5.1 结构类型的定义 结构类型的定义格式如下:struct ;例如,下面是学生数据类型的定义:struct Employeeint no;char name20;sex sex;Date hir
28、e_date;Position pos;double salary;其中的Sex、Date和Position的定义如下:enum SexMALE,FEMALE;struct Dateint year,month,day;enum PositionPROGRAMMER,SALE,MAMANGER;第37页/共96页385.5.2 结构变量的定义和初始化 1.结构变量的定义结构类型的变量称为结构变量,结构变量的定义形式如下:;例如,下面是一些结构变量的定义:Date today,yesterday,some_date;Employee m,m2;2.结构变量的初始化在定义结构类型的变量时可以对其进
29、行初始化,其格式与数组变量初始化类似,即用大括号()把每个成员的初始化值括起来,并且每个初始化值要与相应的成员对应。例如,下面定义了一个Employee结构类型的变量em,并对其进行初始化:Employee em=1088,”张强”,MALE,2002,8,2,SALE,5000;其中,由于em的第四个成员hire_date也是一个结构变量,因此采用了嵌套的初始化方式。第38页/共96页393.结构变量的存储结构变量在内存中占用一块连续的内存空间,其各个元素依它们在结构类型中的定义次序存储在这块内存空间中。例如,对于下面的结构类型变量m:Employee m;其内存空间安排如图所示。m.nom
30、.hire_datem.sexm.posm.salarym.name对于下面的两个结构变量m1、m2:Employee e1,e2;系统会分配不同的存储空间来存放它们的成员。如e1和e2都有自己的空间存放自己的no、name等成员。第39页/共96页405.5.3 结构变量成员的访问 对于一个结构变量,我们可以用下面的格式来访问它的成员:.上述的点(.)称为成员访问运算符,其左边的操作数一定是一个结构类型(或者类)的变量(或对象),右边的操作数是相应结构(或类)的一个成员。例如:today.year表示访问结构类型变量today的成员year。结构类型变量的每个成员都可以看作是一个独立的变量(
31、称为成员变量),对成员变量所能实施的操作由成员的类型来决定。第40页/共96页415.5.4 结构与函数 结构类型可以作为函数的形参类型以及函数的返回值类型,当需要把一个结构数据传给一个函数时,相应函数的形参数应定义为结构类型,而实参则写结构变量的名字。第41页/共96页42例 采用传值方式编写函数打印职工信息。#include using namespace std;enum SexMALE,FEMALE;struct Dateint year,month,day;enum PositionPROGRAMMER,SALE,MANAGER;struct Employeeint no;char
32、name20;Sex sex;Date hire_date;Position pos;double salary;void print_employee(Employee e)cout 工号:e.no endl;cout 姓名:e.name endl;cout 性别:(e.sex=MALE?男:女)endl;cout 招聘日期:e.hire_date.year 年 e.hire_date.month 月 e.hire_date.day 日 endl;cout 职务:;switch(e.pos)case PROGRAMMER:cout PROGRAMMER endl;break;case SAL
33、E:cout SALE endl;break;case MANAGER:cout MANAGER endl;break;cout 工资:e.salary endl;int main()Employee m;strcpy(m.name,李强);m.no=1000;m.pos=MANAGER;m.salary=8000;m.sex=MALE;m.hire_date.year=2007;m.hire_date.month=5;m.hire_date.day=10;print_employee(m);return 0;第42页/共96页435.6 联合 联合用于把多个不同类型的变量放在同一块内存区域。
34、在语法上,联合类型的定义与结构类型类似,不同之处在于把struct关键字替换成union。例如,下面定义了一个类型un:union unint i;char c;double d;上面的类型un既可以表示int型数据,也可以表示char以及double型数据。联合类型与结构类型的区别在于:结构变量所占用的内存空间是其所有成员占用内存空间的和;而联合变量的所有成员占有同一块内存空间,该内存空间的大小为其最大成员所需要的内存空间的大小。第43页/共96页44例如,对于下面的变量u:un u;例如,假设字符占1字节内存空间,int型占4字节内存空间,double型占8字节内存空间,变量u的的内存结构
35、如图所示。char型int型占4字节double型占4字节第44页/共96页45变量u的3个成员共同占用同一块内存区域。在使用联合变量时,不同时刻把它看成是不同类型的变量。如:u.i=100;表示程序员把u看成是int型变量,此时前4个字节存储的是100的二进制补码。后4字节没有使用。再有:u.d=4.56;表示程序员将u看成是一个double型变量,此时8字节存储的是4.56的内存二进制表示(包括指数部分和尾数部分),要注意,此时前4个字节的原来的100的二进制补码已经被覆盖。因此,若有:cout u.i;输出的结果肯定不是100。“u.i”的含义是:将u所占内存空间的前4个字节,看作一个i
36、nt型变量来看待。联合类型变量的赋值是按其占有的整个内存空间进行复制,而不是按某个成员来赋值。例如,对于下面的赋值操作:un u2;u2=u;它不是只把u.i赋给u2.i,而是把u所占内存空间所有内存中内容都复制到u2的内存空间中。第45页/共96页46例 联合变量成员的访问。#include using namespace std;union unchar c;int i;double d;int main()un u;u.c=a;cout u.c endl;u.i=100;cout u.i endl;u.d=4.56;cout u.i endl;/输出的结果不是100cout u.d en
37、dl;return 0;第46页/共96页475.7 指针 第47页/共96页485.7.1 指针的基本概念 在计算机中,所有的数据都是存放在存储器中的。一般把存储器中的一个字节称为一个内存单元,为了正确访问这些内存单元,必须为每个内存单元编上号。根据一个内存单元的编号即可准确地找到该内存单元。内存单元的编号叫做地址,通常也称为指针。在C+语言中,允许用一个变量来存放指针,这种变量叫做指针变量。因此一个指针变量的值就是某个内存单元的地址或称为某内存单元的指针。一个指针是一个地址,是一个常量。而一个指针变量却可以被赋予不同的指针值,是变量。但经常把指针变量称为指针。为了避免混淆,C+语言约定:“
38、指针”是指地址,“指针变量”是指值为地址的变量 第48页/共96页495.7.2 指针变量的定义 在定义一个指针变量时,必须指出它能表示何种类型程序实体的内存地址,或指向何种类型的程序实体。其格式为:*;其中,为所指向的变量的类型,通常称该为指针变量的基类型,它可以是任意的C+数据类型;为所定义的指针变量的名字,用标识符表示;符号“*”表示定义的是指针变量,以区别与普通变量定义。例如,下面定义了一个可以指向int型变量的指针类型变量p:int*p;指针变量拥有自己的内存空间,在该空间中存储的是另一个变量的地址,即指针变量的值是另一个变量的内存地址。例如,上面的指针变量p的值可以是某个整型变量的
39、内存地址。第49页/共96页505.7.3 指针变量的操作1.取地址运算(&)在C+中,可以通过取地址运算符“&”来获得一个变量的地址。例如:int a;int*p;p=&a;/&a表示取变量a的地址。将变量a的地址赋给指针变量p执行完该语句后,变量p的内存空间的值就是变量a的地址,称指针p指向变量a。第50页/共96页512.访问指针指向的变量(*和-)对于一个指针变量,可以通过间接访问操作符“*”来访问它所指向的变量,其格式为:*上面的操作的含义是访问所指向的内存空间的值。例如:int a;int*p=&a;/p指向a*p=100;/*p就代表了acout a;/输出100对于一个指向结构
40、类型变量的指针变量,如果通过该指针变量来访问相应结构变量的成员,则可以写成:(*).或-其中是所指向的结构的成员。第51页/共96页52例 通过指针访问结构成员。#include using namespace std;struct examint i;double d;char ch;int main()exam a;exam*p=&a;p-i=100;cout (*p).i a.i endl;a.ch=c;cout (*p).ch ch endl;return 0;第52页/共96页533.一个指针加上或减去一个整型值一个指针可以与一个整型值进行加或减运算,运算结果为与该指针同类型的指针。
41、值得注意的是:当一个指针与一个整型值进行加(或减)运算时,实际加(或减)的值由该指针所指向的变量类型来决定的。指针的加(或减)运算通常用于以指针方式来访问数组元素。例如,对于下面的一维数组变量a:int a10;除了采用a0、a1、.、a9来访问数组a的元素外,还可以通过定义一个指针变量p,并让它指向数组的第一个元素:int*p;p=&a0;然后,采用*p、*(p+1)、.、*(p+9)的形式来访问数组a的元素。第53页/共96页544.两个相同类型的指针相减两个相同类型的指针相减操作结果为整型值,值的大小由指针所指向的类型决定的。例 两个指针相减。#include using namespa
42、ce std;int main()int a7;int*p=&a0;int*q=&a4;int offset=q-p;/offset为4cout a0-a4之间有 offset 个int型的变量n;char*pc1=(char*)(p);/强制类型转换char*pc2=(char*)(q);int charnum=pc2-pc1;cout a0-a4之间有 charnum 个char型的变量n;return 0;第54页/共96页555.两个相同类型的指针比较两个同类型的指针可以进行比较运算,其含义是比较它们所对应的内存地址数值(无符号数)的大小。第55页/共96页566.指针的输出有时,我们
43、需要把一个指针变量内的地址值输出。这时,我们可以通过cout对象的插入操作符()来实现。例如:int x=1;int*p=&x;cout p;/输出p的值,即变量x的地址值cout *p;/输出p所指向的变量的值,即x的值指针输出操作有一个例外,当输出字符指针(char*)时,输出的不是指针值,而是该指针所指向的字符串,例如:char str=Programmer;char*p=&str0;cout p;/输出p指向的字符串:Programmercout *p;/输出p指向的字符串:Pcout str;/输出Programmer。因为str表示数组第一个元素的地址 第56页/共96页575.7
44、.4 指向常量的指针和指针常量 指向常量的指针的定义格式如下:const *;在上面的格式中,除了const外其他的含义与通常的指针变量定义相同。其中const的含义是:指向的是一个常量,即不能够通过来修改该指针所指向的变量的值。如:const int c;const int*pc=&c;c=300;/错误*pc=400;/错误所谓指针常量是指某个指针变量的值是常量,即其对应的内存空间中存放的地址值不会被修改。如:int x,y;int*const p=&x;/定义了一个指针常量p,指向x*p=320;/修改p所指向的变量的值p=&y;/错误,p是一个常量,其值不能修改第57页/共96页585
45、.7.5 数组与指针 1指针与一维数组 由于每个数组元素也是一个变量,因此,可以使用指针变量指向数组元素,然后通过指针变量来访问数组元素,称为“指针方式”。int*p;p=&a0;/指针指向第0个元素x=*(p+3);/取指针p+3指向的内容,等价于x=a3y=*(p+4);/取指针p+4指向的内容,等价于x=a4也可以用指针和下标来访问数组元素,例如:int*p;p=&a0;/指针指向第0个元素x=p3;/取指针p+3指向的内容,等价于x=a3y=p4;/取指针p+4指向的内容,等价于x=a4 通过以上的分析,我们可以看出,若有一个数组a,指针p指向数组a的首地址,则ai、*(a+i)、*(
46、p+i)、pi都表示数组a中下标为i的元素。第58页/共96页59例数组元素的各种访问方法。#include using namespace std;int main()int a5=1,2,3,4,5;int*p,i;cout 数组名+下标:;for(i=0;i5;i+)cout ai ;cout endl;cout 数组名指针方式:;for(i=0;i5;i+)cout *(a+i);cout endl;p=a;/指针指向第0个元素cout 指针方式:;for(i=0;i5;i+)cout *(p+i);cout endl;p=&a0;/指针指向第0个元素cout 指针+下标方式:;for
47、(i=0;i5;i+)cout pi ;cout endl;第59页/共96页602一维数组作为函数参数函数的形参可以定义成一个一维数组形式,如:int fun(int a,int num).可以指定数组的元素个数,也可以不指定。编译器将a看成是一个指针,即上面的函数fun和下面的定义是相同的:int fun(int*a,int num).第60页/共96页61例 编写函数寻找计算指定数组的最大的元素值,并返回该元素的下标。#include using namespace std;/num为数组元素的个数int max(int x,int num)int i,j=0;for(i=1;ixj)j
48、=i;return j;int main()int a10=34,91,83,56,29,93,56,12,88,2;int b8=52,2,6,4,32,12,9,73,index_max;index_max=max(a,10);cout a的最大元素是:aindex_max,其下标为:index_max endl;index_max=max(b,8);cout b的最大元素是:bindex_max,其下标为:index_max endl;return 0;第61页/共96页623指针与二维数组对于如下定义的二维数组a:int a46;a0a1a2a3第0列第1列第2列第4列第3列第5列aa
49、+1a+2a+3我们可以把a看成是一个一维数组,它的元素为a0、a1、a2。a0、a1、a2又分别代表第1行、第2行、第3行的一维数组。a0a1a2a3第0列第1列第2列第4列第3列第5列aa+1a+2a+3第62页/共96页63C+规定,a0代表a00的地址,即第1行的首地址,a1代表a10的地址,即第2行的首地址,a2代表a20的地址,即第3行的首地址,a3代表a30的地址,即第4行的首地址。a代表其一维数组的首地址,即a0的地址。a指向a0,*a访问到a0,a+1指向a1,*(a+1)访问到a1,a+2指向a2,*(a+2)访问到a2,a+3指向a3,*(a+3)访问到a3。不过这里要注
50、意,a0、a1、a2、a3虽然看做是一个数组元素,但是它们都是虚拟的,不存在的,因此并不占用存储单元。第63页/共96页64例 二维数组和指针的关系。#include using namespace std;int main()int a44=1,0,0,0,2,0,0,0,3,0,0,0,4,0,0,0;cout a a+1 a+2 a+3 endl;cout *a *(a+1)*(a+2)*(a+3)endl;cout a0 a1 a2 a3 endl;cout&a00&a10&a20&a30 endl;cout *a0 *a1 *a2 *a3 endl;cout a00 a10 a20