C语言程序设计C语言程序设计学习目标:为后续专业课(数据结构、面向对象程序设计、单片机与嵌入式系统、物联网技术等课程)奠定程序设计基础。参考教材:索明何、邢海霞、方伟骏编著《C语言程序设计》,机械工业出版社,2016.1C语言程序设计第一章:C语言语法基础第二章:C程序设计基础第三章:数组第四章:函数第五章:指针第六章:结构体、共用体、枚举类型第七章:文件教学内容:C语言程序设计C语言程序设计第三章数组【学习目标】1.掌握数组的定义、初始化和引用的方法;2.能利用数组解决实际问题,了解数组在嵌入式系统中的应用;3.理解并掌握冒泡排序和选择排序算法;4.掌握字符串处理函数及应用。C语言程序设计【学习内容】3.1一维数组3.2二维数组3.3字符数组第三章数组C语言程序设计第三章数组前面使用的都是基本类型(整型、实型、字符型)的数据,C语言还提供了构造类型,包括数组类型、结构体类型、共用体类型和枚举类型。本章学习数组。数组是将相同类型的若干数据按序组合在一起,即数组是有序同类型数据的集合。按数组元素的类型不同,数组又可分为数值数组、字符数组、指针数组、结构体数组等各种类别。本章介绍数值数组和字符数组,其他类别的数组将在后续章节中陆续介绍。C语言程序设计3.1一维数组3.1.1定义一维数组的方法在C语言中,数组和变量一样,先定义后使用。定义一维数组的一般形式:类型标识符数组名[常量表达式];说明:(1)类型标识符可以是基本类型或构造类型。(2)数组名是用户定义的数组标识符。(3)方括号中的常量表达式表示数据元素的个数,也称为数组长度。C语言程序设计3.1一维数组例如:inta[10];表示定义了一个整型数组,数组名为a,此数组有10个元素。定义数组之后,系统会为数组a分配连续的10个整型内存空间,用来存储10个数组元素,如右图所示。数组元素a[0]的内存地址是数组的首地址。每个元素都有自己的编号,第1~10个元素对应的编号依次是:a[0]、a[1]、a[2]、a[3]、a[4]、a[5]、a[6]、a[7]、a[8]、a[9]。由于元素编号是从0开始,因此不存在数组元素a[10]。C语言规定,数组名可以代表数组的首地址(数组首元素的地址)。3.1.1定义一维数组的方法C语言程序设计3.1一维数组3.1.2一维数组的初始化C语言允许在定义数组的同时,对数组进行初始化(对数组元素赋初值)。初值用{}括起来,初值之间用逗号隔开。(1)对全部元素赋初值例如:inta[5]={1,2,3,4,5};定义数组a有5个元素,花括号内提供5个初值,初始化后:a[0]=1,a[1]=2,a[2]=3,a[3]=4,a[4]=5。(2)对部分元素赋初值例如:inta[5]={1,2,3};定义数组a有5个元素,但花括号内只给前3个元素赋初值,后2个元素系统自动赋0,即a[0]=1,a[1]=2,a[2]=3,a[3]=0,a[4]=0。若数组a的全部元素初值都为0,可以写成:inta[5]={0};(3)注意:初值个数不能超过指定的元素个数。此时,对数组的全部元素赋初值,由于数据的个数已经确定,因此可以不指定数组长度(由系统自动计算)。即,亦可写成:inta[]={1,2,3,4,5};inta[5]={1,2,3,4,5,6};错误!C语言程序设计3.1一维数组3.1.3一维数组元素的引用数组先定义,后使用。C规定,只能引用某个数组元素而不能一次引用整个数组。一维数组元素的引用形式为:数组名[下标]下标其实就是数组元素的编号,只能为整型常量或整型表达式。【例3.1】一维数组元素的引用:将一组数据倒序输出。C语言程序设计3.1一维数组3.1.4一维数组的应用一维数组广泛应用于对多个同类型的数据进行存取、排序等操作的场合。用一维数组还可构造出软件设计中常用的堆栈、队列等数据结构。【例3.2】对n个数进行排序(由小到大)。由于对多个数进行排序,自然会想到利用数组来保存和管理参与排序的多个数据。排序算法有多种,现介绍两种:冒泡排序法和选择排序法。C语言程序设计3.1一维数组【例3.2】对n个数进行排序(由小到大)。1、冒泡排序法思路:从第1个数开始,和下邻数比较,小数上浮,大数下沉。用冒泡法对5个数(如:9、7、5、8、0)进行由小到大排序的过程:9758075988900975805787809708975975895780第1次9579第2次第3次第4次第1次7570第1次第2次第3次7570050550第1次第2次a[0]a[1]a[2]a[3]a[4]第1轮第2轮第3轮第4轮3.1.4一维数组的应用C语言程序设计3.1一维数组3.1.4一维数组的应用【例3.2】对n个数进行排序(由小到大)。1、冒泡排序法思路:从第1个数开始,和下邻数比较,小数上浮,大数下沉。对n个数排序,需要进行(n-1)轮比较:第1轮要进行(n-1)次两两比较;第2轮要进行(n-2)次两两比较;……第(n-1)轮要进行1次两两比较。第i轮要进行(n-i)次两两比较;C语言程序设计3.1一维数组【例3.2】对n个数进行排序(由小到大)。1、冒泡排序法#defineN5//待排序的数据个数inta[N];//数组a存放待排序的数据inti,j,t;//冒泡法排序(由小到大):小数在前面,大数在后面for(i=1;iN;i++)//N个数,共需比较N-1轮{if(swap_flag==0)break;}for(j=0;jN-i;j++)//第i轮需要比较N-i次if(a[j]a[j+1])//依次比较两个相邻的数,将大数放后面{t=a[j];a[j]=a[j+1];a[j+1]=t;}用上面的冒泡法程序进行排序时,存在什么问题?如何改进?本轮比较结束后,不必继续进行下一轮比较!解决办法:设置交换标志变量swap_flag,若某轮比较过程中无交换,则提前退出循环,结束比较。若参与排序的多个数据在某轮排序前,恰好已经按照从小到大排序,则inti,j,t,swap_flag;swap_flag=1;swap_flag=0;本程序中,冒泡法排序用了for循环嵌套,其中外层for循环控制比较轮数,内层for循环控制第i轮的比较次数。需要注意:若外层循环变量i从0开始,则对应的程序代码需改为:for(i=0;iN-1;i++)for(j=0;jN-i-1;j++)3.1.4一维数组的应用C语言程序设计3.1一维数组【例3.2】对n个数进行排序(由小到大)。2、选择排序法假设有n个待排序的数据存放在a[0]~a[n-1]中,现使用选择法对这n个数据进行由小到大排序。所谓选择排序法:首先在n个数据中选择最小值放在a[0]位置:假设n个数据中的最小值在a[k]位置,则需要将a[0]位置和a[k]位置上的数据进行交换,即可实现将最小值放在a[0]位置;然后在剩余的n-1个数据中选择最小值放在a[1]位置;在剩余的n-2个数据中选择最小值放在a[2]位置;………………………………………………………………;直到剩下最后1个数据是这n个数据中的最大值,占用a[n-1]位置,无需继续选择。3.1.4一维数组的应用C语言程序设计3.1一维数组【例3.2】对n个数进行排序(由小到大)。2、选择排序法用选择法对5个数(如:2、4、5、3、0)进行由小到大排序的过程:a[0]a[1]a[2]a[3]a[4]排序前:24530第1轮比较最小值位置下标245300k=042023354a[0]a[k]0453223第2轮比较4532k=134a[1]a[k]a[2]a[k]2选择交换选择交换43534第3轮比较选择交换2k=a[3]a[k]5553444第4轮比较选择交换4k=3.1.4一维数组的应用C语言程序设计3.1一维数组【例3.2】对n个数进行排序(由小到大)。2、选择排序法#defineN5//待排序的数据个数inta[N];//数组a存放待排序的数据inti,j,k,t;//选择法排序(由小到大):小数在前面,大数在后面for(i=0;iN-1;i++)//N个数,共需比较N-1轮{}if(k!=i)//若该轮最小值的位置有更新,则要进行数据交换{t=a[i];a[i]=a[k];a[k]=t;}k=i;//先假定该轮第1个数为最小值for(j=i+1;jN;j++)//寻找该轮最小值所处的位置if(a[j]a[k])k=j;3.1.4一维数组的应用C语言程序设计3.1一维数组【例3.2】对n个数进行排序(由小到大)。3.1.4一维数组的应用C语言程序设计3.1一维数组【例3.3】51单片机控制流水灯。若要实现LED小灯从左至右依次轮流点亮,P1口的数据编码:可将P1口的9个编码数据用一个数组来管理,并用循环结构依次取出各数组元素送P1口,即可实现要求的流水灯显示效果。for(i=0;i9;i++){P1=dispcode[i];delay(10000);//延时}uchardispcode[9]={0xff,0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//用数组存放编码3.1.4一维数组的应用C语言程序设计3.2二维数组在单片机控制点阵屏或液晶屏显示多个字符时,常用二维数组存放和管理显示字符的编码,有专门的“取模软件”会自动生成多个显示字符对应的二维数组。C语言程序设计3.2二维数组3.2.1定义二维数组的方法定义二维数组的一般形式:类型标识符数组名[常量表达式1][常量表达式2]其中,常量表达式1表示二维数组的行数,常量表达式2表示二维数组的列数。例如:inta[3][4];表示定义了一个3行4列的整型数组,共有3×4个元素。每个元素都有自己的编号:C语言程序设计3.2二维数组定义数组之后,系统会为数组a分配连续的12个整型内存空间,用来存储12个数组元素。C语言中,二维数组中元素排列的顺序是按“行”存放的,即在内存中先顺序存放第1行的元素;同样地,数组名a代表该数组的首地址(数组首元素的地址)。inta[3][4];再顺序存放第2行的元素。最后顺序存放第3行的元素。首地址3.2.1定义二维数组的方法C语言程序设计3.2二维数组它有3个元素:a[0]、a[1]、a[2],而每个元素又是一个包含4个元素的一维数组,此时把a[0]、a[1]、a[2]看作一维数组名。例如第一行元素:a[0][0]a[0][1]a[0][2]a[0][3]C语言中,又可以把二维数组a看作是一个一维数组。3.2.1定义二维数组的方法C语言程序设计3.2二维数组3.2.2二维数组的初始化在定义数组的同时,对二维数组元素赋初值。(1)分行给二维数组赋初值。例如:inta[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};这种赋初值方法比较直观,把第1个花括号内的数据赋给第1行的元素,第2个花括号内的数据赋给第2行的元素,…,即按行赋初值。(2)将所有数据写在一个花括号内,按数组排列的顺序给元素赋初值。例如:inta[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};效果与第(1)种方法相同。但建议用第(1)种方法,一行对一行,不易出错。C语言程序设计3.2二维数组在定义数组的同时,对二维数组元素赋初值。(3)可以给部分元素赋初值。例如:inta[3][4]={{1},{5},{9}};赋值后数组元素为(4)如果对全部元素都赋初值,则定义数组时,对第一维的长度(行数)可以不指定,但第二维的长度不能省略。例如:inta[][4]={1,2,3,4,5,6,7,8,9,10,11,12};与第(2)种效果相同。3.2.2二维数组的初始化C语言程序设计3.2二维数组3.2.3二维数组元素的引用C规定,只能引用某个数组元素而不能一次引用整个数组。二维数组元素的引用形式为:数组名[下标][下标]下标其实就是数组元素的编号,只能为整型常量或整型表达式。【例3.4】二维数组元素的引用。C语言程序设计3.2二维数组3.2.4二维数组的