资源描述
C程序设计主讲:贺细平电话:13755162334E-mail:办公室:六教207 课程地位与学习方法v课程地位:在软件设计中具有基础性地位培养计算思维-用计算机求解问题时特有的思维方式。“C通百通”!v编程高手秘笈上机思考上机思考程序设计是“练”出来的!v考核办法:平时上机实践(60%)+期终闭卷笔试(40%) 第1讲我与程序设计有个美丽的约会-初识C语言v课程重要性学习方法v编程入门知识v赋值语句的用法vif判断的用法v实例:比大小 程序设计入门知识v计算机程序的执行过程:v冯.诺依曼计算机模型数据的二进制表示存储程序、自动执行、顺序串行v程序是怎样炼成的?编写代码编译执行程序修改程序是“改”出来的!v其他 应用程序与操作系统的关系应用程序与内存、外存的关系 初识C语言v赋值 赋值运算符“=”a=b+c; 先读取b和c的值并作加法运算,将结果写到变量a中取。计算机存取数据的特点:v无论多少次“读”操作不会改变被读数据v写操作将使用新的值覆盖原来的值,原来的数据丢失。v比较与判断If语句的用法常用的比较运算符:, = , = 应用实例v求两个数的和v交换两个变量的值v求2个数中的较大值v求3个数中的最大值v求4个数、5个数v思考:求100个数,1000个数中的最大值。 第2讲机器擅长(重复和存储)-循环与数组(初步)v赋值运算符vfor循环的运用v数组的基本用法 第3讲:初识程序的魅力 -机器擅长之循环v1、求2个数的最大值,求5个数的最大值,求100个数的最大值,到n个数中的最大值。v2、如何从重复语句过渡到循环语句。v3、for语句的4个要素:变量初识化,循环条件,循环变量改变,循环体。v4、实例:求最高分v5、实例:倒计时v6、实例:简单统计 第4讲:复杂逻辑的基础-循环与判断的结合(1)v 1:循环的基本应用、累加算法的实现 :实例:游乐园的收入、证件的连续编号、大奖赛计分、简单统计v 2:for 与if配合:龟兔赛跑v 3: for循环的嵌套:关键:理解内外循环的含义v 4:双重循环举例:九九乘法表 第5讲 我想与我得(进阶)- 分支与循环的综合运用(2)v1:for 与if配合v2:双精度double型的保留小数问题,整型到double型的转换问题。v3:循环:证件的连续编号、龟兔赛跑、性别比v4:双重循环举例:九九乘法表 第6讲:我想即我得(复杂逻辑表达之一)-循环与分支的运用v总结实验课上机情况v 1:分支结构的串联和嵌套:学生成绩的等级,有这样的日期吗?闰年的判断。v 2:循环结构的串联和嵌套:九九乘法表的四种表现形式。v 3:图案的输出:实心矩形图案,空心矩形图案,横卧的空心菱形v总结:循环的嵌套和if的嵌套:串联表示前后的顺序关系,而嵌套表示逻辑的递进和乘性关系。 v展示曲线图案v课后思考题:竖立的空心菱形、余弦曲线图案,余弦与相交直线的图案,圆的图案。 第7讲:我想即我得(复杂逻辑表达之二)-循环与分支的运用v 1:图案的输出:实心矩形图案,空心矩形图案,横卧的空心菱形。图案输出的原理:1:必须从左到右边,从上到下的顺序输出。2:需要定位从屏幕的中间输出的话,必须使用空格跳格之类的字符(不可见)使光标到达指定位置。v 2:break的用法:素性测试。方法一:理解如何利用break语句执行后,循环变量与终点的关系来判断是否为素数。 方法二:使用标志变量v思考:如何提高素性测试的运行速度-时间效率。减少循环次数,改变算法。 第8讲:机器的擅长之二-批量数据处理的利器-数组v数组的适用场合:需要存储并处理一组相同类型数据。v特点:1、能存储大量数据v 2、访问速度快(读写数组元素速度快)。通过ai访问a数组中第i个元素。v 3、占用内存中连续的存储空间。是大量消耗内存空间的主要因素。程序的效率的两方面之一:时间效率和空间效率。v使用原则:尽量不用,尽量少用。 v实例:蛟龙翻身、一哥是何人、成绩分布v一维数组有“表”的作用:超市购物、学生成绩的等级、有这样的日期吗? 第9讲:机器的擅长之二-批量数据处理的利器-二维数组v利用一维数组“表”的作用,可以简化代码的编写过程。实例:超市购物中的会员等级、这个月有多少天,成绩的等级(用switch-case实现,用“表”实现)。v图像的叠加v图像翻转v图像旋转v课后作业:成绩的标准差 第10讲:数组的应用及其他v1:二维数组的应用:东海盘龙。知识点:while循环的应用。前置加和后置加运算。v2:switch-case表达能力受限,完全可被if-else语句替代。实例:这个月有多少天?学生成绩的等级,超市购物。v3:while,do-while循环的运用:完全可以用for循环来实现。分式化简(辗转相除法求最大公约数)。v4:?:运算符。v思路说明:高次方的尾数、这么多0! 补充:我想即我得(复杂逻辑表达之二)-循环与分支的运用v1:标志变量的运用。素性测试与素数筛法。v图示break,continue的执行过程。v2:switch-case表达能力受限,完全可被if-else语句替代。实例:这个月有多少天?学生成绩的等级,超市购物。v3:while,do-while循环的运用完全可以用for循环来实现。v4:?:运算符。 第11讲 文本的处理-字符串的存储与处理v 1: 字符的存储和表示:ASCII码表。中文的双字节编码:Windows-936,GBK,GB2312都是兼容的的双字节编码,还有Unicode的UTF-8,UTF-16等实现形式。v 2:ASCII码表的利用:特殊字符,空字符、换行(10,LF)、回车(13,CR),空格,跳格。数字字符:0,1,2,.,9; 大写字母A-Z,小写字母a-Z。举例:顺序输出0-9,A-Z,a-z。使用原样输出与使用循环输出。应用:大小写的转换。字符串与数字之间的转换。理解累加过程:value=value*10+(ch-0),转换的数学原理:坐标平移。 v 3:实例:选钻石矿。何时清0,何时累加。v 4:演示:穷举所有的中文字符的输出。(注意地位和高位字节都应该从128开始到255,而不是从0开始到128) 选钻石矿Description大家都知道钻石晶莹剔透、有棱有角、非常漂亮,代表着高贵、纯洁和永恒。可能你们知道吗?钻石并非天生就这么漂亮,这些钻石来自非常辛苦的大海捞针式的选矿工作和艰苦巨细的打磨得来的。现在,我们就来试试选矿的工作,假设我们要从一堆包含很多大大小小钻石块的矿中筛选出所有钻石。用一个字符串表示一堆钻石矿。非数字的字符表示泥土、岩石等杂质,一串连续的数字表示一小块钻石的价值(也可以看成是钻石的大小,因为钻石的大小与价值直接相关的)。将所有的数字相加,即为本堆矿物所筛选的钻石总价值。Input在一行中输入一个字符串,行的末尾有一个回车。字符串的长度大于等于1,小于等于106;Output输出钻石总价值。Sample Input adsf32kg! /以空格回车作为字符串输入的结束。gets(str); /以回车作为字符串输入的结束。ch=getchar()与scanf(“%c”,)效果相同。v实例:英汉字典之超水版,大整数的加法 ,门牌号码之短数版,sprintf()函数的用法,sscanf()。v思路讲解:短信中提取号码 v思考:门牌号码之长数版 第14讲 分工合作的利器-设计模块化之函数(1)v函数的概念:具有一定功能的代码模块。v函数的模型:黑盒模型(有输入、有输出、能实现一定功能,但是不用关心其内部实现和结构)v两个层次的软构件:函数、类(封装了函数和数据)。v构建新软件的方法论:“扬弃”-拿来主义,站在前人的肩膀上 + 为解决新问题而必须的开拓和创造。 拿来主义:库函数的使用要点:函数名、功能、参数的类型和含义,返回值的类型和含义。创造开拓:自己设计并实现函数。 第14讲 分工合作的利器-设计模块化之函数(1)v设计原则:具有一定的功能,具有相对的独立性,具有清晰的接口。v“先声明后使用”使用函数的语法要求。v函数在软件工程中意义:代码简洁、逻辑清晰、便于调试、自顶向下设计,模块间分工合作,代码重用,快速开发。v简单实例:分式的化简(求最大公约数)v sin函数的实现: sinx=x-x3/3!+x5/5!-x7/7!+x9/9!- (无穷级数的形式) 第15讲 分工合作的利器-设计模块化之函数(2)v 1:函数的参数传递过程,实参-形参,值的复制过程。v 2:讲解全局变量和局部变量和静态变量的区别。v 3:实例讲解:sin函数的实现:sinx=x-x3/3!+x5/5!-x7/7!+x9/9!-(这里就写成无穷级数的形式了。) 其中,简单直接法解决:分子和分母分开计算,然后再除,这样可能导致分子、分母先溢出了。解决方法:分子除以分母之后,然后再乘。最后,利用x的2周期,将x变换到2周期内。 第16讲 分工合作的利器-设计模块化之函数(3)v1:算法思想讲解:实例讲解:东海盘龙(格式版)v2:sscanf(str,%s,.)的运用。v3:算法效率问题:利用计算过程中已经得到的结果,尽量避免重复计算。v 算法的时间和空间效率问题。v4:素数有多少。 第9讲 分工合作的利器-设计模块化之函数(1)v 1:函数相关概念:先定义后使用。参数的类型与个数必须正确。返回值是所表示的含义。形式参数与实际参数的传递过程。v 2:如何设计函数:设计函数某块的原则:具有一定的功能,具有相对的独立性,具有清晰地接口。v 3:实例讲解:公历万年历。 第11讲 :程序之美 函数的递归(1)v1:递归的概念:函数自身调用自身。原问题求解方式与子问题相似(此为“递”)当子问题的规模小到一个特定程度时问题的解是已知的。(此为“归”)v2:递归举例:Fibonacci数列,阶乘,求和、正反序输出一组数据,选择排序。 第12讲 :程序之美 函数的递归(2)v递归与非递归(循环)的区别:递归方式的实现代码相对简洁,但是每次递归但需要有一定的开销,效率有损失,并且递归的深度不能过大,否则堆栈溢出。循环方式的实现相对较复杂,但是运行效率高,不会有堆栈的溢出。 v本次小结理解递归函数适用的场合。清楚递归调用的“递”过程和“归”过程。掌握递归函数的简单应用。 递归举例:v1:猜猜有多少v2:生成全排列v3:折半查找v4:应用实例:整存零取,全排列, 最大公约数。 第13讲 :内存地址的妙用(1) 指针的基本概念v 1:什么是指针:指针即内存地址。v 2:变量,指针变量深入理解变量和指针变量v 3:指针变量的用法 0012FF740012FF750012FF760012FF770012FF780012FF790012FF7A0012FF7B0012FF7C 0A0012FF7D 000012FF7E 000012FF7F 000012FF800012FF810012FF820012FF83aa 0012FF740012FF750012FF760012FF770012FF78 CC0012FF79 CC0012FF7A CC0012FF7B CC0012FF7C 0A0012FF7D 000012FF7E 000012FF7F 000012FF800012FF810012FF820012FF83int b=a*2; b变量与指针变量v普通变量三要素变量名:v程序中通过名字引用它。v程序中变量名与其值直接关联,以直接寻址方式读/写变量。变量类型:v表示数据的需要占用的字节数v数据表示的范围v数据所能进行哪些运算。vint型,double型,char型变量所占内存单元的起始地址:简称为变量的地址。v通过取地址运算符a 0012FF740012FF750012FF760012FF770012FF78 140012FF79 000012FF7A 000012FF7B 000012FF7C 0A0012FF7D 000012FF7E 000012FF7F 000012FF800012FF810012FF820012FF83int b=a*2; pa变量与指针变量int a=10;int *pa;pa = a 0012FF740012FF750012FF760012FF770012FF78 7C0012FF79 FF0012FF7A 120012FF7B 000012FF7C 0A0012FF7D 000012FF7E 000012FF7F 000012FF800012FF810012FF820012FF83v指针变量三要素变量名:v程序中通过名字引用它。v程序中指针变量名与其所指向的值间接关联,以间接寻址方式读写所指向的变量。变量类型:表示它所指向的变量的数据类型。vint *型,double*型,char*型变量所占的内存单元的起始编号:v即变量在内存中的起始地址。v通过取地址运算符得到这个起始地址。2个值v指针变量的值:即所指向变量的地址v它所指向的变量的值。通过间接寻址运算符获得。 pa变量与指针变量int a=10;int *pa;pa = *pa= *pa+10; 0012FF740012FF750012FF760012FF770012FF78 7C0012FF79 FF0012FF7A 120012FF7B 000012FF7C 140012FF7D 000012FF7E 000012FF7F 000012FF800012FF810012FF820012FF83v指针变量三要素指针变量名:v程序中通过名字引用它。v程序中指针变量名与其所指向的值间接关联,以间接寻址方式读写所指向的变量。指针变量类型:表示它所指向的变量的数据类型。v int *型,double*型,char*型指针变量所占的内存单元的起始编号:v即变量在内存中的起始地址。v通过取地址运算符得到这个起始地址。 2个值v指针变量的值:即所指向变量的地址v它所指向的变量的值。通过间接寻址运算符获得。注意:在32位的操作系统中,任何类型的指针变量占用4个字节的内存空间。即机器的寻址空间。a pa变量与指针变量int a=10;int *pa;pa = *pa= *pa+10;a 0012FF740012FF750012FF760012FF770012FF78 7C0012FF79 FF0012FF7A 120012FF7B 000012FF7C 0A0012FF7D 000012FF7E 000012FF7F 000012FF800012FF810012FF820012FF830012FF7Cpa0012FF7C 10 10apa a2 a3a0a1数组与指针变量int a4;a0=1;a1=2;a2=3;a3=4; 0012FF74 010012FF75 000012FF76 000012FF77 000012FF78 020012FF79 000012FF7A 000012FF7B 000012FF7C 030012FF7D 000012FF7E 000012FF7F 000012FF80 040012FF81 000012FF82 000012FF83 00a2int a4;int *p;p=a;*p=1;*(p+1)=2;*(p+2)=3;*(p+3)=4;int a4;int *p;p=a;*p=1;p+;*p=2;p+;*p=3;p+;*p=4 int a4;int *p;p=a;p0=1;p1=2;p2=3;p3=4; a重要概念:数组名是指针常量,它表示数组的起始地址。 数组与指针变量0012FF74 010012FF75 000012FF76 000012FF77 000012FF78 020012FF79 000012FF7A 000012FF7B 000012FF7C 030012FF7D 000012FF7E 000012FF7F 00 0012FF80 040012FF81 000012FF82 000012FF83 00int a4;int *p;p=a;*p=1;p+;*p=2;p+;*p=3;p+;*p=4 pint a4;int *p;p=a;for(i=0;i4;i+) *p=i+1; p+; a注意:每次p+移动4个字节, 这是由p所指向的是整型数据 是4个字节决定的。 数组与指针变量0012FF74 a0012FF75 b0012FF76 c0012FF77 d0012FF78 e0012FF79 f0012FF7A g0012FF7B h0012FF7C i0012FF7D j0012FF7E k0012FF7F l 0012FF80 m0012FF81 n0012FF82 o0012FF83 p pchar a16;char *p;p=a;for(i=0;i16;i+) *p=a+i; p+; a注意:每次p+移动1个字节, 这是由p所指向的是字符型数据 是1个字节决定的。 数组与指针变量0012FF74 a0012FF75 b0012FF76 c0012FF77 c0012FF78 d0012FF79 e0012FF7A f0012FF7B g0012FF7C h0012FF7D I0012FF7E j0012FF7F k 0012FF80 l0012FF81 k0012FF82 l0012FF83 mpchar a4;char *p;p=a;for(i=0;i16;i+) *p=a+i; p+; a 注意:每次p+移动1个字节, 这是由p所指向的是字符型数据 是1个字节决定的。 数组与指针变量0012FF74 a0012FF75 b0012FF76 c0012FF77 c0012FF78 d0012FF79 e0012FF7A f0012FF7B g0012FF7C h0012FF7D I0012FF7E j0012FF7F k 0012FF80 l0012FF81 k0012FF82 l0012FF83 mpchar a4;char *p;p=a;for(i=0;i16;i+) *p=a+i; p+; a 注意:每次p+移动1个字节, 这是由p所指向的是字符型数据 是1个字节决定的。 数组与指针变量0012FF74 a0012FF75 b0012FF76 c0012FF77 c0012FF78 d0012FF79 e0012FF7A f0012FF7B g0012FF7C h0012FF7D I0012FF7E j0012FF7F k 0012FF80 l0012FF81 k0012FF82 l0012FF83 mpchar a4;char *p;p=a;for(i=0;i16;i+) *p=a+i; p+; a 注意:每次p+移动1个字节, 这是由p所指向的是字符型数据 是1个字节决定的。 第14讲:内存地址的妙用(2) 指针作为函数参数v函数参数传递的2种方式。传值调用:实参形参的单向传递,可以理解为“传复印件”传址调用:实参的双向传递,可以理解为“传原件”。本质上都是传递一个数值的复制件。只不过传值时的值是一个普通的变量值,而传址时传递的是地址。v交换2个变量值的函数先不用函数实现用2种方法(复制值,复制地址的方法)交换2个变量的值 v注意事项,定义多个指针变量必须重复写*号。int *p1,*p1 (正确)Int *p1,p2;(只有p1是指针,p2是int型变量)理解scanf()中的v int c,d,t;v c=a; d=b;v t=c;c=d;d=t;v printf(a=%d,b=%dn,a,b);v int *pa,*pb; v pa=v pb=v t=*pa; *pa=*pb; *pb=t;v printf(a=%d,b=%dn,a,b);v return 0;v 第15讲:内存地址的妙用(3) 指针变量在动态内存分配中的应用v数组:是内存中开辟的地址连续的存储空间v动态分配方式:举例特点:容量在运行时确定。分配和回收耗时,存储空间利用率高,能利用非连续小块空间。能在运行过程中动态地申请,动态地释放。数据保存在堆区(heap) 生命期:申请成功后一直到释放前,在何处申请对生命期没有影响。必须由程序员负责释放,否则存在内存泄漏。v静态的分配方式:举例特点:容量预先设定,运行时不能修改。分配速度快,存储空间利用率低,不能利用非连续的小块空间。全局数组:v开辟在进程的数据区(data segment),可以较大。v生命期:在主函数运行前分配,主函数返回后释放。局部数组:即任何函数内定义的静态数组,在栈区(stack)。v生命期:函数运行时分配,函数返回后释放。 第16讲:动态内存分配的应用:二维数组的动态生成与销毁 v1:蛟龙翻身v2:二维数组的动态分配用一维数组模拟用指针数组和动态分配的一维数组模拟v实例:图像的翻转和旋转 第17讲:软件构件化的基础之数据的结盟-结构体v1:结构体的概念和应用场合v2:结构体的用法:v (1)设计自定义数据类型:结构体,v (2)使用结构体类型定义结构体变量v (3)读写结构体变量:读写结构体变量的成员v3:应用举例:简单电话薄 第18讲环环相扣的结构体-链表初步v 1:链表的概念和用途v 2:链表的结点类型设计v 3:链表的常用操作的实现v 4:应用举例:谁是幸运者 第19讲 结构体的排序(基础)v 1:选择排序与冒泡排序v 2:结构体上的选择排序与冒泡排序v 3:举例,学生信息的排序 v 4: 库函数qsort的用法。第20讲 结构体的排序(进阶)v 1:选择排序v 2:冒泡排序 第21讲:数据的持久化-文件(1)v文件:计算机持久化存储数据的基本单位。v文件类型千变万化 vs 文本文件与二进制文件v常用的文件读写操作。打开(新建)文件,关闭文件。从文件读数据向文件写数据文件读/写指针的定位操作。文件的删除。v举例:源代码文件添加行号 第22讲:数据的持久化-文件(2)v文件:计算机持久化存储数据的基本单位。v文件类型千变万化 vs 文本文件与二进制文件v常用的文件读写操作。打开(新建)文件,关闭文件。从文件读数据向文件写数据文件读/写指针的定位操作。文件的删除。v二进制文件读写举例:获取图片或mp3文件信息 第23讲:深入到bit的运算-位运算v位(bit):字节byte是计算机存储管理的基本单位。1 byte = 8 bitsv位运算的特点:运算速度快:相比乘2除2运算。操作硬件的需要:设置或读取某些特殊的硬件端口数据或硬件标志位寄存器或缓冲区的数据。v位运算包括:&,| ,v举例:循环移位
展开阅读全文