1、第五章第五章 构造数据类型构造数据类型丘志杰丘志杰电子科技大学电子科技大学计算机学院计算机学院 软件学院软件学院枚举类型枚举类型 “枚举枚举”是指将变量所有可能的取值是指将变量所有可能的取值一一一一列举列举出来,变量的取值只限于列举出来的常出来,变量的取值只限于列举出来的常量。枚举类型的声明的一般形式如下量。枚举类型的声明的一般形式如下:当当没给各枚举常量指定值时没给各枚举常量指定值时,其值依次默认,其值依次默认为为0、1、2、;在定义枚举类型时,也可;在定义枚举类型时,也可使用赋值号另行指定枚举常量的值。使用赋值号另行指定枚举常量的值。enumenum 枚举类型名枚举类型名 枚举常量枚举常量
2、1,1,枚举常量枚举常量2,2,枚举常量枚举常量nn;枚举!枚举!例:例:Need To Do举例举例 数组数组 数组是一组在内存中数组是一组在内存中依次连续存依次连续存放放的、具有的、具有同一类型同一类型的数据变量的数据变量所组成的集合体。所组成的集合体。数组元素用数组名与带方括号的数组元素用数组名与带方括号的数组数组下标下标一起标识。一起标识。一维数组定义与使用一维数组定义与使用 一维数组定义的一般形式为:一维数组定义的一般形式为:数据类型数据类型 数组名数组名常量表达式常量表达式;说明:说明:数组元素的类型可以是数组元素的类型可以是voidvoid型以型以外的任何数据类型。外的任何数据类
3、型。数组名代表数组元素在内存中的起数组名代表数组元素在内存中的起始地址,是一个地址常量。始地址,是一个地址常量。数组定义之后,系统会将从内存中数组定义之后,系统会将从内存中为其分配为其分配一块连续的存储空间一块连续的存储空间,从第,从第1 1个数据元素开始个数据元素开始依次存放依次存放各个数组元素。各个数组元素。例如:例如:intint a5;a5;假设地址 内容 符号地址 103410A0 103410A4 103410A8 103410AC 103410B0 a a+1 a+2 a+3 a+4 5*sizeof(int)a0 a1 a2 a3 a4 一维数组的初始化一维数组的初始化 一维数
4、组初始化的语法形式为:一维数组初始化的语法形式为:数据类型数据类型 数组名数组名 常量表达式常量表达式=初初值值1,初值初值2,初值初值n;例如:例如:int array3=5,6,7;int array23=1,2;存取一维数组元素的语法形式为:存取一维数组元素的语法形式为:数组名数组名 下标表达式下标表达式;读数组元素的地址读数组元素的地址通过数组名通过数组名来读来读取,格式如下:取,格式如下:数组名数组名+整型表达式整型表达式;或&数组名数组名下标表达式下标表达式;使用数组要注意的地方使用数组要注意的地方F在使用数组时最常犯的错误是在使用数组时最常犯的错误是下标越界下标越界。F数组名是一
5、个地址常量,不能作为数组名是一个地址常量,不能作为左值左值(赋值的目标赋值的目标)。因此,不能将一个数组整体。因此,不能将一个数组整体拷贝给另外一个数组。拷贝给另外一个数组。例如:例如:intint a5,c5,i;a5,c5,i;a=c;a=c;/错误错误!正确的方法是将对应的元素进行拷贝:正确的方法是将对应的元素进行拷贝:for(ifor(i=0;i5;i+)=0;i5;i+)aiai=cici;字符数组与字符串字符数组与字符串 存放字符型数据的数组称为存放字符型数据的数组称为字符数组字符数组。1.1.用字符进行初始化用字符进行初始化 例如:例如:char s1=C,h,i,n,a;2.用
6、字符串进行初始化用字符串进行初始化 例如:例如:char s2=China;字符数组的使用字符数组的使用 字符数组也是数组,我们同样可以字符数组也是数组,我们同样可以通过数组名及下标引用数组中的元通过数组名及下标引用数组中的元素。为方便对字符与字符串的处理,素。为方便对字符与字符串的处理,C+C+提供了许多专门处理字符与字提供了许多专门处理字符与字符串的函数。符串的函数。参看参看P118表表5-1。指针指针指针是指针是C+C+语言最重要特性之一,语言最重要特性之一,也是也是C+C+的主要难点。的主要难点。指针提供了一种较为直观的指针提供了一种较为直观的地址地址操操作的手段,正确地使用指针,可以
7、作的手段,正确地使用指针,可以方便、灵活而有效地组织和表示复方便、灵活而有效地组织和表示复杂的数据。杂的数据。地址与指针地址与指针 地址:当定义一个变量后,内存中将会划地址:当定义一个变量后,内存中将会划出一块由若干个存储单元组成的区域,用于出一块由若干个存储单元组成的区域,用于保存该变量的数据。在保存该变量的数据。在内存里每个存储单元内存里每个存储单元都有各自的编号都有各自的编号,称为地址。,称为地址。指针:在指针:在C+C+中,提供了指针类型,它是一中,提供了指针类型,它是一种种用于存放内存单元地址的变量类型用于存放内存单元地址的变量类型,地址,地址就存储在这种指针类型的变量中。正因为就存
8、储在这种指针类型的变量中。正因为指指针变量存储的是地址针变量存储的是地址,用它来指明内存单元,用它来指明内存单元,所以形象地称这种地址变量为指针。所以形象地称这种地址变量为指针。指针变量的定义指针变量的定义例如:例如:int*ip;/定义了一个定义了一个int型的指针变量型的指针变量ip float*fp;/定义了一个定义了一个float型指针变量型指针变量fp typedef int A10;A*ap;/定义了一个定义了一个A类型的指针变量类型的指针变量ap sizeof(ip)=sizeof(fp)=sizeof(ap)=4;数据类型数据类型 *变量名;变量名;指针的初始化与赋值指针的初始
9、化与赋值(1)不要将一个非地址常量、变量以及无意义的实)不要将一个非地址常量、变量以及无意义的实际地址赋给指针变量。如:际地址赋给指针变量。如:int*p=100;/int*p=(int*)100;(对吗?)(对吗?)int*p=(char*)100;(2)可以使用一个已初始化的指针去给另一个指针)可以使用一个已初始化的指针去给另一个指针赋值,但类型必须一致如果不一致,可进行强制赋值,但类型必须一致如果不一致,可进行强制类型转换。类型转换。char*p=NULL;int*ip=(int*)p+100;数据类型数据类型 *指针变量名指针变量名=初始地址表达式;初始地址表达式;(3)对于基本数据类
10、型的变量、数组元素我们可以)对于基本数据类型的变量、数组元素我们可以使用取地址运算符使用取地址运算符&来获得它们的地址,但是也只来获得它们的地址,但是也只有类型一致才能赋值。有类型一致才能赋值。int a10;/定义定义int型数组型数组 int *i_pointer=a;/定义并初始化定义并初始化int型指针型指针(4)有一种特殊的)有一种特殊的void类型指针,可以存储任何的类型指针,可以存储任何的类型地址;但将一个类型地址;但将一个void类型的地址赋值给非类型的地址赋值给非void类型的指针变量,要使用类型强制转换。类型的指针变量,要使用类型强制转换。void v;/错误,不能定义错误
11、,不能定义void类型的变量类型的变量 void*vp;/定义定义void类型的指针类型的指针指针运算指针运算 指针通常进行下列几种运算:赋值运算、取指针通常进行下列几种运算:赋值运算、取值运算、算术运算、相减运算、比较运算。值运算、算术运算、相减运算、比较运算。(1 1)*和和&运算运算 *:指针运算符,:指针运算符,&:取地址运算符。:取地址运算符。例如:例如:int a4=1,2,3;int*ip=&a2;cout*ip;*ip=100;0013A000 a0=1 0013A004 a1=2 *ip 0013A008 a2=3 0013A00C a3=0 ip 0013A014 ip=0
12、013A008 (2)指针与整数的加减运算)指针与整数的加减运算 指针的指针的加减运算加减运算与普通变量的加减与普通变量的加减运算不同,由于指针存储的是变量的运算不同,由于指针存储的是变量的内存地址,指针加上或减去一个整数内存地址,指针加上或减去一个整数n n,表示指针从当前位置向后或向前,表示指针从当前位置向后或向前移动移动n n个个sizeof(数据类型)(数据类型)长度的存长度的存储单元。因此对于不同的数据类型,储单元。因此对于不同的数据类型,n n的实际大小就不同。的实际大小就不同。(3 3)指针自增、自减运算)指针自增、自减运算 指针的自增、自减运算是指针加减运算的特指针的自增、自减
13、运算是指针加减运算的特例。指针的自增或自减表示指针从当前位置例。指针的自增或自减表示指针从当前位置向后或向前移动向后或向前移动sizeof(数据类型)长度的(数据类型)长度的存储单元。存储单元。例如:例如:int*p,a=5;p=&a;p+;/指针指针p后移后移4个字节个字节(4 4)两指针相减)两指针相减 当两个指针当两个指针指向同一数组时指向同一数组时,两个指,两个指针的相减针的相减才有意义才有意义。两个指针相减的结。两个指针相减的结果为一整数,表示两个指针之间数组元果为一整数,表示两个指针之间数组元素的个数。素的个数。(5 5)两个指针的比较运算)两个指针的比较运算 两个指针的比较一般用
14、于下列两种情况:两个指针的比较一般用于下列两种情况:一是比较两个指针所指向的对象在内存一是比较两个指针所指向的对象在内存中的中的位置关系位置关系;二是判断指针是否为空;二是判断指针是否为空指针。指针。void类型指针类型指针 指向指向voidvoid类型的指针是一种类型的指针是一种不确定类型不确定类型的指针,它的指针,它可以可以指向任何类型的变量指向任何类型的变量。实际使用。实际使用voidvoid型指针时,只有通过型指针时,只有通过强强制类型转换制类型转换才能使才能使voidvoid型指针得到具体变量的值。在型指针得到具体变量的值。在没有转没有转换前换前voidvoid型指针型指针不能不能进
15、行指针的算术运算。进行指针的算术运算。例如:例如:voidvoid*vpvp;/;/定义了一个定义了一个voidvoid型指针型指针vpvp intint i=6,i=6,*ipip;vpvp=&i;/=&i;/vpvp指向整型变量指向整型变量i i coutcout“i=”“i=”*vpvpendlendl;/;/错误错误 coutcouti=i=*(intint*)p)pendlendl;ipip=(=(intint*)vpvp;/;/ipip指向指向vpvp指向的变量指向的变量i i coutcouti=i=*ipipendlendl;指针与字符串指针与字符串 字符型指针:字符型指针:用
16、于存放字符型变量的地址,而用于存放字符型变量的地址,而字符串的本字符串的本质是以质是以00结尾的字符数组结尾的字符数组,一个字符型指针存储了,一个字符型指针存储了字符数组的第一个元素的地址,也就存储了字符串字符数组的第一个元素的地址,也就存储了字符串的地址,这个指针就指向了字符串。的地址,这个指针就指向了字符串。在定义一个字符数组时,可以将一个字符串在定义一个字符数组时,可以将一个字符串常量作为初值,但将字符串常量作为初值赋给字符常量作为初值,但将字符串常量作为初值赋给字符数组和将字符串常量作为数组和将字符串常量作为初值初值赋给字符指针变量,赋给字符指针变量,二者的含义是不同的。二者的含义是不
17、同的。例如:例如:char str5=abcd;char*p_str=abcd;指针与数组指针与数组 1 1 使用指针操作符使用指针操作符*存取数组存取数组 指针的加减运算的特点指针的加减运算的特点使得指针操作符特别适使得指针操作符特别适合处理存储在合处理存储在一段连续内存空间一段连续内存空间中的同类型数据。这中的同类型数据。这样,使用指针操作符来对数组及其元素进行操作就非样,使用指针操作符来对数组及其元素进行操作就非常方便。常方便。(1)(1)一维数组的指针操作一维数组的指针操作 当定义数组一维数组当定义数组一维数组T T aNaN(T(T为类型为类型),下式为,下式为存取数组元素存取数组元
18、素aiai 的等效方式:的等效方式:*(a+ia+i);而而a+ia+i为为aiai 的地址。的地址。数组指针数组指针 数组指针是指向数组的指针。数组指针是指向数组的指针。例如:例如:intint(*a_pa_p)5;)5;等效于下列定义方式:等效于下列定义方式:typedeftypedef intint I_A5;I_A5;I_A I_A *a_pa_p;数组与函数数组与函数 数组名数组名是一个地址,不能当作一个左值,是一个地址,不能当作一个左值,但是可以作为函数的形参,接受实参传送来但是可以作为函数的形参,接受实参传送来的地址。当形参接受实参传送来的地址后,的地址。当形参接受实参传送来的地
19、址后,形参数组与实参形参数组与实参共享内存中的一块空间共享内存中的一块空间。函。函数体通过形参对数组内容的改变会直接作用数体通过形参对数组内容的改变会直接作用到实参上。数组名作为形参是数组应用的一到实参上。数组名作为形参是数组应用的一个重要方面。个重要方面。举例举例 void void func(intfunc(int a,inta,int n)n)intint i;i;for(ifor(i=0;i=0;in;in;i+)+)aiai+=3;+=3;void main()void main()intint a=1,2,3,4;a=1,2,3,4;func(a,4);func(a,4);指向函数
20、的指针指向函数的指针 在程序运行时,不仅数据要占用内存空间,程序的代在程序运行时,不仅数据要占用内存空间,程序的代码也被调入内存并占据一定的内存空间。每一个函数都有码也被调入内存并占据一定的内存空间。每一个函数都有函数名,实际上,这个函数名,实际上,这个函数名就是该函数的代码在内存的函数名就是该函数的代码在内存的起始地址起始地址。当调用一个函数时,编译系统就是根据函数名找到函当调用一个函数时,编译系统就是根据函数名找到函数代码的首地址,从而执行这段代码。由此看来,函数的数代码的首地址,从而执行这段代码。由此看来,函数的调用形式:函数名(参数表),其实质就是:调用形式:函数名(参数表),其实质就
21、是:函数代码首函数代码首地址(参数表)地址(参数表)。函数指针:函数指针:就是指向某个函数的指针,它是就是指向某个函数的指针,它是专门用于存放该函数专门用于存放该函数代码首地址的指针变量代码首地址的指针变量。一旦定义了某个函数指针,那么,。一旦定义了某个函数指针,那么,它就与函数名有同样的作用,在程序中就可以象使用函数它就与函数名有同样的作用,在程序中就可以象使用函数名一样,通过指向该函数的指针来调用该函数。名一样,通过指向该函数的指针来调用该函数。函数指针的定义语法形式如下:函数指针的定义语法形式如下:其中其中:数据类型为函数指针所指函数的返回值类型;数据类型为函数指针所指函数的返回值类型;
22、形参表则列出了该指针所指函数的形参类型形参表则列出了该指针所指函数的形参类型和个数。和个数。函数指针名与函数指针名与*外面的外面的圆括号()是必须圆括号()是必须的,的,如果去掉圆括号,将被解释为函数的返回值如果去掉圆括号,将被解释为函数的返回值为指针。为指针。数据类型数据类型 (*函数指针名)(形参表);函数指针名)(形参表);函数指针在函数指针在使用之前也要进行赋值使用之前也要进行赋值,使指针指向一,使指针指向一个已经存在的函数代码的起始地址。语法形式为:个已经存在的函数代码的起始地址。语法形式为:函数指针名函数指针名=函数名;函数名;调用函数指针指向的函数有如下两种格式:调用函数指针指向
23、的函数有如下两种格式:函数指针名函数指针名(实参表实参表);(*函数指针名函数指针名)(实参表实参表);例如:例如:intint add(intadd(int a,inta,int b);/b);/定义函数定义函数 intint(*fptr)(intfptr)(int a,inta,int b);/b);/定义函数指针定义函数指针 fptrfptr=add;/=add;/函数指针赋值函数指针赋值 采用下列任何一种形式调用函数采用下列任何一种形式调用函数add:add:add(1,2);add(1,2);(*fptr)(1,2);fptr)(1,2);fptr(1,2);fptr(1,2);F说
24、明说明:虽然三种调用形式的结果完全相同,当用指虽然三种调用形式的结果完全相同,当用指向函数的指针调用函数向函数的指针调用函数add()add()时,习惯上使用时,习惯上使用(*fptr)(1,2)fptr)(1,2),因为这种形式能更直观地说,因为这种形式能更直观地说明是用指向函数的指针来调用函数。明是用指向函数的指针来调用函数。多重指针多重指针 如果已经定义了一个指针类型,我们再如果已经定义了一个指针类型,我们再定义一个指针,用于指向已经定义的指针变定义一个指针,用于指向已经定义的指针变量,后面定义的指针变量就是一个指向指针量,后面定义的指针变量就是一个指向指针的指针变量,简称的指针变量,简
25、称指向指针的指针指向指针的指针,这样的,这样的指针也称指针也称二重二重(级级)指针指针。三重及以上三重及以上的指针统称为的指针统称为多重指针多重指针。例如:例如:int*pp;定义了一个二级指针变量,等效于下列定义方式:定义了一个二级指针变量,等效于下列定义方式:typedef int*P;P *p;例:例:intint a,a,*p,p,*pp;pp;p=&a;pp=&p;2023-1-2732动态存储分配和释放存储空间动态存储分配和释放存储空间C的做法的做法void*malloc(size_t size);voidfree(void*pMemory);例如:例如:char*p=(char*
26、)malloc(100);strcpy(p,”Hello World!”);free(p);2023-1-2733C+的做法的做法使用运算符使用运算符new和和delete使用形式使用形式 type是一个数据类型名,是一个数据类型名,p是该类型的指针变量,是该类型的指针变量,new的作用就是从堆空间中分配一块与的作用就是从堆空间中分配一块与type类型的类型的数据一样大小的内存(如果分配失败,数据一样大小的内存(如果分配失败,new返回一返回一个空指针),该内存地址被存于指针个空指针),该内存地址被存于指针p中。一旦不想中。一旦不想再使用,可以用再使用,可以用delete来释放该内存空间。来释
27、放该内存空间。type*p;p=new type;delete p;2023-1-2734举例举例int*p;p=new int;*p=50;delete p;2023-1-2735几点注意几点注意 使用使用new申请的内存空间是没有名字的,申请的内存空间是没有名字的,只能通过指针间接访问它们。只能通过指针间接访问它们。用用delete释放的内存空间必须是由释放的内存空间必须是由new分配的空间,否则执行分配的空间,否则执行delete时时将会导致严重的错误。例如:将会导致严重的错误。例如:int*p;delete p;/出错出错int*p,value;p=&value;delete p;/出
28、错出错2023-1-2736new和和delete的典型用法的典型用法 动态分配和释放单个数据的存储区动态分配和释放单个数据的存储区#include void main()int*p;p=new int;if(p=NULL)cout“Allocation failure!n”;else*p=15;cout*p;delete p;2023-1-2737用用new运算符初始化单个数据的存储区运算符初始化单个数据的存储区 语法为:语法为:type*p;P=new type(初始值初始值);delete p;几点说明:几点说明:是用是用小括号小括号将初始值括起来。将初始值括起来。初始值可以是常量、变量
29、、以及表达式。初始值可以是常量、变量、以及表达式。2023-1-2738 举例举例#include void main()int*p;p=new int(100);if(p=NULL)cout“Allocation failure!n”;elsecout*p;delete p;/如果如果p=new int(98.5),会怎么样?,会怎么样?注意:初始值必须与相应类型一致。注意:初始值必须与相应类型一致。2023-1-2739动态分配一维数组的存储空间动态分配一维数组的存储空间 语法为:语法为:type*p;P=new typenum;delete p;几点说明:几点说明:num用于指定数组大小
30、,可以是常量、变用于指定数组大小,可以是常量、变量、以及表达式,并且用中括号括起来。量、以及表达式,并且用中括号括起来。通过通过pi的方式访问数组元素。的方式访问数组元素。2023-1-2740#include void main()int i,*p;p=new int100;if(p=NULL)cout“Allocation failure!n”;elsefor(i=0;i 100;i+)pi=i+1;for(i=0;i 100;i+)coutpi;delete p;2023-1-2741 几点说明:几点说明:new返回的指针指向数组的起始位置,也返回的指针指向数组的起始位置,也就是数组的第
31、一个元素。就是数组的第一个元素。用用new动态分配一个数组时不能对它进行动态分配一个数组时不能对它进行初始化。初始化。(呵呵,为什么?)(呵呵,为什么?)2023-1-2742引用引用 Reference简单地说,引用就是给一个单元起一个别简单地说,引用就是给一个单元起一个别名。也就是说,引用与它所引用的变量共名。也就是说,引用与它所引用的变量共享存储单元。享存储单元。引用主要有以下三种用法引用主要有以下三种用法:独立引用独立引用作为函数参数作为函数参数作为函数返回类型作为函数返回类型2023-1-2743独立引用独立引用int i=0,k=8;int&j=i;int*p=&i;j=k;j是是
32、i的引用,的引用,i和和j是代表同一个单元。是代表同一个单元。这种这种使用引用的方式称为独立引用。使用引用的方式称为独立引用。在声明独立引用时必须对它初始化,这种情况在声明独立引用时必须对它初始化,这种情况下的别名绑定是永久的。下的别名绑定是永久的。语句语句”j=k;”不是试图使不是试图使j成为成为k的别名,而是的别名,而是在给在给j赋值,即使赋值,即使j的值也就是的值也就是i的值等于的值等于k。2023-1-2744初始化独立引用的几种方式初始化独立引用的几种方式赋值表达式的右端是一个变量赋值表达式的右端是一个变量int a;int&ra=a;赋值表达式的右端是一个常量赋值表达式的右端是一个
33、常量float&r1=1.0;/早期的早期的C+版本版本const float&r2=1.0;/近期近期C+版本版本定义常引用定义常引用int x=1;const int&rx=x;rx=98;/错误,只能使用错误,只能使用rx,不能修改不能修改2023-1-2745引用作为函数参数引用作为函数参数 C+和和C一样一样,都是采用都是采用“传值传值”的方式向函数传递参数,从而使的方式向函数传递参数,从而使实际参数和形式参数相结合的。实际参数和形式参数相结合的。在这种情况下,实参和形参是两在这种情况下,实参和形参是两个不同的单元,在结合时,实参个不同的单元,在结合时,实参的值将会被拷贝到形参中。的
34、值将会被拷贝到形参中。2023-1-2746C+函数的传值调用函数的传值调用void func(int num)num+;void main()int value=5;func(value);cout value;/输出:输出:5由于由于“传值传值”方式的存在,方式的存在,因此试图通过改变形参来改因此试图通过改变形参来改变实参的努力是不会成功的。变实参的努力是不会成功的。2023-1-2747通过传地址来改变实参通过传地址来改变实参 为了解决上述问题,在为了解决上述问题,在C语言语言中,可以通过中,可以通过传递指针传递指针的方的方式来完成。我们可以通过形式来完成。我们可以通过形参指针参指针间接
35、间接地改变实参。地改变实参。2023-1-2748C语言的传指针调用语言的传指针调用void func(int*pnum)(*pnum)+;void main()int value=5;func(&value);cout value;/输出:输出:6此时实参与形参的传递为:此时实参与形参的传递为:int*pnum=&value;2023-1-2749C+传递引用的方式传递引用的方式 C+采用了比传递指针更好的方式:采用了比传递指针更好的方式:传递引用传递引用。在这种情况下,形参的。在这种情况下,形参的名字将被看作是实参的名字将被看作是实参的别名别名(同独(同独立引用的情况一样),也就是说,立引
36、用的情况一样),也就是说,形参就是实参本身。此时对形参的形参就是实参本身。此时对形参的改变也就改变也就直接直接改变了实参。改变了实参。2023-1-2750C+语言的引用调用语言的引用调用void func(int&pnum)pnum+;void main()int value=5;func(value);cout value;/输出:输出:6此时实参与形参的传递为:此时实参与形参的传递为:int&pnum=value;2023-1-2751引用作为函数的返回引用作为函数的返回 函数返回引用,实际上返回的是一个函数返回引用,实际上返回的是一个存储单元(变量),即存储单元(变量),即“左值左值”
37、。因。因此,如果一个函数返回引用,那么函此,如果一个函数返回引用,那么函数调用可以出现在赋值号的左边。这数调用可以出现在赋值号的左边。这种情况在种情况在C语言里是见不到的。语言里是见不到的。值得注意的是,因为返回的引用是一值得注意的是,因为返回的引用是一个存储单元,所以函数返回后这个单个存储单元,所以函数返回后这个单元的生命期应该不会结束,否则返回元的生命期应该不会结束,否则返回值将没有意义。值将没有意义。2023-1-2752举例举例int&f(int*pint)return*pint;void main()int a=10,b;b=f(&a)*5;f(&a)=88;coutb“a;/输出:
38、50 88结构与联合结构与联合 数组是由数组是由类型相同类型相同的数据元素构成的。然而,程的数据元素构成的。然而,程序中往往需要处理一些由不同类型数据元素所构成序中往往需要处理一些由不同类型数据元素所构成的数据。的数据。例如,一个学生的基本情况由学号、姓名、性别、例如,一个学生的基本情况由学号、姓名、性别、出生日期、成绩等数据元素构成,这些数据元素具出生日期、成绩等数据元素构成,这些数据元素具有不同的数据类型,如果使用独立的不同数据类型有不同的数据类型,如果使用独立的不同数据类型的变量来描述这些信息,那么,变量之间的关系不的变量来描述这些信息,那么,变量之间的关系不能体现出来。能体现出来。C+
39、C+也提供了描述不同数据类型的组合也提供了描述不同数据类型的组合体的方法:体的方法:结构和联合。结构和联合。结构结构 结构类型将不同数据类型组合成一个整结构类型将不同数据类型组合成一个整体类型,是一种体类型,是一种“用户自定义构造数据类用户自定义构造数据类型型”。定义结构类型的格式如下:定义结构类型的格式如下:struct 结构类型名结构类型名 数据类型数据类型1 成员名成员名1;数据类型数据类型2 成员名成员名2;数据类型数据类型 n 成员名成员名n;联合联合 联合类型联合类型提供了一种可以将几种不同类型数据提供了一种可以将几种不同类型数据存放于同一段内存,对其中各个成员可以存放于同一段内存,对其中各个成员可以按名存按名存取取的机制。联合类型定义的语法形式为:的机制。联合类型定义的语法形式为:union 联合类型名联合类型名 数据类型数据类型1 成员名成员名1;数据类型数据类型2 成员名成员名2;数据类型数据类型 n 成员名成员名n;