资源描述
单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,单击此处编辑母版标题样式,Date:,28 November 2024,Date:,28 November 2024,C语言程序设计案例教程,(四,),Date:,28 November 2024,第五章C语言程序设计常用算法,冒泡排序,授课要点,冒泡排序的思想及实现,排序算法的应用,假设您是一位营养师,有顾客向您索取一份减肥菜谱。,前提条件:您熟悉各种食物的热量,问题:保持身材之道,列出各种食物的热量,对各种食物的热量进行排序,选择热量低的食物,问题分析,问题解决,冒泡排序,排序过程假设元素存放在a0an-1中,按递减排序:,1比较第一个数与第二个数,假设为逆序a0= aj+1,位置不动;,如果 aj aj+1,位置交换,即,temp=aj; ai=aj+1; aj+1=temp;,步骤3结束后 a5-i中的数为最小的数,步骤4:让i=i+1;只要i=4就返回步骤3,将a5-i的值排好。当i=5时执行步骤5,步骤5:输出排序结果,冒泡排序算法分析:,#include ,void main() /*,主函数*,/,int i, j, temp, a6; /*,整型变量*,/,for (i=0; i=5; i+)/*,键入,6,个数,放入,a,数组中*,/,printf(“,请输入食物的热量,a%d=, i);/*,提示*,/,scanf (%d, /*,用键盘输入整数赋给,ai*/,for ( i=0; i=4; i+)/*,冒泡排序,外层循环*,/,for ( j=0; j=4-i; j+ )/*,内层循环*,/,/*,循环体,开始*,/,if ( aj ai+1*/,temp = aj;/*,让,ai,与,ai+1,交换*,/,aj = aj+1;,aj+1 = temp;,/*,循环体结束*,/,printf(,食物按热量从高到低的顺序显示为:,n);,for ( i=0; i=5; i+)/*,输出排序结果*,/,printf(%dn, ai);/*,格式输出,ai*/,假设将题目改为按从小到大的顺序输出,如何修改程序?,假设排序的个数由用户指定,如何修改程序?,小组讨论并总结,在数组排序的根底上,进一步将一个数据插入一个有序数组中。,学生进阶练习,a,1,a,2,a,i-1,a,i,a,n,a,1,a,2,a,i-1,a,i,x,a,n,数组中的元素增加,1,个,问题分析,提示,数据初始化输入、排序,输入待插入数据,找到待插入位置,将待插入位置空出,插入数据,输出结果,#include ,void main() /*,主函数*,/,int i, j, temp, a6,x;/*,定义整型变量*,/,for (i=0; i=5; i+)/*,键入,6,个数,放入,a,数组中*,/,printf(,请输入待排序的数,a%d=, i);/*,提示*,/,scanf (%d, /*,用键盘输入整数赋给,ai*/,for ( i=0; i=4; i+)/*,冒泡排序,外层循环*,/,for ( j=0; j aj+1 )/*,如果,ai ai+1*/,temp = aj;/*,让,ai,与,ai+1,交换*,/,aj = aj+1;,aj+1 = temp;,/*,循环体结束*,/,for ( i=0; i=i;j-)/*,循环实现元素后移*,/,aj+1=aj;,ai=x;/*,插入元素,x*/,printf(,插入后的序列是:,n);,for ( i=0; ibi, ai=bi,aik,认为数组ab,假设nk,认为数组ab,假设n=k,认为数组a=b,数组元素作函数参数和普通变量作函数参数效果和用法一样问题1:假设有两个整型数组,试编程实现数组间关系大于、等于或小于的输出。,#include ,main(),int a10,b10,i,n=0,m=0,k=0;,printf(Enter array a:n);,for(i=0;i10;i+),scanf(%d,printf(Enter array b:n);,for(i=0;i10;i+),scanf(%d,for(i=0;iy) flag=1;,else if(xy) flag=-1;,else flag=0;,return(flag);,问题,1,解决方案:,模仿练习,1、把8、9、5、8、6、4、2、8和9、6、2、3、6、2、1、3这两组数保存在两个一维数组中主函数实现,再把两个数组对应 元素的值相减后自定义函数实现显示出来主函数实现。,2、实现两个整型变量的值的互换。假设两个整型变量是一个长度为2的整型数组的元素,模仿1答案,#include,int sub(int x,int y);,void main(),int a=8,9,5,8,6,4,2,8;,int b=9,6,2,3,6,2,1,3;,int result,i;,for(i=0;i8;i+),result=sub(ai,bi);,printf(%dn,result);,int sub(int x,int y),return x-y;,#include ,void,swap2,(int x,,,int y,), int z;,z=x; x=y; y=z;,main(), int a2=1,2;,swap2(,a0,a1,);,printf(a0=%dna1=%dn,a0,a1);,值传递,模仿2答案,1,2,a,调用前,FFAA,FFAE,1,2,x,调用时,y,FF01,FAAC,2,1,x,交换,y,FF01,FAAC,1,2,a,返回,FFAA,FFAE,授课要点,数组元素作函数参数,数组名作函数参数,模仿1改进,#include,void sub(int x,int y,int n);,void main(),int a=8,9,5,8,6,4,2,8;,int b=9,6,2,3,6,2,1,3;,sub(a,b,8);,void sub(int x,int y,int n),int i,result;,for(i=0;in;i+),result=xi-yi;,printf(%dn,result);,问题,2,:,定义一个函数,求全班学生的某门课程总分,并将总分返回到主函数中输出。,问题,2,解决,-,自定义函数求总分,int sum(,int,stu,int n,), int i;,int total=0;,for( i=,0,; i,n,; i+ ),total +=,stu,i;,return total;,形参用数组定义,int stu ,n,为数组长度,#include ,float sum(int stu, int n);,void main(),int score10, i;,int total;,printf(Input 10 scores,:,n);,for( i=0; i10; i+ ),scanf(%d, ,total=,sum(,score,10);,printf(“sum is,:,%d, total);,int sum(,int,stu, int n), int i;,int total=0;,for( i=0; in; i+ ),total += stui;,return total;,实参用数组名,.,.,2,1,0,9,score,56,23,12,.,.,88,stu,问题,2,解决,形参用数组定义,int stu ,数组名作函数参数总结,地址传递,在主调函数与被调函数分别,定义数组,且类型应一致,实参用,数组名,,形参用,数组定义,形参、实参数组名是,地址变量,模仿练习,1、实现两个整型变量的值的互换。假设两个整型变量是一个长度为2的整型数组的元素,2、在主函数输入8个整数保存到数组中,自定义函数对数组元素排序,并在主函数中将排序后的数组输出。,3、在主函数输入10个整数保存到数组中,分别定义三个函数求和、平均值和最大值并返回到主函数输出。,1,2,a,调用前,1,2,a,x,调用,2,1,a,x,交换,2,1,a,返回,#include ,void,swap2,(int x,), int z;,z=x0; x0=x1; x1=z;,main(), int a2=1,2;,swap2(,a,);,printf(a0=%dna1=%dn,a0,a1);,地址传递,模仿1答案,小组讨论并总结,数组元素作函数参数时,实参和形参间的传递方式是什么?,数组名作函数参数时,实参和形参的写法有什么不同?,数组元素作函数参数是,实参与形参间发生值传递。,结论,1,:,数组名作函数参数时,实参和形参间发生地址传递;,在主调函数与被调函数分别定义数组,且类型应一致;,形参数组大小,(,多维数组第一维,),可不指定,形参数组名表示,地址;,结论,2,:,学以致用,寻找你身边的一个实际问题,用到数组名作函数参数。例如:定义一个函数,实现10个同学身高的比较,从中找出最高身高,并返回到主函数中输出。,作业,每人必做,将“学生成绩管理系统中的“学生变量定义成结构体数组,学生信息的输入、输出代码做出相应的修改。,Date:,28 十一月 2024,第四章 模块化程序设计,-,二维数组,授课要点,二维数组的定义和引用,二维数组的初始化和赋值,二维数组的简单应用,问题,1,:有如下表,在,C,程序中如何表示和存储,2,4,6,8,4,8,12,16,10,12,14,18,13,15,17,19,假定某班有,3,名学生期末考试共,5,门课程,要求输入每名学生各门成绩,计算出每名学生的总分并输出。,问题,2,课程,学生,C,语言,高数,英语,文化基础,体育,李军,90,75,81,95,55,陈兰,60,62,67,87,78,王芳,85,91,98,88,73,以上两个例子有什么共同之处?,分析,:,1,、,每行,都是,4,个整数,,类型一致,2,、,每名,学生都有,5,门课程,,成绩类型一致,问题解决,二维数组,如何定义二维数组?,如何为数组元素赋值?,如何引用数组元素?,二维数组的定义和引用,二维数组,有两个下标的数组,类型说明符 数组名,常量表达式,1 ,常量表达式,2,例如:,int a44,;,数组元素的存放顺序,原因:内存是,一维,的,二维数组:按,行,序优先,行数,列数,元素个数,=,行数*列数,int a32,a01,a10,a11,a20,a21,0,1,4,5,2,3,a00,a00 a01,a10 a11,a20 a21,a00 a01 a02 a03,a10 a11 a12 a13,a20 a21 a22 a23,a30 a31 a32 a33,二维数组理解,例,int a34;,2016,17,2018,19,2020,21,2022,23,2008,9,2010,11,2012,13,2014,15,2000,1,2002,3,2004,5,20006,7,a00,a01,a02,a03,a10,a11,a12,a13,a20,a21,a22,a23,每个元素,ai,由包含,4,个元素,的一维数组组成,二维数组,a,是由,3,个元素组成,a0,a1,a2,行名,0,1,4,5,2,3,a01,a02,a03,a10,a11,a00,a13,a20,a21,a22,a23,a12,6,7,10,11,8,9,a0,a1,a2,因此:二维数组中的每一行,相当于一个一维数组。或者说,,一维数组是由多个简单变量组成,而二维数组是由多个一维数组组成,。,二维数组的初始化,二维数组元素的初始化,分行初始化:,例,int a23=1,2,3,4,5,6;,a00,a01,a02,a10,a11,a12,1,2,3,4,5,6,全部初始化,例,int a3=1,4,5;,a00,a01,a02,a10,a11,a12,1,0,0,4,5,0,第一维,长度省略初始化,例,int a23=1,2,3,4,5,6;,a00,a01,a02,a10,a11,a12,1,2,3,4,5,6,全部初始化,例,int a23=1,2,4;,a00,a01,a02,a10,a11,a12,1,2,4,0,0,0,部分初始化,例,int a3=1,2,3,4,5;,a00,a01,a02,a10,a11,a12,1,2,3,4,5,0,第一维,长度省略初始化,定义一二维数组,存放下表数据:,模仿练习,2,4,6,8,4,8,12,16,10,12,14,18,13,15,17,19,数组的赋值只能对数组元素单独操作,不能对数组整体操作。,赋值的两种方式:int a54;,赋值运算符 如:a30=8;,输入函数 如:,for(i=0;i5;i+),for(j=0;j4;j+),scanf(“%d,单独为每个元素赋值,对数组的整体赋值只能在初始化时进行,二维数组的赋值,二维数组的遍历,数组的遍历一般用二重循环实现,注意下标的取值范围,不能越界编译系统对下标的越界不做检查,假定某班有,3,名学生期末考试共,5,门课程,要求输入每名学生各门成绩,计算出每名学生的总分并输出。,问题,2,#include,void main(),int a36,i,j;,for(i=0;i3;i+),ai5=0; /*为每位学生的总分赋初值0*/,for(i=0;i3;i+) /*控制多少学生(多少行)*/,printf(请输入第%d个学生5门课程成绩:,i+1);,for(j=0;j5;j+) /*控制每个学生的课程(每行的列)*/, scanf(“%d, /*输入成绩参加总分*/,printf(学号 总分n);,for(i=0;ib,显示“a大于b,如果anum=101,结构体指针名,-,成员名,结构体变量名,.,成员名,(*,结构体指针名,).,成员名,小组讨论并总结,指针定义后为什么必须要赋值才能使用,为什么指向变量的指针必须同变量的类型一致,int *p;,与*,p=10,中的*有什么区别,使用指针的意义,结论,1,指针定义后为什么必须要赋值才能使用?,指针如果没有赋值,那么指向一个任意的地址,如果使用没有初始化的指针,很危险,会发生一些不可预料的后果。,结论,2,为什么指向变量的指针必须同变量的类型一致?,指针变量用来存放地址,使用前要进行初始化,因此要知道其存放什么类型的地址。,一个指针必须指向某一个确定的数据类型定义的变量,而不能随便更改一个指针变量所指向的数据类型。,具体地说,一个整型指针变量只能指向一个整型变量,一个实型指针只能指向一个实型变量,更不能定义一个万能型的指针变量void既可以指向一种数据类型,又可以指向另一种数据类型,结论,3,int *p;,与*,p=10,中的*有什么区别?,int *p,中的*表示定义指针变量,p,*p=10,中的*表示访问指针变量,p,指向地址处存放的值,结论,3,使用指针的意义,使程序简洁、紧凑、高效,有效地表示复杂的数据结构,动态分配内存,得到多于一个的函数返回值,作业,每人必做,1从键盘输入5个整数到动态内存区域,求出其中偶数之和。,2. 定义一个指向“学生结构体的指针,通过函数malloc()为一个学生的信息分配空间,通过指针为学号、姓名、4门成绩赋值并输出。,Date:,28 十一月 2024,第六章 指针,-,指针与数组,授课要点,指向数组元素的指针变量,指针的运算,用指针表示数组元素,引入:数组和指针的关系,数组名,是表示数组,首地,址的,地址常量,指针变量,是存放变量,地址的变量,指向数组元素的指针变量,例,int array10;,int *p;,p= /, p=array;,或,int *p=,或,int *p=array;,array0,array1,array2,array3,array9,.,整型指针,p,&array0,p,授课要点,指向数组元素的指针变量,指针的运算,用指针表示数组元素,指针的运算,指针变量的赋值运算,p= (,将变量,a,地址,p),p=array; (,将数组,array,首地址,p),p= (,将数组元素地址,p),p1=p2; (,指针变量,p2,值,p1),不能把一个整数,p,也不能把,p,的值整型变量,如,int i, *p;,p=1000; (,),i=p; (,),指针的算术运算,指针的算术运算:,pi (i为整型数),p+, p-, p+i, p-i, p+=i, p-=i等,假设p1与p2指向同一数组,p1-p2=两指针间元素个数(p1-p2)/d,p1+p2 无意义,指针的算术运算,例 p指向short int型数组,且 p= 那么p+1 指向a1,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a,数组,p,p+1,a+1,p+i,a+i,p+9,a+9,例,int a10;,int *p=,p+;,*p=1;,等价于,a3=1;,例 int a10;,int *p1=,int *p2=,那么:p2-p1=3;,有定义:float a10,*p=NULL; 那么:,p=a; p、p+表示什么?,p= p、p-3、p+3、p- - 表示什么?,模仿练习,授课要点,指向数组元素的指针变量,指针的运算,用指针表示数组元素,数组元素表示方法,a0,a1,a2,a3,a9,.,a,a+9,a+1,a+2,地址,元素,下标法,a0,a1,a2,a,9,a0,a1,a2,a3,a9,.,p,p+9,p+1,p,+,2,地址,元素,指针法,*,p,*(,p+1),*(,p+2),*(,p+9),变址运算符,a,i,*(a+i),ai, pi *(p+i) *(a+i),有,:int a10,*p=a;,有定义:float a10,*p=NULL; 那么:,p= *p 、*(p+1) 、*(p+3)表示什么?,p=a; *p+1 、*(p+5)-1表示什么?,模仿练习,用指针表示数组元素举例,1,例:定义一一维数组,从键盘输入元素值,并输出。要求用指针表示数组元素,void main(), int i,*p,a7;,p=a;,for(i=0;i7;i+),scanf(%d,p+,);,printf(n);,p=a;,for(i=0;i7;i+,p+),printf(%d,*p,);,指针变量可以指到,数组后,的内存单元,用指针表示数组元素举例,2,例:输入,10,个整数,找出最大值并输出。要求用指针表示数组元素,void main(), int a10,*p=a,*pmax=a,i;,for(i=0;i10;i+),printf(,请输入第,%d,个数:,i+1);,scanf(%d,p+,);,p=a+1;,for(i=1;i10;i+,p+,),if(,*pmax=str;p-),printf(%c,*p);,模仿练习答案,2.,#include,#include ,int max(int *q,int n);,void main(),int a5,*p=a;,int i;,for(i=0;i5;i+,p+),scanf(%d,p);,printf(max=%d,max(a,5);,int max(int *q,int n),int i;,int maxNo=*q;,q=q+1;,for(i=1;imaxNo),maxNo=*q;,return maxNo;,小组讨论并总结,1,、数组元素的表示方法有哪几种,并举例说明?,2,、数组名和指向数组的指针有何区别?,结论,1,数组元素表示方法,有四种表示方法,如下:,int a10,*p=a;,ai,pi *(p+i) *(a+i),,它们都表示数组的第,i+1,个元素,结论,2,数组名和指向数组的指针有何区别,数组名是,地址常量,,它的值不能改变,指向数组的指针,是,指针变量,,它的值可以改变,作业,每人必做,将“学生成绩管理系统中的“学生变量定义成数组,学生信息的输入、输出代码做出相应的修改。,
展开阅读全文