1、第四章第四章 构造型数据类型构造型数据类型 4.1 4.1 数组数组4.2 4.2 结构体结构体 4.34.3共用体共用体 4.4 4.4 枚举型枚举型 4.5 typedef4.5 typedef的用途的用途 4.6 4.6 小结小结 习题习题 前面章节介绍了语言中的基本数据类型前面章节介绍了语言中的基本数据类型(整型、字符型、实整型、字符型、实型型),本章将介绍语言中的构造型数据类型数组、结构体、共本章将介绍语言中的构造型数据类型数组、结构体、共用体等。讲述一维数组和多维数组的定义、初始化和使用;字符用体等。讲述一维数组和多维数组的定义、初始化和使用;字符串与字符数组的概念;结构体和共用体
2、类型变量的定义方法和使串与字符数组的概念;结构体和共用体类型变量的定义方法和使用方法,结构体和共用体的嵌套使用;枚举型的概念以及用用方法,结构体和共用体的嵌套使用;枚举型的概念以及用typedef定义类型名。建议本章授课定义类型名。建议本章授课8学时,上机学时,上机6学时,自学学时,自学10学时。学时。返回目录返回目录4.1 数组教学内容:教学内容:4.1.1 一维数组一维数组 4.1.2 字符数组字符数组 4.1.3 二维数组二维数组 返回目录返回目录 数组是最简单、最常用的构造型数据类型,它由若干个类数组是最简单、最常用的构造型数据类型,它由若干个类型相同的元素组成,每个元素就是一个变量,
3、每个数组都有一个名型相同的元素组成,每个元素就是一个变量,每个数组都有一个名字称为数组名。数组可以是一维的、也可以是多维的。语言中数字称为数组名。数组可以是一维的、也可以是多维的。语言中数组元素的个数必须在定义数组时就确定,不是可调数组。组元素的个数必须在定义数组时就确定,不是可调数组。返回目录返回目录4.1.1 一维数组教学内容:教学内容:数组概念的引入数组概念的引入 一维数组的定义一维数组的定义 一维数组元素的使用一维数组元素的使用 数组元素的初始化数组元素的初始化 初始化时不指定数组长度初始化时不指定数组长度 一维数组程序举例一维数组程序举例 返回目录返回目录数组概念的引入数组概念的引入
4、 从以下的问题中,可以看到引入数组的必要性。键盘读入从以下的问题中,可以看到引入数组的必要性。键盘读入100个实数个实数a1,a2,.,a100。输出。输出(a1+a100)/2.0,(a2+a99)/2.0,.,(a50+a51)/2.0。可以先把这。可以先把这100个实数存放在个实数存放在100实型变实型变量中。为此定义量中。为此定义100实型变量实型变量f0,f1,.f99分别存放这分别存放这100个个实数,程序如下实数,程序如下 scanf(%f,&f0);scanf(%f,&f1);scanf(%f,&f99);prinft(%f,(f0+f99)/2.0);prinft(%f,(f
5、1+f98)/2.0);prinft(%f,(f49+f50)/2.0);返回目录返回目录 上述程序十分重复、繁琐。为了简化这一程序,引入数组概上述程序十分重复、繁琐。为了简化这一程序,引入数组概念,将这念,将这100个实型变量写成个实型变量写成f0,f1,.,f99,它们都有相,它们都有相同的数组名同的数组名f,其中方括号中的数字称为数组下标,数组下标可以,其中方括号中的数字称为数组下标,数组下标可以用整型变量或整型表达式来表示。设用整型变量或整型表达式来表示。设i为整型变量,当为整型变量,当i=0时时fi就就代表代表f0,.,.,当当i=99时时fi就代表就代表f99。因此,上述程序简化为
6、因此,上述程序简化为:for(i=0;i100;i+)scanf(%f,&fi);for(i=0;i50;i+)prinft(“%f,”,(fi+f99-i)/2.0);可见,引入数组之后,程序变得非常简练。本章讲述的排序可见,引入数组之后,程序变得非常简练。本章讲述的排序和查找等程序设计算法,不使用数组就无法进行。程序设计语言和查找等程序设计算法,不使用数组就无法进行。程序设计语言中,数组是必不可少的重要数据类型。中,数组是必不可少的重要数据类型。返回目录返回目录一维数组的定义一维数组的定义 一维数组是指数组元素只有一个下标的数组。定义一维数组一维数组是指数组元素只有一个下标的数组。定义
7、一维数组的一般格式如下:的一般格式如下:类型名数组名类型名数组名整型常量表达式整型常量表达式,.;类型名即数据类型标识符,是每一个数组元素的数据类型,可类型名即数据类型标识符,是每一个数组元素的数据类型,可以是整型、实型、字符型、指针类型、结构体和共用体等。整型以是整型、实型、字符型、指针类型、结构体和共用体等。整型常量表达式的值就是该数组元素的个数。例如下述定义:常量表达式的值就是该数组元素的个数。例如下述定义:int a10;这条定义语句说明了:这条定义语句说明了:()定义了一个名为()定义了一个名为a的一维数组。的一维数组。()方括号中的()方括号中的10规定了规定了a数组有数组有10个
8、元素,它们是个元素,它们是a0、a1、a2、.、a9。()类型名()类型名int规定了规定了a数组的每个元素都是整型变量。数组的每个元素都是整型变量。返回目录返回目录()每个元素只有一个下标,因此数组()每个元素只有一个下标,因此数组a是一维数组。是一维数组。C语言规定语言规定 数组的第一个元素的数组下标(数组下标的下界)是数组的第一个元素的数组下标(数组下标的下界)是0。在。在 语言中一个数组最后一个元素的下标语言中一个数组最后一个元素的下标(数组下标的上界数组下标的上界)是:数是:数 组元素的个数减。例如上述组元素的个数减。例如上述a数组下标的上界为数组下标的上界为9,则最后,则最后 一个
9、元素为一个元素为a9。()系统将为()系统将为a数组在内存中分配一块数组在内存中分配一块20个字节的连续存储单元,个字节的连续存储单元,每个元素(每个元素(int类型)占个字节,类型)占个字节,a0元素分配的单元地址最元素分配的单元地址最 低,低,a9元素分配的单元地址最高,如图元素分配的单元地址最高,如图4.1所示。所示。一条语句中,可以定义多个数组,也可以在定义普通变量名的一条语句中,可以定义多个数组,也可以在定义普通变量名的同时定义数组。例如:同时定义数组。例如:floatx1,y100,x2,z10;以上语句定义了两个单精度实型变量以上语句定义了两个单精度实型变量x1与与x2,同时还定
10、义了,同时还定义了两个单精度实型数组两个单精度实型数组y与,其中与,其中y数组包含数组包含100个元素,它们是个元素,它们是y0y99;数组包含;数组包含10个元素,它们是个元素,它们是z0z9。返回目录返回目录一维数组元素的使用一维数组元素的使用 数数组组定定义义后后,就就可可以以在在程程序序中中使使用用数数组组元元素素,一一维维数数组组元元素素的使用格式如下的使用格式如下 数组名数组名下标表达式下标表达式 此此处处下下标标表表达达式式可可以以是是整整型型常常量量表表达达式式或或整整型型表表达达式式。例例如如有如下定义语句:有如下定义语句:float f10;设设变变量量i,j均均为为整整型
11、型变变量量,则则对对数数组组f的的元元素素合合法法的的使使用用形形式式可可以以是是f0,f1,.,f9,fi,fi+j,fi-5等等,程程序序中中可可以以象象使用变量一样使用这些元素。例如下述语句都是正确的:使用变量一样使用这些元素。例如下述语句都是正确的:scanf(%f%f,&f3,&f5);f1=(f3+f5)/5.0;printf(%fn,f1);由于定义数组由于定义数组f有有10个元素,因此下标表达式的值必须大于个元素,因此下标表达式的值必须大于等于等于0,并且小于等于,并且小于等于9。返回目录返回目录使用数组元素应该注意:使用数组元素应该注意:()系统在内存中为数组分配一块连续的存
12、储单元,最低的地址()系统在内存中为数组分配一块连续的存储单元,最低的地址对应于第一个数组元素,对应于第一个数组元素,.,最高的地址对应最后一个数,最高的地址对应最后一个数组元素。每个数组元素都等同于一个变量,使用数组元素就组元素。每个数组元素都等同于一个变量,使用数组元素就可以存取这些存储单元内的数据,就象存取变量的值一样。可以存取这些存储单元内的数据,就象存取变量的值一样。()()C语言中,不能对一个数组整体赋值。例如若有下述程序语言中,不能对一个数组整体赋值。例如若有下述程序段,段,inta10,b10,i;for(i=0;i10;i+)scanf(%d,&ai);则语句:则语句:b=a
13、是非法的,要把;是非法的,要把a数组元素赋值给下标对应的数组元素赋值给下标对应的b数组元素可用如下语句:数组元素可用如下语句:for(i=0;iaj+1ajaj+1,则交换,则交换ajaj与与aj+1aj+1,否则不交换,否则不交换,j=0j=0,1 1,2 2,.,n-2n-2,经过这样,经过这样n-1n-1次比较(称为次比较(称为一趟冒泡),就把一趟冒泡),就把a0a0an-1an-1中最大的值换到了元素中最大的值换到了元素an-1an-1中;中;然后在然后在a0a0an-2an-2的范围内再进行一趟冒泡,又将该范围内元的范围内再进行一趟冒泡,又将该范围内元素的最大值换到了元素素的最大值
14、换到了元素an-2an-2中;依次进行下去,最多只要进行中;依次进行下去,最多只要进行n-1n-1趟冒泡,就可完成排序。如果在某趟冒泡过程中没有交换相邻趟冒泡,就可完成排序。如果在某趟冒泡过程中没有交换相邻元素的值,则说明排序已完成,可以提前结束处理。如元素的值,则说明排序已完成,可以提前结束处理。如图图4 4.2 2所示,所示,是一个冒泡排序的例子,图中用花括号表示每趟冒泡的范围。是一个冒泡排序的例子,图中用花括号表示每趟冒泡的范围。返回目录返回目录返回目录返回目录根据上述算法,写出程序如下:根据上述算法,写出程序如下:main()inti,j,a8,temp,swap;/*变量变量swap
15、用于判定本趟冒泡是否交换了元素值用于判定本趟冒泡是否交换了元素值*/printf(请输入请输入8个整数:个整数:);for(i=0;i8;i+)scanf(%d,&ai);for(i=0;i8-1;i+)swap=0;for(j=0;jaj+1)swap=1;temp=aj;aj=aj+1;aj+1=temp;if(!swap)break;printf(8个数排序后的结果为:个数排序后的结果为:);for(i=0;iaj则将则将j值赋给值赋给k(即即k总是记录着值最小的元素下标总是记录着值最小的元素下标),每进行一次比较,每进行一次比较,j加;当加;当jn-1时,若时,若ki则交换则交换ai与
16、与ak。返回目录返回目录 显然选择排序法对冒泡排序法进行了改进,它减少显然选择排序法对冒泡排序法进行了改进,它减少了元素之间交换数据的次数。了元素之间交换数据的次数。如如图图4.3.3所示,是一个选择排序的例子,图中用花所示,是一个选择排序的例子,图中用花括号表示每次选择的范围。括号表示每次选择的范围。返回目录返回目录根据上述算法,写出程序如下:根据上述算法,写出程序如下:main()inti,j,k,a8,temp;printf(请输入请输入8个整数个整数:);for(i=0;i8;i+)scanf(%d,&ai);for(i=0;i8-1;i+)k=i;for(j=i+1;jaj)k=j;
17、if(k!=i)temp=ai;ai=ak;ak=temp;printf(8个数排序后的结果为个数排序后的结果为:);for(i=0;iamid,说明待查元素可能在,说明待查元素可能在amid+1ahigh之间,之间,可令可令low=mid+1。()若()若x=alow&x=ahigh)/*如果如果x位于查找区间内,则开始查找位于查找区间内,则开始查找*/while(!found&lowamid)low=mid+1;elsehigh=mid-1;if(found)printf(元素值为元素值为%d的数组下标是的数组下标是%d。n,x,mid);elseprintf(未找到。未找到。n);运行结
18、果:运行结果:请输入查找数据:请输入查找数据:26 元素值为元素值为 26 的数组下标是的数组下标是 4。返回目录返回目录4.1.2 字符数组字符数组教学内容:教学内容:字符数组的定义字符数组的定义 字符数组的初始化字符数组的初始化 3给字符数组元素逐个赋字符值给字符数组元素逐个赋字符值 利用库函数利用库函数strcpy给字符数组赋字给字符数组赋字 符串符串 5字符数组的输入输出字符数组的输入输出 返回目录返回目录 语言中没有字符串类型的变量,字符串的存储有两种方语言中没有字符串类型的变量,字符串的存储有两种方式,一是把字符串存储在一个字符数组中,第二种方法是利用指针式,一是把字符串存储在一个
19、字符数组中,第二种方法是利用指针处理字符串常量(详见第五章)。本节介绍使用字符数组来处理字处理字符串常量(详见第五章)。本节介绍使用字符数组来处理字符串的方法。符串的方法。返回目录返回目录字符数组的定义字符数组的定义 字字符符数数组组的的每每个个元元素素存存放放一一个个字字符符,其其定定义义方方法法与与定定义义一一个个一维数组相同:一维数组相同:char数组名数组名整型常量表达式整型常量表达式,.;例如:例如:charstr15;此语句定义了一个有此语句定义了一个有15个元素的字符数组个元素的字符数组str。字符数组的初始化字符数组的初始化()字符数组逐个元素赋初值()字符数组逐个元素赋初值
20、这种情况与一般的数组赋初值方法相同。例如:这种情况与一般的数组赋初值方法相同。例如:chars=H,e,l,l,o,!,0;上述语句等同于:上述语句等同于:chars7=H,e,l,l,o,!,0;()在赋初值时直接赋字符串常量()在赋初值时直接赋字符串常量可以直接用字符串常量给一维字符数组赋初值。例如:可以直接用字符串常量给一维字符数组赋初值。例如:chars=Hello!;返回目录返回目录赋赋初初值值时时,若若不不给给定定数数组组元元素素的的个个数数,系系统统将将按按字字符符串串中中实实际际的的字字符符个个数数来来定定义义数数组组的的大大小小。上上述述语语句句等等同同于于:chars7=H
21、ello!;即即用用字字符符串串常常量量给给字字符符数数组组赋赋初初值值时时,系系统统自自动动在在最最后后补补上上字字符符串串结结束束标标志志0,所所以以不不必必人人为为加加入入。也也可可以以省省略略花花括号,简写成:括号,简写成:chars=Hello!;这里字符数组这里字符数组s的内容如的内容如图图4.5所示。所示。返回目录返回目录 用字符串常量直接给字符数组赋初值,应注意字符数组要有用字符串常量直接给字符数组赋初值,应注意字符数组要有足够的存储单元存储字符串。例如:足够的存储单元存储字符串。例如:char str6=“Hello!”;该语该语句定义了一个有个元素的字符数组句定义了一个有个
22、元素的字符数组str,但是字符串常量,但是字符串常量“Hello!”包括了字符串结束标志包括了字符串结束标志0,要占用,要占用7个存储单元,个存储单元,个单元空间不够用,个单元空间不够用,0将占用下一个不属于字符数组将占用下一个不属于字符数组str的的存储单元,会破坏其它内存单元的数据或程序代码。存储单元,会破坏其它内存单元的数据或程序代码。3给字符数组元素逐个赋字符值给字符数组元素逐个赋字符值 定义了一个字符数组后,就可以对其元素赋值。例如:定义了一个字符数组后,就可以对其元素赋值。例如:chars9;s0=H;s1=e;s2=l;s3=l;s4=o;s5=!;上述语句把上述语句把6个字符存
23、入了字符数组个字符存入了字符数组s,如,如图图4.6所示。所示。返回目录返回目录 以以上上字字符符数数组组s中中存存放放了了6个个字字符符,并并不不等等同同于于s中中存存放放了了字字符符串串“Hello!”。因因为为语语言言规规定定字字符符串串要要以以字字符符串串结结束束标标志志0结结束束。上上面面若若加加上上s6=0;则则才才是是把把字字符符串串“Hello!”存存入入字字符符数数组组s中中。因因此此,用用字字符符数数组组来来存存放放字字符符串串时时,若若是是逐逐个个字字符符赋赋值值给给数数组组元元素素,要要在在最最后后一一个个字字符符之之后后加加上上字字符符串串结结束束标标志志0。用用逐逐
24、个个字字符符给给字字符符数数组组赋赋值值,存存储储字字符符串串,操操作作起起来来很很不不方方便便。语语言言提提供供了了专专门门用用于于处处理理字字符符串串的的各各种种库库函函数数。利利用用字字符符串串处处理理函函数数,可可以以方方便便地地将将字字符串存入字符数组、以及输入、输出字符串。符串存入字符数组、以及输入、输出字符串。返回目录返回目录利用库函数利用库函数strcpy给字符数组赋字符串给字符数组赋字符串(1)不能用赋值语句把字符串整体赋值给字符数组)不能用赋值语句把字符串整体赋值给字符数组在在语语言言中中,不不能能用用赋赋值值语语句句把把字字符符串串整整体体赋赋值值给字符数组。例如:给字符
25、数组。例如:chars130,s230,s3=GoodMorning!;s1=Hello!;s2=s3;以上两句赋值语句都是非法的。第一个赋值语句以上两句赋值语句都是非法的。第一个赋值语句相当于把字符串相当于把字符串“Hello!”的首地址赋值给的首地址赋值给s1,第二,第二个赋值语句相当于把数组个赋值语句相当于把数组s3的首地址赋值给的首地址赋值给s2,但,但s1和和s2都是数组的首地址,是地址常量,不能被赋值。都是数组的首地址,是地址常量,不能被赋值。返回目录返回目录()()利用库函数利用库函数strcpy给字符数组赋字符串给字符数组赋字符串可可以以方方便便地地利利用用库库函函数数strc
26、py把把字字符符串串存存入入字字符符数数组组,函函数数strcpy的调用形式为:的调用形式为:strcpy(字符数组字符数组1,字符串,字符串);strcpy的的作作用用是是将将字字符符串串复复制制到到字字符符数数组组1中中,复复制制时时将将字字符符串串2后后面面的的字字符符串串结结束束标标志志0也也复复制制到到字字符符数数组组中中。例例如如下下面的程序段:面的程序段:charstr130,str230,str3=Howareyou.;strcpy(str1,str3);/*将将字字符符串串Howareyou.存存入入字字符符数数组组str1中中*/strcpy(str2,Howdoyoudo
27、);/*将将字字符符串串Howdoyoudo.存入字符数组存入字符数组str2中中*/使用函数使用函数strcpy应该注意字符数组应该注意字符数组1必须定义的足够大,以必须定义的足够大,以便可以容纳得下被复制的字符串。定义字符串数组便可以容纳得下被复制的字符串。定义字符串数组1时时,其元素个其元素个数至少应该比字符串的长度多数至少应该比字符串的长度多1,应该留有存放字符串结束标,应该留有存放字符串结束标志志0的元素。的元素。返回目录返回目录5字符数组的输入输出字符数组的输入输出 在程序中可以逐个输入输出数组元素。也可以利用系统提供的在程序中可以逐个输入输出数组元素。也可以利用系统提供的字符串
28、处理函数,整体输入输出字符数组中的字符串。第二章介绍的字符串处理函数,整体输入输出字符数组中的字符串。第二章介绍的printf、scanf、getchar、putchar、getch 、getche等库函数均等库函数均可用来输入、输出字符和字符串。另外,第六章还将讲述其它的字符可用来输入、输出字符和字符串。另外,第六章还将讲述其它的字符串处理函数,如串处理函数,如gets与与puts等函数。等函数。()将字符数组中的字符串逐个字符输入输出()将字符数组中的字符串逐个字符输入输出在标准输入输出函数在标准输入输出函数printf和和scanf中使用中使用c格式格式 说明符。说明符。使用使用getc
29、har、putchar、getch和和getche函数。函数。()字符串整体输入输出()字符串整体输入输出 在标准输入输出函数在标准输入输出函数printf和和scanf中使用中使用s格式格式 说明符。说明符。使用使用getsgets和和putsputs函数输入输出一行(详见第六函数输入输出一行(详见第六 章)。章)。返回目录返回目录例例4.4由键盘输入两个字符串,比较它们的大小。本例完成与库函数由键盘输入两个字符串,比较它们的大小。本例完成与库函数strcmp(详见第六章)类似的功能。语言中字符串比较规则与其它语(详见第六章)类似的功能。语言中字符串比较规则与其它语言相同,即对两个字符串从左
30、到右逐个字符(按言相同,即对两个字符串从左到右逐个字符(按ASCII码值大小)相比较,码值大小)相比较,直到出现第一个不同的字符或遇到直到出现第一个不同的字符或遇到0为止。若全部字符相等,则认为止。若全部字符相等,则认为两字符串相等;否则比较结果以第一个不相同的字符为准。为两字符串相等;否则比较结果以第一个不相同的字符为准。main()chars1300,s2300;intresult,i=0;printf(请输入两个字符串:请输入两个字符串:);scanf(%s%s,s1,s2);while(s1i&s2i&s1i=s2i)i+;result=s1i-s2i;printf(字符串字符串%s,
31、s1);if(result=0)printf(等于等于);elseif(result0)printf(大于大于);elseprintf(小于小于);printf(字符串字符串%sn,s2);返回目录返回目录运行结果:运行结果:请输入两个字符串:请输入两个字符串:abcDxyzabcd字符串字符串abcDxyz小于小于字符串字符串abcd 上上例例把把字字符符串串2插插入入到到字字符符串串1中中第第i个个开开始始的的位位置置上上。例例如如:字字符符串串为为abcde,字字符符串串2为为4k3y,i=3,则则插插入入后后,字字符符串串变成变成ab4k3ycde。解解题题思思路路:先先求求出出字字符
32、符串串的的长长度度len2,然然后后把把字字符符串串从从最最后后一一个个字字符符开开始始后后移移len2个个元元素素,依依次次移移动动元元素素,一一直直到到第第i个个字字符符后后移移len2个个元元素素,这这样样字字符符串串就就留留出出len2个个元元素素的的空空间间,然然后后把把字字符符串串插插入入到到该该空空间间中中,并并在在最最后后加加上上字字符符串串结结束束标标志志0,如如图图4.7。返回目录返回目录返回目录返回目录#defineN100main()chars1N,s2N;inti,j,pos,len1=0,len2=0;printf(请输入字符串请输入字符串1、字符串、字符串2以及插
33、入位置:以及插入位置:);scanf(%s%s%d,s1,s2,&pos);while(s1len1)len1+;/*求出字符串求出字符串1的长度的长度*/while(s2len2)len2+;/*求出字符串求出字符串2的长度的长度*/if(poslen1+1|len1+len2N)printf(不能作插入操作。不能作插入操作。n);elsefor(i=len1-1;i=pos-1;i-)s1i+len2=s1i;/*s1i后移到后移到s1i+len2处处*/for(i=0;ilen2;i+)s1pos-1+i=s2i;/*把字符串把字符串2插入到字符串插入到字符串1中空出的位置中中空出的位置
34、中*/s1len1+len2=0;/*写入字符串结束标志写入字符串结束标志*/printf(插入后字符串插入后字符串1变成:变成:%sn,s1);运行结果:运行结果:请输入字符串请输入字符串1、字符串、字符串2以及插入位置:以及插入位置:abcde4k3y3插入后字符串插入后字符串1变成:变成:ab4k3ycde 返回目录返回目录4.1.3 二维数组二维数组教学内容:教学内容:二维数组的定义二维数组的定义二维数组元素的使用二维数组元素的使用 二维数组的初始化二维数组的初始化 二维数组程序举例二维数组程序举例 返回目录返回目录 二维数组的定义二维数组的定义 二维数组的每个元素带有两个下标,在语言
35、中,二维数组二维数组的每个元素带有两个下标,在语言中,二维数组的定义形式如下:的定义形式如下:类型名类型名数组名数组名整型常量表达式整型常量表达式整型常量表达式整型常量表达式;类类型型名名是是每每一一个个数数组组元元素素的的数数据据类类型型。实实际际上上二二维维数数组组元元素素组组成成了了一一个个矩矩阵阵,整整型型常常量量表表达达式式1的的值值就就是是该该矩矩阵阵的的行行数数,第第一一维维下下标标值值的的上上限限为为:整整型型常常量量表表达达式式1-1;整整型型常常量量表表达达式式的的值值就就是是该该矩矩的的阵阵列列数数,第第二二维维下下标标值值的的上上限限为为:整整型型常常量量表表达达式式2
36、1;语语言言中中数数组组下下标标的的下下限限均均为为,因因此此,二二维维数数组组元元素素的的个个数数为:常量表达式为:常量表达式1常量表达式。例如有下述定义:常量表达式。例如有下述定义:int a34;返回目录返回目录这就定义了一个三行四列的矩阵,共个数组元素:这就定义了一个三行四列的矩阵,共个数组元素:第列第列第列第列第列第列第列第列第第0行行a00,a01,a02,a03,第第1行行a10,a11,a12,a13,第第2行行a20,a21,a22,a23 a 是二维数组名。是二维数组名。int是类型名,表示是类型名,表示a数组的每个元素均为数组的每个元素均为整型变量。每个元素有两个下标,
37、第一个方括号中的下标代表行整型变量。每个元素有两个下标,第一个方括号中的下标代表行号,称行下标,也称为第一维下标;第二个方括号中的下标代表号,称行下标,也称为第一维下标;第二个方括号中的下标代表列号,称列下标,也称为第二维下标。例如:元素列号,称列下标,也称为第二维下标。例如:元素a02的行下的行下标为标为0,列下标为,列下标为2,它的位置在第,它的位置在第0行,第行,第2列。列。C语言中,可以把一个二维数组看成是一个一维数组,这个语言中,可以把一个二维数组看成是一个一维数组,这个一维数组的每个元素又是一维数组。例如以上二维数组一维数组的每个元素又是一维数组。例如以上二维数组a可以看可以看成是
38、由成是由a0、a1、a2三个元素组成的一维数组;其中每个元素三个元素组成的一维数组;其中每个元素又是一个包含了四个整型元素的一维数组。例如:又是一个包含了四个整型元素的一维数组。例如:a0可看是由可看是由a00,a01,a02,a03四个元素组成的一维数组。四个元素组成的一维数组。返回目录返回目录系统为二维数组在内存中分配一块连续的存储单元,系统为二维数组在内存中分配一块连续的存储单元,C语言语言中,二维数组排列的顺序是中,二维数组排列的顺序是“按行存放按行存放”的。即先存放第的。即先存放第0行的行的元素,再存放第元素,再存放第1行的元素,行的元素,.。如图。如图4.8表示表示a数组元素在内存
39、数组元素在内存中的排列顺序。中的排列顺序。由由二二维维数数组组的的概概念念很很容容易易推推广广到到多多维维数数组组的的情情况况,多多维维数数组组的定义形式为:的定义形式为:类型名类型名数组名数组名第维长度第维长度第维长度第维长度.第第n维长度维长度;多多维维数数组组的的元元素素存存放放顺顺序序是是按按第第一一维维下下标标变变化化最最慢慢,最最右右边边的下标变化最快的原则。例如:的下标变化最快的原则。例如:doublex223;上上述述定定义义了了一一个个双双精精度度实实型型的的三三维维数数组组x。数数组组x共共有有2*2*3=12个元素,其元素在内存中的存放顺序为:个元素,其元素在内存中的存放
40、顺序为:x000 x001x002x010 x011x012 x100 x101x102 x110 x111x112。返回目录返回目录二维数组元素的使用二维数组元素的使用 定定义义了了二二维维数数组组后后,就就可可以以在在程程序序中中使使用用其其数数组组元元素素,二二维维数组元素的使用格式如下:数组元素的使用格式如下:数组名数组名下标表达式下标表达式1下标表达式下标表达式2此此处处下下标标表表达达式式可可以以是是整整型型常常量量表表达达式式或或整整型型表表达达式式。例例如如有如下定义语句:有如下定义语句:inta59;设设变变量量i,j均均为为整整型型变变量量,则则对对数数组组a的的元元素素合
41、合法法的的使使用用形形式式可可以以是是a00,a01,.,a08,a10,.,a48,aij,ai+ji-3等,在程序中可以象使用变量一样使用这些元素。等,在程序中可以象使用变量一样使用这些元素。使用二维数组元素时应注意:使用二维数组元素时应注意:()所有下标表达式的值必须是整数,且不能越过数组定义时()所有下标表达式的值必须是整数,且不能越过数组定义时下下标的上界与下界。系统也不会检查二维数组元素的下标是标的上界与下界。系统也不会检查二维数组元素的下标是否否越界,需要编程人员注意限制下标不要越界。越界,需要编程人员注意限制下标不要越界。()语语言言中中,不不能能使使用用一一个个方方括括号号来
42、来表表示示二二维维数数组组的的元元素素,以下表示是非法的:以下表示是非法的:a3,4,ai,k。返回目录返回目录二维数组的初始化二维数组的初始化 可可以以在在定定义义二二维维数数组组的的同同时时给给二二维维数数组组的的各各元元素素赋赋初初值值,赋赋初值的方法有下面几种。初值的方法有下面几种。()对全部元素赋初值()对全部元素赋初值用分行赋值方式,对全部元素赋初值用分行赋值方式,对全部元素赋初值数数组组的的每每一一行行元元素素初初始始化化赋赋值值用用花花括括号号括括起起来来,各各元元素素之之间间用逗号用逗号“,”分开,最外层再加一对花括号。例如:分开,最外层再加一对花括号。例如:inta35=1
43、2,3,4,5,6,7,8,9,10,11,12,13,14,15;把把第第一一个个花花括括号号内内的的数数据据赋赋值值给给第第一一行行的的元元素素,把把第第二二个个花花括括号号内内的的数数据据赋赋值值给给第第二二行行的的元元素素,.。这这种种赋赋值值方方法法直直观观,不不易遗漏,易于查错。易遗漏,易于查错。按顺序赋值方式,对全部元素赋初值按顺序赋值方式,对全部元素赋初值二二维维数数组组存存储储是是连连续续的的,因因此此可可以以用用一一维维数数组组赋赋初初值值的的方方法法来给二维数组赋初值。例如:来给二维数组赋初值。例如:inta35=1,2,3,4,5,6,7,8,9,10,11,12,1
44、3,14,15;这与上面这与上面中的中的a a数组赋初值的结果相同,但比较之下这种数组赋初值的结果相同,但比较之下这种赋值方法不够清晰。赋值方法不够清晰。返回目录返回目录省略第一维的长度,但第二维长度不能省略,对全部元素省略第一维的长度,但第二维长度不能省略,对全部元素 赋初值赋初值 例如:例如:inta5=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15;或或者者inta5=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15;这这与与上上面面、中中a a数数组组赋赋初初值值的的结结果果相相同同。系系统统会会根根据据数数据据的的总总个个数数分分配配存存
45、储储空空间间,共共15 个个数数据据,已已知知每每行行5列列,得得知知共共15/5=3行。行。()对部分元素赋初值()对部分元素赋初值分行赋值方式,对部分元素赋初值分行赋值方式,对部分元素赋初值可可以以对对二二维维数数组组每每一一行行的的前前面面几几元元素素赋赋初初值值。而而对对于于后后面面没没有赋初值的元素,系统将自动给该行后面的元素赋初值有赋初值的元素,系统将自动给该行后面的元素赋初值0。例如:。例如:int a45=1,2,0,8,9,16;返回目录返回目录则数组则数组a a中各元素的值为:中各元素的值为:用分行赋值方式对部分元素赋初值时,也可以省略第一维的长度。用分行赋值方式对部分元素
46、赋初值时,也可以省略第一维的长度。例如:例如:inta5=1,2,0,8,9,16;与语句与语句inta45=1,2,0,8,9,16;等价。;等价。按顺序赋值,对部分元素赋初值按顺序赋值,对部分元素赋初值可可以以按按顺顺序序赋赋值值的的方方式式对对二二维维数数组组的的部部分分元元素素赋赋初初值值。对对于于后后面没有赋初值的元素,系统也将自动赋初值面没有赋初值的元素,系统也将自动赋初值0。例如:。例如:inta35=1,2,3,4,5,6,7,8,9,;返回目录返回目录则数组则数组a中各元素的值为:中各元素的值为:利用这一特点,可以用如下方式:利用这一特点,可以用如下方式:intb59=0;给
47、二维数组给二维数组b的所有元素赋初值的所有元素赋初值0。按顺序赋值,对部分元素赋初值,并且省略第一维的长度按顺序赋值,对部分元素赋初值,并且省略第一维的长度此此时时,数数组组第第一一维维的的大大小小按按以以下下规规则则决决定定:设设有有n个个初初值值数数据据,数数组组的的第第二二维维长长度度是是n2,因因为为是是对对部部分分元元素素赋赋初初值值,则则n/n2不能被整除。第一维的大小不能被整除。第一维的大小n/n2。例如:。例如:inta5=1,2,3,4,5,6,7,8,9,10,11;此处共有此处共有11个初值数据,则个初值数据,则a数组第一维的大小数组第一维的大小=11/5+1=3(这里(
48、这里11/5为整数除),即上述语句等同于:为整数除),即上述语句等同于:int a3 5=1,2,3,4,5,6,7,8,9,10,11;返回目录返回目录二维数组程序举例二维数组程序举例 例例4.6调调用用随随机机函函数数产产生生一一个个行行列列的的二二维维数数组组(矩矩阵阵)a a,要要求求每每个个数数组组元元素素均均为为整整数数,并并且且10aijaij99,输输出出该该矩矩阵阵。把矩阵把矩阵a转置(行、列互换),然后再输出该矩阵。转置(行、列互换),然后再输出该矩阵。库库函函数数randomizse()用用于于:初初始始化化随随机机数数产产生生函函数数random。调调用用库库函函数数r
49、andom(n)产产生生一一个个0到到n-1之之间间的的随随机机整整数数。调调用用这这两两个函数,程序中应使用库文件包含个函数,程序中应使用库文件包含#includestdlib.h。把矩阵转置,即把矩阵的行、列互换,为了防止已交换过把矩阵转置,即把矩阵的行、列互换,为了防止已交换过的元素再次进行交换,程序中控制列号的变量的元素再次进行交换,程序中控制列号的变量j是从是从i+1循环到循环到n-1。例例4.6程序如下:程序如下:返回目录返回目录#includestdlib.hconstintMax=99,Min=10;main()inti,j,a55,temp;randomize();for(i
50、0;i5;i+)for(j=0;j5;j+)aij=Min+random(Max-Min+1);/*限制限制MinaijMax aijMax*/printf(随机产生的随机产生的a矩阵如下矩阵如下:n);for(i=0;i5;i+)for(j=0;j5;j+)printf(%5d,aij);printf(n);for(i=0;i5;i+)for(j=i+1;j5;j+)temp=aij;aij=aji;aji=temp;printf(a矩阵转置后如下矩阵转置后如下:n);for(i=0;i5;i+)for(j=0;j5;j+)printf(%5d,aij);printf(n);返回目录返回目






