郝斌C语言详细笔记附源码.docx
- 文档编号:6125294
- 上传时间:2023-01-04
- 格式:DOCX
- 页数:36
- 大小:329.90KB
郝斌C语言详细笔记附源码.docx
《郝斌C语言详细笔记附源码.docx》由会员分享,可在线阅读,更多相关《郝斌C语言详细笔记附源码.docx(36页珍藏版)》请在冰豆网上搜索。
郝斌C语言详细笔记附源码
郝斌老师的C语言:
课堂讲解全程动手敲代码,讲解细致,对于重要知识点的讲解不厌其烦,是一个难得的C语言入门教程。
在这里对老师的辛勤付出表示感谢。
郝斌c语言视频教程
·
概述:
课程计划
为什么学习c语言:
Fortran语言主要用于科学计算,在第三代语言中,以1980年为分水岭,分为结构化和面向对象语言。
Basic语言是vb的前生,pascal语言一般是用于教学。
C语言是最重要的,其他的语言一般很少用了。
结构化的代表语言是c语言。
结构化语言的数据和操作是分离的,导致在写大项目的时候,会出现各种各样莫名其妙的问题。
在面向对象的语言中c++是最复杂的语言。
由于c++语言太复杂,sun公司对c++进行了改装,产生了java语言。
而c#是由微软开发的,和java相似,几乎一模一样。
在高级语言的执行速度上,c是最快的,c++其次,而java和c#是最后的。
Java和c#流行,主要的一个原因是可以跨平台。
C语言的发展和过程:
C语言的特点:
·优点:
代码量小,速度快,功能强大。
·缺点:
危险性高,开发周期长,可移植性弱。
危险性高:
写同一个程序,在java中会报错,而在c中不会报错,为什么呢,因为c认为程序你想怎么写就怎么写,c语言认为你写的程序不是很离谱,他都认为你写的这个程序有特殊的含义。
可以直接通过,而java则不可以。
开发周期长:
c语言是面向过程的语言,面向过程的语言的特点就是在开发大项目的时候,很容易崩溃,好比盖大楼,C语言还要造大量的砖块、钢筋等结构原材料,而C++C#JAVA则进行了一定的继承封装等操作,相当于原材料直接给你,你只需要用它盖楼即可。
现在市场上的语言分三块
C/c++:
单纯的学习c是什么都做不了的。
Java
C#
可移植性不强:
这是针对java来说的,因为java的可移植性太强了,所以就感觉说c的可移植性不强。
金山公司最主要是靠wps办公软件来发展的。
Wps是c语言开发的,其安装包比Office少了10多倍。
三大操作系统:
windows,unix,linux
Windows内核是c语言写的,而外壳是c++写的。
Java永远不可能写操作系统。
因为java运行速度太慢了。
而linux和unix都是纯c写的。
操作系统控制了硬件,如果说操作系统的运行速度慢,那么当我们在运行软件的时候,运行速度会更慢。
为什么使用c语言写操作系统呢,首先是因为c的运行速度快,然后是因为c可以直接控制硬件,而其他语言不可以。
没有指针的语言是不能直接访问硬件的。
C语言的应用领域:
驱动一般是用c和汇编来写的。
数据库一般是用c和c++来写的
C语言的重要性:
虽然应用场合相对较窄,但贴近系统内核,较底层。
病毒最基本的是要感染系统,
数据结构,c,c++这三门语言是必须要学习的。
牛人牛语:
怎样学习c语言
要将编程当成一项事业来经营,而不是糊口的工具。
多思考,多上机。
不能光看,光听,而要排错,调试。
在犯错误中成长。
参考资料
王爽写的c++也很不错
学习的目标:
掌握简单的算法--解决问题的方法和步骤。
熟悉语法规则。
能看懂程序并调试程序。
C语言的关键字:
C语言程序的格式:
一定要养成良好的习惯:
代码规范
边写边保存,括号成对出现,应用空格
软件操作:
新建保存关闭(关闭空间)
.cpp是原始文件,可单独拷贝到其它电脑。
第二讲:
(14)c语言编程必备知识
1.Cpu,内存条,硬盘,显卡,主板,显示器之间关系。
Cpu不能直接处理硬盘上的数据,必须要先调入内存
2.Helloword程序是如何运行起来的。
3.什么是数据类型
数据类型--数据的分类,对编程而言,首要考虑问题是数据的输入和存储。
可以分为
A:
基本数据类型:
整型
整型int--4字节一字节byte=8位bit
短整型shortint-2
长整型longint-8
浮点型
单精度浮点数float:
存储范围小-4
双精度浮点数double:
存储范围大-8
Float和Double都不能保证将小数完全准确保存。
字符char:
c语言中是没有字符串string-1
(区别于JAVA、C#中有string且C#中char为2字节)
B:
复合类型:
就是把基本类型拼凑在一起
结构体
枚举---实用
共用体—基本淘汰
4.什么是变量
变量的本质是内存中一段存储空间。
IntI;i=5;I是变量,程序向系统申请了一个内存单元,在程序运行中,i的值可以改变,但程序结束后,其所占的空间不是释放,而是被系统收回权限。
5Cpu,内存条,vc++,操作系统之间的关系。
6变量为什么必须初始(即赋值)
1.软件在运行前需要向操作系统申请存储空间,在内存空间足够空闲时,操作系统将分配一段内存空间并将该外存中软件拷贝一份存入该内存空间中,并启动该软件运行。
2.在软件运行期间,该软件所占内存空间不再分配给其他软件。
3.当该软件运行完毕后,操作系统将回收该内存空间(注意:
操作系统并不清空该内存空间遗留下来的数据),以便再次分配给其他软件使用。
《操作系统》一门课中系统分配表中会讲到,用1标记表示内在是被占用的,用0标记表示是空闲的。
综上所述,一个软件所分配到的空间中极可能存在着以前其他软件使用过后的残留数据,这些数据被称之为垃圾数据,所以通常情况下我们为一个变量,为一个数组,分配好存储空间之前都要对该内存空间初始化。
7如何定义变量
数据类型变量名称=赋予的值;
等价于
数据类型变量名;
变量名=要赋予的值;
举例子:
inti=3;等价于inti;i=3;
Inti,j;等价于inti;intj;
Inti,j=3等价于inti;intj;j=3;
IntI=3,j=5;等价于inti;intj;I=3;j=5;
8什么是进制–逢几进一
我们规定八进制前面加0(零),十六进制前面加0x。
常用计数制对照表:
Printf的基本用法:
9常量在c中是如何表示的
当个字符使用单引号括起来,多个字符串使用双引号括起来(指针、数组)。
在c中,默认是double类型的。
在后面加F表示当做float来处理,否则会有警告提示--丢失部分字节。
10常量以什么样的二进制代码存储在计算机中?
编码:
整数是以补码的形式转换为二进制代码存储在计算机
浮点数是以ieee754标准转换为二进制代码存储
字符本质实际是与整数的存储方式相同,ASII码标准。
第三次课:
代码规范化
·可以参考林锐《高质量c/c++编程》
·代码的规范化非常的重要,是学习一门编程语言的基础,代码可以允许错误,但不能不规范。
例如:
成对敲括号{}()
加空格于运算符和数字之间I=1+2;
加缩进分清上下级地位。
换行--进行功能区域分隔or{}括号单独成一行。
·代码规范化的好处
1:
整齐,别人和自己都容易看懂。
2:
代码规范了,代码不容易出错。
3:
一般的程序可以分为三块:
a:
定义变量
b:
对变量进行操作
c:
输出值
什么是字节
·存储数据的单位,并且是硬件所能访问的最小单位。
内存中存储的最小单位是位bit(0或1),但是硬件控制的时候不能精确到位,只能精确到字节(8位),是通过地址总线来控制的,而精确到位是通过软件来控制的,叫做位运算符来精确到位的。
1字节=8位1K=1024字节
1M=1024K1G=1024M1T=1024G
2G的内存条的总空间:
2*1024*1024*1024*8=4*1032
不同类型数据之间相互赋值的问题不同数据类型之间最好不要相互转换。
如果需要明白这个知识点,那么需要明白补码。
什么是ASCII码
以char定义变量的时候,只能使用单引号括起一个字符才是正确的。
在上图中注释的最后一样是重复定义了ch的值,是错误的,而下面的ch=‘c’是指把c赋值给ch,是正确的。
上图中输出的值是98(将字符以整数%d的形式输出)
Ascll码规定了ch是以哪个值去保存,ascii码不是一个值,而是一种规定,规定了不同的字符是以哪个整数值去表示。
其它规定还有GB2312UTF-8等。
字符本质上与整数的存储方式相同【字符的存储】
基本的输入和输出函数的用法:
第三次课
Printf()
将变量的内容输出到显示器上。
四种用法
输什么是输出控制符,什么是非输出控制符
输出控制符包含如下:
Printf为什么需要输出控制符:
·01组成的代码可以表示数据也可以表示指令。
必须要有输出控制符告诉他怎么去解读。
·如果01组成的代码表示的是数据的话,那么同样的01代码组合以不同的格式输出就会有不同的输出结果,所以必须要有输出控制符。
在上图中,intx=47,如果前面加0(零)048表示的是八进制,如果前面加0x(零x)0X47则表示的是十六进制,而在输出的时候,则是o(字母o)表示八进制,ox(字母o,x)表示十六进制。
非输出控制符:
非输出控制符在输出的时候会原样输出。
Scanf()通过键盘将数据输入到变量中
有两种用法:
示例:
非输入控制符:
在输入的时候也会原样输入。
但是强烈建议:
在使用scanf的时候,不使用非输入控制符。
给多个变量赋值:
需要记住,非控制符需要原样输入。
如何使用scanf编写出高质量代码
运算符:
算术运算符:
加(+),减(—)乘(*)除(/)取余(%)
关系运算符:
>,>=,<,<=,!
=,
逻辑运算符:
!
(非),&&(且),||(或)
赋值运算符:
=,+=,*=,/=
例如:
a+=3是等价于a=a+3,a/=3等价于a=a/3
其优先级别是算术>关系>逻辑>赋值。
取余的结果的正负只和被除数有关。
第四节
流程控制(第一个重点):
1.什么是流程控制
程序代码执行的顺序。
2.流程控制的分类
顺序执行
选择执行
定义:
某些代码可能执行,可能不执行,有选择的执行某些代码。
分类:
if
If最简单的用法:
如果想控制多个语句的执行或者不执行,那么需要使用{}括起来。
…else…的用法:
if…elseif…else的用法:
C错误的if…elseif…else语句:
在上图中,当执行到哈哈那句时,下面的else将会被算作另外一个语句来执行,而在我们的c语言中,没有以else开头的语句。
所以会出错。
If实例:
If常见的问题:
变量的替换:
求三个数字的大小:
C语言常见误区:
纸老虎
素数:
只能被1和自己整除的数,如1,5,9等。
回文数:
正着写和倒着写一样的数。
如1221,121,等
编程实现求一个十进制数字的二进制形式:
求一个数字的每位是奇数的数字取出来组合形成的新数字。
求一个数字到过来的数字。
1:
如果不懂,那么就看答案。
看懂答案在敲。
没错误了,在尝试改。
如何看懂一个程序:
1.流程:
2.每个语句的功能:
3.试数:
对一些小算法的程序:
1.尝试自己编程结局。
2.解决不了,看答案。
3.关键是把答案看懂。
4.看懂之后尝试自己修改程序,且知道修改之后程序的不同输出结果的含义。
5.照着答案去敲
6.调试错误
7.不看答案,自己独立把程序编出
8.如果程序实在是彻底无法了解,就把他背会。
空语句的问题:
在上图中,最终的结果会是AAAA,BBBB,程序也不会报错,为什么呢,因为在程序执行的时候,会在;哪里认为是一个空语句。
也就是说,如果if成立,那么执行空语句。
If常见错误解析(重点)
上面这个程序是错误的,为什么呢,在该程序中,总的有4个语句,而在以else开头的那个语句中是有错误的,因为在c语言中是没有以else开头的这种语法。
在上面这个程序中,最终的值是AAAA,虽说后面的3>1也满足条件,但是当3>2满足条件后,该if语句就会终止,后面的语句是不会在执行的。
既然7行要写表达式,就要写if。
循环的定义、分类。
定义:
某些代码会被重复执行。
分类:
forwhiledo……while
在上图中,先执行1,在执行2,2如果成立,标志着循环成立,那么在执行4,最后在执行3,3执行完后代表一次循环完成,然后在执行2.以此类推。
1永远只执行一次。
++I等价于i+1
求1-10的所有奇数的和:
求1-12之间的所有能被3整除的数字之和:
For所控制的语句:
在上图中,for默认只能控制一个语句,但是如果要控制多个语句时候,那么需要使用{}把语句括起来。
求1+1/2+1/3….1/100的和
在上图中,重点是强制数据类型转换也就是(float)(i)那句:
如果把print那句换为下面这句会怎么样呢:
也是错的,为什么呢,因为i是整型,1也是整型,所以不管你怎么转换也是整型啊,如果想要这样写的话,那么我们需要把1改成也可以的。
也就是:
试数详细步骤举例:
浮点数存取:
求1-100之间所有奇数的和:
求1-100之间的奇数的个数:
求1-100之间奇数的平均值:
求1-100之间的奇数之和,在求1-100之间的偶数之和:
多个for循环的嵌套使用:
整体是两个语句。
上图中,先执行1,在执行2,如果2成立,执行4,在执行5,如果5成立执行A,在执行6,在执行5,如果5不成立,意味着里面的循环结束,然后执行3,在执行2,如果2成立又执行4,在执行5,如果5成立在执行6,在执行5,如果5不成立,在执行3,在执行2,如果2不成立,意味着本次循环结束,在执行B,在上图中,需要注意的是,如果2成立的话,那么每次4都需要执行。
进制之间的转换:
如234为5进制,那么转换成10进制是多少:
2x5x5+3x5+4的值就是转换成的10进制。
234e是16进制,转换成2进制是多少:
2x16x16x16+3x16x16+4x16+12的值就是转换成10进制的值。
注意上面的规律。
那么把十进制转换成r进制呢,其实很简单,就是把10进制数除以r,直到商是0的时候。
然后取余数,余数倒序排列:
琐碎的运算符:
自增:
自减:
和自增一样。
三目运算符:
最终的输出结果是1.
逗号表达式:
最终结果是6.
上图中,逗号是个顺序点,即所有的副作用必须在下个语句前生效,其最后结果为1,j+2只是产生临时值,并没有把j+2的值赋个j。
如果写成j+=2,那最后的值则变为5.
For的嵌套使用举例:
上例中输出的结果是9个哈哈,1个嘻嘻。
在上图中,整个程序分成3个语句,输出的结果是3个嘿嘿,3个哈哈,1个嘻嘻。
其结果是:
While(先付钱后吃饭)
1:
执行的顺序:
2:
与for的相互比较:
用for来求1-100之和:
用while实现1-100之和。
只需要把for语句替换为:
For和while是可以相互转换的,可以用下面的表达式来表示:
While和for在逻辑上完全等价,但是for在逻辑上更强。
更容易理解,更不容易出错。
推荐多使用for。
3:
while举例:
试数:
通过上面的试数,应该能很快的理解回文数的算法。
4:
什么时候使用while,什么时候使用for:
没法说,用多了就自然而然知道了
Do…while(先吃饭后付钱)
一元二次方程:
Switch的用法:
电梯程序:
Case是程序的入口,当进入程序后,程序会从上往下执行,如果有break,那么会中断程序,如果没有,那么会一直执行。
Break的用法:
在多层循环中,Break只能终止他最近的循环。
在多层switch中,break也是只能终止距离他最近的switch。
Break只能用于循环和switch,不能用于if。
如果用于if,必须要当循环中嵌套if的时候。
Continue的用法:
上图中,如果执行continue,那么C,D将不会被执行,会执行3.
在上图中,如果执行了continue,那么后面的C,D将不再执行,而会去执行表达式。
数组:
--非重点
数组的使用:
为什么需要数组
1:
为了解决大量同类型数据的存储和使用问题。
2:
用数组可以模拟现实世界。
Inta[25]:
一维数组,可以当做一个线性结构。
Inta[8][6]:
可以当做一个平面,意思是8行6列。
有48个元素。
Inta[3][4][5]:
可以当做一个三维立体。
Inta[3][4][5][6]:
可以当做一个四维空间。
数组的分类
一维数组
怎样定义一维数组:
·为n个变量分配存储空间:
数组内存空间是连续的。
·所有的变量类型必须相同:
数组不可能第一个元素是整形,第二个元素是浮点型。
·所有变量所占用的字节必须相等。
例子:
int[5]
数组不是学习重点的原因?
数组一旦定义,其长度是死的。
有关一维数组的操作--都需要自己另外编程序实现
而我们通常用第三方软件(工具)如数据库等方便直接地实现。
对数组的操作:
初始化赋值排序求最大/小值倒置查找插入删除
·初始化:
上图中a[5]前面如果没有加上数据类型,那么这里的a[5]不是指一个数组,其中的5只的是下标。
上图中,数组的5个元素不是用a来代表的,是用a0,a1…a4来代表的,所以说数组名a代表的不是数组的5个元素,数组名代表的是数组的第一个元素的地址。
·赋值
把一个数组元素给全部倒过来:
·排序
·求最大/小值
·倒置
·查找
·插入
·删除
二维数组:
二维数组的初始化:
输出二维数组内容:
多维数组:
是否存在多维数组:
不存在
因为内存是线性一维的,在内存中是不分行不分列的。
N维数组可以当做每个元素是n-1维数组的一维数组。
函数(第二个重点):
为什么需要函数:
·避免了重复性操作。
·有利于程序的模块化。
(自上而下,逐步细化,大问题分解成小问题)
用它作为参照,可以对比JAVA和C#面向对象的思想。
C语言基本单位是函数,C#、C++和JAVA基本单位是类。
什么叫做函数
·逻辑上:
能够完成特定功能的独立的代码块。
物理上:
能够接收数据【也可以不接收数据】,能够对接收的数据进行处理【也可以不对数据进行处理】,能够将数据处理的结果返【也可以没有返回值】。
·总结:
函数是个工具,他是为了解决大量类似问题而设计的,函数可以当做黑匣子(内部原理不用管)。
如何定义函数
·函数的返回值,函数的名字(函数的形参列表)
{
函数的执行体
}
·函数定义的本质:
详细描述函数之所以能够实现某个特定功能的具体方法。
函数中的变量叫做形参;数组中的变量叫元素。
一旦函数执行完毕,其内部的形参所占空间就被收回。
·return表达式的含义:
Return是终止被调函数,向主调函数返回表达式的值,如果表达式为空,则只终止函数,不向被主函数返回任何值。
Break是用来终止(就近的)循环和switch语句。
而return是用来终止被调函数的。
·函数返回值的类型,也称为函数的类型,因为如果函数名前的返回值类型和函数执行体中的return表达式中表达式的类型不同的话,则最终函数返回值的类型以函数名前的返回值类型为准。
例:
在上图中,函数的返回值以函数前的数值类型为准。
函数的分类
·有参函数和无参函数。
·有返回值和无返回值。
·库函数和用户自定义函数。
·普通函数和主函数(main函数)
1:
一个程序有且只有一个主函数。
2:
主函数可以调用普通函数,普通不能调用主函数。
3:
普通函数可以相互调用。
4:
主函数是程序的入口,也是函数的出口。
5:
值传递函数和地址传递函数。
判断一个数是否是素数:
使用函数判断一个数是否是素数:
函数和程序的调用应该注意的地方:
函数的声明:
当函数没有返回值时,那么规范的写法是要在函数中写明void的。
在上图中,第一个void表示没有返回值,而第二个void表示不接收形参,也就是函数不接收数据。
如果想把函数写在程序的后面,那么需要写函数声明:
函数声明的含义是告诉编译器f()是个函数名。
如果不加函数声明,那么编译器在编译到f的时候,不知道f是个什么,如果加了函数声明,那么编译器编译到f的时候,就知道f是个函数。
·需要注意的是,调用语句需要放在定义语句的后面,也就是说,定义函数的语句要放在调用语句的前面。
如果函数调用写在了函数定义的前面,则必须加函数前置声明,函数前置声明的作用是:
1:
告诉编译器即将可能出现的若干个字母代表的是一个函数。
“打招呼”
2:
告诉编译器即将可能出现的若干个字母所代表的函数的形参和返回值的具体情况。
3:
函数声明必须是一个语句,也就是在函数声明后需加分号。
4:
对库函数的声明也就是系统函数。
是通过#include<库函数所在的文件的名字.h>来实现的。
如
形参和实参要求:
1:
形参和实参个数是一一对应的。
2:
形参和实参的位置也是一一对应的。
3:
形参和实参的数据类型需要相互兼容。
·如何在软件开发中合理的设计函数来解决实际问题。
求1到某个数字之间的数是否是素数,并将他输出:
合理设计函数1
合理设计函数2:
合理设计函数3:
合理的设计函数4:
合理设计函数5:
常用的系统函数和如何通过书籍来学习函数:
实用大全—机械工业出版社
递归:
(略)
栈:
相当于一个杯子(容器)
变量的作用域和存储方式:
全局变量和局部变量:
局部变量:
局部变量的使用范围只能在本函数内部使用。
全部变量:
全局变量和局部变量命名冲突的问题:
在同一个范围之内不能定义两个一样的局部变量:
在一个函数内部,如果定义的局部函数的名字和全局变量名一样时,局部变量会屏蔽掉全局变量:
上例中最终的输出结果是8,因为局部变量把全局变量给屏蔽掉了。
指针:
(C语言的灵魂)
内存的存储是以一个字节为一个编号,也就是8位合在一起给一个编号,不是0,1就给编号。
内存分为很多个单元,每个单元就会分配一个编号。
地址:
内存单元的一个编号。
而指针和地址一个概念的。
也就是说指针就是地址。
普通变量:
只能存放一个值。
指针变量:
同样是一个变量,但是指针变量存放其他变量的地址。
*p代表的是p所指向的那个变量。
在上图中*p和i是同一个东西,但是*p和p不是同一个东西。
在上图中,int*p是一个声明,开头的int*是他的数据类型。
P是变量的名字。
不能理解我定义了一个整形变量,这个整形变量的名字叫做*p。
所谓int*类型,实际就是存放int变量地址的类型。
*p代表的是以p的内容为地址的变量。
解析:
p的内容是一个地址,在上图中,p的内容就是i的地址,*p其指向的变量当然就是i变量了。
指针和指针变量:
指针就是地址,地址就是指针。
地址就是内存单元的编号。
指针变量:
存放地址的变量。
而指针只是一个值,这个值是内存单元的一个编号。
指针变量才是一个变量,他里面才可以存放数据。
指针和指针变量是两个不同的概念,但是需要注意的是,通常我们在叙述时会把指针变量简称为指针,实际他们含义并不一样。
指针的重要性:
指针的分类:
指针的定义:
·地址:
内存单元的编号,是一个从0开始的非负整数。
范围:
cpu对内存是通过控制、数据、地址三条总线来进行控制的。
控制:
cup会先把内存中的数据读入,进行处理后,在返回给内存,然后内存在把数据写入硬盘。
数据:
用于数据的传输,不管是把内存中的数据发送给cpu,还是把cpu的数据写如内存条,都是由数据线来完成的,但是数据传输的方向则是由控制线来控制的。
地址:
地址线则是确定数据
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 郝斌 语言 详细 笔记 源码