郝斌-C语言详细笔记(附带源码)

郝斌-C语言详细笔记(附带源码)

ID:83025158

大小:298.65 KB

页数:133页

时间:2023-09-19

上传者:灯火阑珊2019
郝斌-C语言详细笔记(附带源码)_第1页
郝斌-C语言详细笔记(附带源码)_第2页
郝斌-C语言详细笔记(附带源码)_第3页
郝斌-C语言详细笔记(附带源码)_第4页
郝斌-C语言详细笔记(附带源码)_第5页
郝斌-C语言详细笔记(附带源码)_第6页
郝斌-C语言详细笔记(附带源码)_第7页
郝斌-C语言详细笔记(附带源码)_第8页
郝斌-C语言详细笔记(附带源码)_第9页
郝斌-C语言详细笔记(附带源码)_第10页
资源描述:

《郝斌-C语言详细笔记(附带源码)》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库

郝斌c语言视频教程概述:课程计划为什么学习C语言:I机器轴—I第一代诺言I汇编语・]第二代语言I|FEIIBasic厂第三代高级语言纳构化||C||Pascal|Algo||Simula67]面向对象(OO)Ada~||SmallTalkFortran语言主要用于科学计算,在第三代语言中,以1980年为分水岭,分为结构化和面向对象语言。Basic语言是vb的前生,pascal语言一般是用于教学。C语言是最重要的,其他的语言一般很少用了。结构化的代表语言是c语言。结构化语言的数据和操作是分离的,导致在写大项目的时候,会出现各种各样莫名其妙的问题。在面向对象的语言中C++是最复杂的语言。由于C++语言太复杂,sun公司对C++进行了改装,产生了java语言。而c#是由微软开发的,和java相似,几乎一模一样。■高级语言:a+b

1■汇编语言ADDAX,BX■机器语言00000001110110000在高级语言的执行速度上,C是最快的,C++其次,而java和c#是最后的。Java和c#流行,主要的一个原因是可C语言的发展和过程:

2■产生时间:1972-1973■产生地点:美国贝尔实验室(Bell)■创始人:Dennis.M.Ritchie和Ken.Thompson■目的:改写UNIX操作系统■C语言发展过程・1983年ANSIC・1987年ANSIC87・1994年C99C语言的特点:•优点:代码量小,速度快,功能强大。•缺点:危险性高,开发周期长,可移植性弱。危险性高:写同一个程序,在java中会报错,而在c中不会报错,为什么呢,因为c认为程序你想怎么写就怎么写,c语言认为你写的程序不是很离谱,他都认为你写的这个程序有特殊的含义。可以直接通过,而java则不可以。开发周期长:c语言是面向过程的语言,面向过程的语言的特点就是在开发大项目的时候,很容易崩溃,好比盖大楼,C语言还要造大量的砖块、钢筋等结构原材料,而C++C#JAVA则进行了一定的继承封装等操作,相当于原材料直接给你,你只需要用它盖楼即可。现在市场上的语言分三块

3C/C++:单纯的学习c是什么都做不了的。JavaC#可移植性不强:这是针对java来说的,因为java的可移植性太强了,所以就感觉说c的可移植性不强。金山公司最主要是靠wps办公软件来发展的。Wps是c语言开发的,其安装包比Office少了10多倍。三大操作系统:windows,unix,linuxWindows内核是c语言写的,而外壳是C++写的。Java永远不可能写操作系统。因为java运行速度太慢了。而linux和unix都是纯c写的。操作系统控制了硬件,如果说操作系统的运行速度慢,那么当我们在运行软件的时候,运行速度会更慢。为什么使用c语言写操作系统呢,首先是因为c的运行速度快,然后是因为c可以直接控制硬件,而其他语言不可以。没有指针的语言是不能直接访问硬件的。C语言的应用领域:■系统软件开发■操作系统:Windows、Linux、Unix■驱动程序:主板驱动、显卡驱动、摄像头驱动■数据库:DB2、Oracle.SqlServer■应用软件开发■办公软件:Wps

4■图形图像多媒体:ACDSeePhotoshopMediaPlayer■嵌入式软件开发:智能手机、掌上电脑■游戏开发:2D、3D游戏驱动一般是用c和汇编来写的。数据库一般是用c和C++来写的C语言的重要性:■有史以来最重要语言■所有大学工科和理科学生必修课程■最重要系统软件:windows、Hnux、unix均使用c开发■一名合格黑客必须掌握的语言■任何一个想终身从事程序设计和开发人员必须熟练掌握的语言■大企业、外企招聘程序员必考的语言■为学习数据结构、C++、Java、C#奠定基础虽然应用场合相对较窄,但贴近系统内核,较底层。病毒最基本的是要感染系统,数据结构,C,C++这三门语言是必须要学习的。牛人牛语:入门最基本的方法就是从C语言入手.当你成为c语言的高手,那么就你很容易进入到操作系统的平台里面去;当你进入到操作系统的平台里去实际做程序时,就会懂得进行调试;当你懂得调试的时候,你就会发现能轻而易举地了解整个平台的架构.这时候,计算机基本上一切都在你的掌握之中了,没有什么东西能逃得出你的手掌心一一《编程箴言》梁肇新

5怎样学习C语言要将编程当成一项事业来经营,而不是糊口的工具。多思考,多上机。不能光看,光听,而要排错,调试。在犯错误中成长。参考资料■谭浩强《C语言程序设计》清华■《TheCprogramminglanguage》机械J_业■《CPrimerPlus》60元人名邮电■《C和指针》65元人名邮电■《C专家编程》绝版■《C陷阱与缺陷》人名邮电30■《C科学与艺术》机械工业王爽写的C++也很不错学习的目标:掌握简单的算法-解决问题的方法和步骤。熟悉语法规则。能看懂程序并调试程序。C语言的关键字:32个关键字:(由系统定义,不能重作其它定义)autobreakcasecharconst

6continuedefaultdodoubleelseenumexternfloatforgotoifintlongregisterreturnshortsignedsizeofstaticstructswitchtypedefunsignedunionvoidvolatilewhilec语言程序的格式:#includeintmain(void)(IIreturn0;J一定要养成良好的习惯:代码规范边写边保存,括号成对出现,应用空格VC6.0软件操作:新建保存关闭(关闭空间).cpp是原始文件,可单独拷贝到其它电脑。第二讲:(14)c语言编程必备知识1.Cpu,内存条,硬盘,显卡,主板,显示器之间关系。Cpu不能直接处理硬盘上的数据,必须要先调入内存2.Helloword程序是如何运行起来的。3.什么是数据类型数据类型-数据的分类,对编程而言,首要考虑问题是

7数据的输入和存储。可以分为A:基本数据类型:整型整型int-4字节一字节byte=8位bit短整型shortint-2长整型longint-8浮点型单精度浮点数float:存储范围小-4双精度浮点数double:存储范围大-8Float和Double都不能保证将小数完全准确保存。字符char:c语言中是没有字符串string-1(区别于JAVA、C#中有string且C#中char为2字节)B:复合类型:就是把基本类型拼凑在一起结构体枚举一实用共用体一基本淘汰1.什么是变量变量的本质是内存中一段存储空间。IntI;i=5;I是变量,程序向系统申请了一个内存单元,在程序运行中,i的值可以改变,但程序结束后,其所占的空间不是释放,而是被系统收回权限。

81Cpu,内存条,VC++6.0,操作系统之间的关系。6变量为什么必须初始(即赋值)软件运行与内存关系(垃圾数据-9868598658)1.软件在运行前需要向操作系统申请存储空间,在内存空间足够空闲时,操作系统将分配一段内存空间并将该外存中软件拷贝一份存入该内存空间中,并启动该软件运行。2.在软件运行期间,该软件所占内存空间不再分配给其他软件。3.当该软件运行完毕后,操作系统将回收该内存空间(注意:操作系统并不清空该内存空间遗留下来的数据),以便再次分配给其他软件使用。《操作系统》一门课中系统分配表中会讲到,用1标记表示内在是被占用的,用0标记表示是空闲的。综上所述,一个软件所分配到的空间中极可能存在着以前其他软件使用过后的残留数据,这些数据被称之为垃圾数据,所以通常情况下我们为一个变量,为一个数组,分配好存储空间之前都要对该内存空间初始化。7如何定义变量数据类型变量名称=赋予的值;等价于数据类型变量名;变量名=要赋予的值;

9举例子: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(零),十六进制前面加Ox。在汇编中:在数学后加字母B表示二戏制救,加字母O表示八我制救,加字母D表示+式制数,加字母H表示十六进制敷。II例:10UB为二进制数1011,也记为(1011)213570为人进制数1357,也记为(1357)」2049D为十进制数2049,也记为(2049)103FB9H为十六进制数3FB9,也记为(3FB9),

10B什么叫n进制■八进制・8个基数逢8进一・基数:01234567・8->109->1110->12■十六进制:■16个基数逢16进一・基数:012345・01234567■16->1017->11常用计数制对照表:6789ABC89abed18->12出EF或ef19->13.常用计数制对昭八、、表十进制(D)二进制(B)八进制(0)十六进制(H)高工昆⑥二居98765432-001101110010111011110001001101010111100110111101111012345671011121314151617fCdCbp)987654321。1Printf的基本用法:printf(^i=%d

11”,i):/*printf的用法

12%d表示以十进制输建%*或%乂表示以十六递制输出%o表示以八进制输出*/9常量在c中是如何表示的十进制:传统的写法十六进制:前面加Ox或0X八进制:前面0注意是数字零不是字母。浮点数传统的写法floatx=3.2;//传统科学计数法floatx=3.2@3;〃x的值是3200floatx=123.45e-2;〃x的值是1.2345I字符当个字符使用单引号括起来,多个字符串使用双引号括起来(指针、数组)。intmain(void)floatx=123.45e-2F|;1printf(*%f

13*,x);return0;1在c中,默认是double类型的。在后面加F表示当做float来处理,否则会有警告提示--丢失部分字节。

1410常量以什么样的二进制代码存储在计算机中?编码:整数是以补码的形式转换为二进制代码存储在计算机浮点数是以ieee754标准转换为二进制代码存储字符本质实际是与整数的存储方式相同,ASII码标准。第三次课:代码规范化•可以参考林锐《高质量C/C++编程》•代码的规范化非常的重要,是学习一门编程语言的基础,代码可以允许错误,但不能不规范。例如:成对敲括号。()加空格于运算符和数字之间1=1+2;加缩进分清上下级地位。换行-进行功能区域分隔or{}括号单独成一行。•代码规范化的好处1:整齐,别人和自己都容易看懂。2:代码规范了,代码不容易出错。3:一般的程序可以分为三块:a:定义变量b:对变量进行操作C:输出值

15什么是字节•存储数据的单位,并且是硬件所能访问的最小单位。内存中存储的最小单位是位bit(O或1),但是硬件控制的时候不能精确到位,只能精确到字节(8位),是通过地址总线来控制的,而精确到位是通过软件来控制的,叫做位运算符来精确到位的。1字节=8位1K=1024字节1M=1024K1G=1024M1T=1024G2G的内存条的总空间:2*1024*1024*1024*8=4*1032不同类型数据之间相互赋值的问题不同数据类型之间最好不要相互转换。inti=45;longj=102345,i=j;printf(*%ld%d

16*,i,j);floatx=6.6;doubley=8.8;printf(*%f%lf

17,x,y").inti-;如果需要明白这个知识点,那么需要明白补码。什么是ASCII码以char定义变量的时候,只能使用单引号括起一个字符才是正确的。Kincludeintmain(void)Icharch='A',〃4行OK等价charch,*'A'//charch=*AB\//error因为"AB"是字符串,我们不能把字符串赋给单个字符//charch="A";//error//charch='AB',//'AB'是错误的

18//charch=*B\//error,因为ch变量巳经在4行定义了,这样会导致变量名被:ch-C,printf(*%c

19*,ch);在上图中注释的最后一样是重复定义了ch的值,是错误的,而下面的ch二七是指把C赋值给ch,是正确的。itinc1ude〈stdi。.h>intmainXx^id)clmrLhy='b'.printTv%d

20*,ch),return0;)上图中输出的值是98(将字符以整数%d的形式输出)Ascii码规定了ch是以哪个值去保存,ascii码不是一个值,而是一种规定,规定了不同的字符是以哪个整数值去表示。其它规定还有GB2312UTF-8等。14.什么是ASCIIASCII不是一个值,而是一种规定,ASCII规定r了不同的字符是使用哪个整数值去表示它规定了1'A'"65'B'—66'a'——97'b"一989Q9——48字符本质上与整数的存储方式相同【字符的存储】基本的输入和输出函数的用法:第三次课Printf()将变量的内容输出到显示器上。四种用法1.printf("字符串");2.printf("输出控制符:输出参数);3.printf「输出控制符1输出控制符2...”,输出参数1,输出控制符和输出参数的个数必须一一对应4.printf("输出控制将非输出控制符",输出参数)|,

21输什么是输出控制符,什么是非输出控制符输出控制符包含如下:%d%ld%c—%f%lf%x(或者%X后者%#X)%o%sIintlongintcharfloatdoubleint或longint或shortint同上字符串1Printf为什么需要输出控制符:•01组成的代码可以表示数据也可以表示指令。必须要有输出控制符告诉他怎么去解读。■如果01组成的代码表示的是数据的话,那么同样的01代码组合以不同的格式输出就会有不同的输出结果,所以必须要有输出控制符。intmain(void)(intx=47;//100是十进制printf(*%x

22*,x);〃输出结果是:2fprintf(*%X

23*,x);//输出结臬是:2Fprintf(*%#X

24*,x);〃输出结果是:OX2F|printf(*%#x

25*,x);〃输出结果是:0x2freturn0;}在上图中,intx=47,如果前面加0(零)048表示的是八进制,如果前面加Ox(零x)0X47则表示的是十六进制,而在输出的时候,则是0(字母o)表示八进制,ox(字母。,x)表示十六进制。非输出控制符:非输出控制符在输出的时候会原样输出。•••_.■,1,・,•・t"•・\・•I———,"•••・)

26printf(*i=%d,j=%d

27*,j,k);Scanf()通过键盘将数据输入到变量中有两种用法:用法一:scanf("输入控制符",输入参数);功能:将从键盘输入的字冷转化为输入控制符所规定格式的数据,然后存入以输入参数的值为地址的变量中|示例:#includeintmain(void)(inti;scanf(袋d。&i);//&i表示i的地址&是一个取地址符printf(i=%d

28",i);return0;|非输入控制符:在输入的时候也会原样输入。用法二:scanf("非悔入控制符检入控制符,检入参数);功能:将从键盘怆入的字符转化为怆入控制符所规定格式的数据,然后存入以输入参数的值为地址的变量中非输入控制符必须原样输入ttincludeintmain(void)(inti;scanf&i),printf(*i=%d

29\i)]return0;}但是强烈建议:在使用scanf的时候,不使用非输入控制符。给多个变量赋值:Uinclude

30intmain(void)(inti,j;scanf(*%d%d",&i,&j);Tprintf(*i=%d,j|=%d

31H»i,j);return0;)需要记住,非控制符需要原样输入。如何使用scanf编写出高质量代码如何使用scanf编写出高质量代码1.使用scanf之前最好先使用printf提示用户以什么样的方式来输入2.scanf中尽量不要使用非输入控制符,尤其是不要用

32|

33intmain(void){inti;[scanf&i);〃非常不好的格式,不要加

34printf(*i=%d

35”,i);return0;)1.应该编写代码对用户的非法输入做适当的处理【非重点】while((ch=getchar())!=9

36)continue;|ftincludeintmain(void)|inti;charch;scanf("%d",&i);printf(*i=%d

37”,i);I//while((ch=getchar())!='

38')Y/continue;intj;scanf("%d",&j);printfj=%d'n”,j);return0;}运算符:算术运算符:加(+),减(一)乘(*)除(/)取余(%)关系运算符:>,>=,<,<=,!=,逻辑运算符:

39!(非),&&(且),||(或)

40真真假假假真真真假!(非),&&(并且)||(或)!真假!假真我也真真也也假假&也真假&&假真II假假II真真II真假II假C语言对真假的处理非零是真零是假]真是1表示假是。表示&&左边的表达式为假右边的表达式肯定不会执行I|左边的表达式为真|右边的表达式肯定不会执行赋值运算符:=,+=,*=,/—例如:a+=3是等价于a=a+3,a/=3等价于a=a/3其优先级别是算术〉关系〉逻辑〉赋值。

41■除法与取模运算符■除法/的运算结果和运算对象的数据类型有关,两个数都是int,则商就是int,若商有小数,则截取小数部分;被除数和除数中只要有一个或两个都是浮点型数据,则商也是浮点型,不截取小数部分。如:16/5==316/5.0==3.20000-13/4==-4-13/-3==43/5==05/3==1最典型的例题就是求s=1+1/2+1/3+1/4+1/5....+1/100的值(具体程序我们以后再讲).■取余%的运算对象必须是整数,结果是整除后的余数,其余数的符号与被除数相同如:13%3=(113%-3==1-13%3==-1-13%23==-133%5==3・测试取模运算符的例子.1.#include2.intmain(void)3.(printfC%d%d%d%d%d%d飞,・13%3.43%3,・13%23,3%5);5.return0;6.}7.r8.输出结果是:°♦****♦*****************•*********,*********10.01-1-1-13311.Pressanykeytocontinue._***•***•****••・・・**・・****・・•********♦********♦12.总结:取余%的运算对象胸是整数,结果是雌后的余数,其余数的符号与祓除数相同14.*/取余的结果的正负只和被除数有关。第四节流程控制(第一个重点):

421.什么是流程控制程序代码执行的顺序。2.流程控制的分类顺序执行选择执行定义:某些代码可能执行,可能不执行,有选择的执行某些代码。分类:if1.点最简单的用法2.if的范围问题3.if..else...的用法4.if..elseif...else...的用法5.C语言对真假的处理6.if举例一求分数的等级7.if的常见问题解析If最简单的用法:1.if最简单的用法格式:if(表达式)语句功能:如果表达式为真,执行语句如果表达式为假,语句不执行#includeintmain(void)|if(3)printf(*AAAA

43*);〃会输出if(0)

44printf;//不会输出if(0==0)printf(*CCCC

45*);//会输出return0;1.if的范围问题1.if(表达式)语句A;语句B;解释:if默认只能控制语句A的执行或不执行if无法控制语句B的执行或不执行或者讲:语句B一定会执行,"if就认的只能控制一个语句的执行或不执行|if(表达式){语句A;语句B;)此时if可以控制语句A和语句BI由此可见:if默认只能控制一个语句的执行或不执行如果想控制多个语句的执行或不执行就必须把这些语句用{}括起来|如果想控制多个语句的执行或者不执行,那么需要使用{}括起来。3.1f...else...的用法:#includeintmain(void)|inti[j;scanf(*%d%dT,&i,&j);

46if(i>j)printf("i大于j

47");elseprintf("i小于j'n");return0;)Uincludeintmain(void){if(1|>2)printf("AAAA

48");elseprintf;printf("CCCC'n");return0;}if...elseif...else的用法:if(1)A■elseif(2)既elseif(3)C;elseD;Sincludeintmain(void){doubledelta=3;if(delta>0)printf("看两个解八n");elseif(delta==0)printf("有一个唯一解!、n");elseprintf("无解!、nf);

49return0;C错误的if...elseif...else语句:#includeintmain(void)(doubledelta=-1;if(delta>0)尸rintf("看两个解!、n");Iprintf("哈哈!、n");elseif(delta==0)printf("有一个唯一解八n");elseprintf("无解!

50");return0;}在上图中,当执行到哈哈那句时,下面的else将会被算作另外一个语句来执行,而在我们的c语言中,没有以else开头的语句。所以会出错。If实例:ttincludeintmain(void)(floatscore;〃score分数printf("请输入您的考试成绩:”);scanf('%f”,fescore);if(score>100)printf("这是做梦八n");elseif(score>=90&fcscore<=100)//不能写成90<=score<=100printf("优秀!

51");elseif(score>=80&fcscore<90)printf(〃良好!

52*);elseif(score>=60&&score<80)ppntf("及格!;elseif(score>=0&&score<60)printf("不及格!继续努力!

53f);

54If常见的问题:变量的替换:intt;〃定义临时变埴,/6和7行代码无法完成代IIj的互换//i=j;//6fj*i=5;j=5;//j=i://7ffi=5:j=5:I//iE确的彳.换i和j的方法It=i:*♦1=j:j=t:printfCi=%d,j=%d

55”,i,j);return0;求三个数字的大小:inta,b,c;〃等价于:inta;intb;intc;intt;printf「请输入三个整数(巾间以空格分隔):,・);scanfC^d%d%d",&a,&b,&c);〃编写代码完成a是最大值b是中间值c是最小值if(aif(aif(bprintf(',%(1%d

56'i,a,b,c);return0;c语言常见误区:纸老虎

57素数:只能被1和自己整除的数,如159等。回文数:正着写和倒着写一样的数。如1221,121,等编程实现求一个十进制数字的二进制形式:求一个数字的每位是奇数的数字取出来组合形成的新数字。求一个数字到过来的数字。1:如果不懂,那么就看答案。看懂答案在敲。没错误了,在尝试改。如何看懂一个程序:1.流程:2.每个语句的功能:3.试数:对一些小算法的程序:1.尝试自己编程结局。2.解决不了,看答案。3.关键是把答案看懂。4.看懂之后尝试自己修改程序,且知道修改之后程序的不同输出结果的含义。5.照着答案去敲6.调试错误7.不看答案,自己独立把程序编出

581.如果程序实在是彻底无法了解,就把他背会。空语句的问题:7.if的常见问题解析1.空语句的问题if(3>2);等价于工if(3>2);〃这是一个空语句intmain(void)(if(1>2)printf;printfCBBBB

59");return0;1在上图中,最终的结果会是AAAA,BBBB,程序也不会报错,为什么呢,因为在程序执行的时候,会在;哪里认为是一个空语句。也就是说,如果if成立,那么执行空语句。If常见错误解析(重点)#includeintmain(void)(if(3>2)〃4行如果这里加分号,则会导致程序编译到6行时就会出错printfJ;"哈哈!

60");flse〃6行printf("嘿嘿!

61*);return0;)上面这个程序是错误的,为什么呢,在该程序中,总的有4个语句,而在以else开头的那个语句中是有错误的,因为在c

62语言中是没有以else开头的这种语法。

63if(表达式1)A:elseB;是正确的if(表达式1);|IA;elseB;是错误的#includeintmain(void)(if(3>2)printf("AAAA'n");elseif(3>1)printf(*BBBB

64*);elseIprintf("CCCC'n");return0;在上面这个程序中,最终的值是AAAA,虽说后面的3>1也满足条件,但是当3〉2满足条件后,该if语句就会终止,后面的语句是不会在执行的。

65if(表达式1)A;elseif(表达式2)B;elseif(表达式3)C;这样写语法不会出错,但逻辑上有漏洞if(表达式1)A;elseif(表达式2)B;elseif(表达式3)C;else1(表达式4)〃7行D;这样写是不对的,正确的写法是:要么去掉7行的(表达式4)要么在else后面加if|既然7行要写表达式,就要写if。if(表达式1)A;elseif(表达式2)B;elseif(表达式3)C;Telse(表达式4)D;这样写语法不会出错,但逻辑上是错误的

66else(表达式4);D;等价于else(表达式4);D;I循环的定义、分类。定义:某些代码会被重复执行。分类:forwhiledowhile#includeintmain(void)(inti;intsum=0,一for(i=l,i<=4|,++i)sum=s心+i;4printf(*sum=%d

67”,sum);return0,在上图中,先执行1,在执行2,2如果成立,标志着循环成立,那么在执行4,最后在执行3,3执行完后代表一次循环完成,然后在执行2.以此类推。1永远只执行一次。++I等价于i+1求1-10的所有奇数的和:intmain(void)(inti;intsum=0;for(i=l;i<10;i+=2)//i+=2,等价于i=i+2;(

68sum=sum+i|;)return0;)求1-12之间的所有能被3整除的数字之和:intsum=0;for(i=3;i<=12;++i)(if(i%3==0)〃如果i能被3整除sum=sum+i;}printf(*sum=%d

69*,sun{);return0;}For所控制的语句:hinclude〈stdio.h>intmain(void)(Iinti;for(i=l;i<4;++i){printf("AAAA'n");printf(*BBBB

70*);)return0;)在上图中,for默认只能控制一个语句,但是如果要控

71制多个语句时候,那么需要使用。把语句括起来。求1+1/2+V3....V1OO的和#includeintmain(void){inti;floatsum=0;for(i=l;i<=100;++i)(sum=sum+1/(float)(i尢printf(*sum=%f

72*,sum);//f必须用%f输出return0;在上图中,重点是强制数据类型转换也就是(float*)那句:强制类型转化格式:(数据类型)(表达式)功能:把表达式的值强制转化为前面所执行的数据类型例子:(int)(4.5+2.2)最终值是6(float)(5)最终值是5.000000如果把print那句换为下面这句会怎么样呢://sum=sum+1(float)(1/i);也是错的,为什么呢,因为i是整型,1也是整型,所以不管你怎么转换也是整型啊,如果想要这样写的话,那么我们需要把1改成1.0也可以的。也就是:〃更简单的写法是:sum=sum+i.O而;试数详细步骤举例:l->i=l1<=100成立sum=O+l/l.00=1++ii=22->i=22<=100成立sum=l+l/2.0++ii=33->i=33<=1001sum=l+l/2.0+1/3.0++ii=41

73浮点数存取:浮点数的存错所带来的问题float和double都不能保证可以精确的存储一个小数举例:|有」个浮点型变量X,如何判断x的值是否是零if(|x-0.0000011<0.000001)是零else不是零为什么循环中更新的变量不能定义成浮点型求1-100之间所有奇数的和:#includeintmain(void){inti;intsum=0;for(i=l;i<101;++i){Iif(i%2==1)sum+=i;//sum=sum+i;}.〃”printf(*sum=sum);return0;求1-100之间的奇数的个数:

74intmain(void)(inti;intent=0;〃个数一般用ent表示for(i=l;i<101,++i)(if(i%2==1)++cnt;)printf(*cnt=%d

75”,ent);求1-100之间奇数的平均值:inti;intsum=intent=floatavg;for(i=l;i<101;++i)(if(i%2==1)(sum+=i;++cnt;))//I.0默认是double类型sum);ent);avg),avg=1.0*sum/ent;printf(*sum=%d

76",printf(*cnt=%d

77",printf("avg=%f

78*.求1-100之间的奇数之和,在求1-100之间的偶数之和:

79//奇数和〃偶数和for(i=l;i<101;++i)(if(i%2==1){suml+=i;)else{,sum2+=i;|))printf("意数和=%d

80*,suml);printf("隅数和=%d

81*,sum2);多个for循环的嵌套使用:多个for猛环而最《使用for(1;2;3)//Ifor(4;5;6)//2A,//3B;//4整体是两个语句,123是第一个语句4是第二个语句整体是两个语句。上图中,先执行1,在执行2,如果2成立,执行4,在执行5,如果5成立执行A,在执行6,在执行5,如果5不成立,意味着里面的循环结束,然后执行3,在执行2,如果2成立又执行4,在执行5,如果5成立在执行6,在执行5,如果5不成立,在执行3,在执

82行2,如果2不成立,意味着本次循环结束,在执行B,在上图中,需要注意的是,如果2成立的话,那么每次4都需要执行。for(1;2;3)for(4,5;6)|A,B;)整体是L个语句3.for(7;8;9)for(1;2;3)(IA;!'B;for(4,5;6)C;)整体是一个语句|进制之间的转换:如234为5进制,那么转换成10进制是多少:2x5x5+3x5+4的值就是转换成的10进制。234e是16进制,转换成2进制是多少:2x16x16x16+3x16x16+4x16+12的值就是转换成10进制的值。注意上面的规律。那么把十进制转换成r进制呢,其实很简单,就是把10

83进制数除以r,直到商是。的时候。然后取余数,余数倒序排列:(185)10=(?)22I,185余数(39瓢)1。=(?)161616163981余数24813(D)158015(F)(3981)I。=(F8D)I。琐碎的运算符:自增:自增[或需自成],分类:前自增一++i后自增-i++前自增和后自增的异同:相同:最终都使i的值加1不同前自增蝮体表达在的值是i加1之后

84的值后自增整体表达K的值是i加1之前I的值#includeintmain(void)(inti;intj;intk;intm,i=j=3;〃节价于i=3,j=3.k=-i++;m=++j;printf(Mi=%d,j=%d,k=%d,m=%d

85*,i,j,k,m);return0;在Vc++6.0中的榆出结果是:4,j=4,k=3,m=4总结:前自增整体表达式的值是i加I之后的值后自强整体表达式的值是i加1之前的值学习自增要明白的几个问题1.我们编程时应该尽量屏蔽掉前自增和后自培的差别2.自培表达式最好不要作为一个更大的表达式的一部分来使或者说i++和++i单独成一个语句,不要把它作为一个完整复合语句的一部分来使用自减:和自增一样。三目运算符:A?B:t等价于

86if(A)B;elseIIc;|#includeintmain(void)(inti;i=(Ob2?5:1);printf(*%d

87*,i),return0,)最终的输出结果是1.逗号表达式:格式(A,B,C,D)功•从左到右执行I最终表达式的值是最后一项的值IUincludeintmain(void)Iinti,i=(3,2,5,6);tprintf(*%d

88*,i);Ireturn0,}最终结果是6.intmain(void)(inti;intj=2;Ii=(j++,++j,j+2.j-3);printf(*%d

89*,i)Jreturn0,)

90上图中,逗号是个顺序点,即所有的副作用必须在下个语句前生效,其最后结果为1,j+2只是产生临时值,并没有把j+2的值赋个j。如果写成j+=2,那最后的值则变为5.For的嵌套使用举例:#includeintmain(void)(inti,j;for(i=0;i<3;++i)for(j=2;j<5,++j)printf("哈哈!

91*);printf("嘻嘻!

92"),|return0;)上例中输出的结果是9个哈哈,1个嘻嘻。

93x)z+!\JZ"+-^"A7n唯n•1\\•I人a\\+!5联!+嘿j<厂嘻3嘿;t嗜<"2n"izf\--i(f-Jrf••t(ptonn--r»1•1ror(pfprfoTh7return0;在上图中,整个程序分成3个语句,输出的结果是3个嘿嘿,3个哈哈,1个嘻嘻。#includeintmain(void){inti,j;for(i=0;i<3:++i){printf("111!

94");for(j=2;j<5:++j){Iprintf("222!

95"),printf("333!

96"),)printf("444|!

97");}return0;其结果是:

98111?222?333?222?333?等444?111?222?333?222?333?222?333?444?111?222?333?222?333?222?33314441While(先付钱后吃饭)1:执行的顺序:格式:while(表达式)语句;2:与for的相互比较:用for来求1-100之和:

99hinclude〈stdio.h>intmain(void)(intsum=0;inti;for(i=l;i<101;++i)(sum=sum+i;}printf(*sum=%d

100”,sum);return0;)用while实现1-100之和。只需要把for语句替换为:i=1;while(i<101){^um=sum+i;++i;For和while是可以相互转换的,可以用下面的表达式来表示:forQj2;3)等价于I;while(2)(A;3;IIWhile和for在逻辑上完全等价,但是for在逻辑上更

101强。更容易理解,更不容易出错。推荐多使用for。

1023:while举例:乐键盘愉入一个数字,如果该数字是回文数,则返回yes,否则返回no回文数:正着写和倒着写都一样比如:|12112321|ttincludeintmain(uoid)intual;〃存放待判断的数字intm;intsum=0;printf(“请输入您需要判断的数字:");scanFC%d",&ual);m=ual;while(m)if(sum==ual)printf("Ves!

103");elseprintFC^NotXn");return0;>试数:1>2>3>4>5>m^l234成立sum-0*10+1234%10-4■=■710-123;m=123成立sun=4*l0+123%10=43ib-123/10=12n=12成立sum-43*10+12%10=432m-12/10=1sum-432*10+l%10=4321n=l/10^0m0不成立最终sum=4321通过上面的试数,应该能很快的理解回文数的算法。

104菲波拉契序列12358132134»/tincludeIntnain(uoid)[intn;intF1,F2,f3;inti;F1-1;F2=2;printf(“请输入您需要求的想的序列:“);scanf("%d",&n);if(1==n){F3=1;>elseif(2==n)else

105”,F3);return0;f358立1=立1=立1=立1=成成f成f成f成f不1=33<=6f3=1*2=32>3>4>5>4:什么时候使用while,什么时候使用for:没法说,用多了就自然而然知道了Do...while(先吃饭后付钱)格式do}while(表达式);

106<$o...while.并用等价于for,当然也不等价于while主要用于人机交互元二次方程:

107Itinclude#includeintnain(uoid)(doublea9b,c;doubledelta;doublex1,x2;charch;doprintf(“请输入一元二次方程的三个系数:

108”);printf("a=");scanFCUf",&a);printf("b=°);scanFCUf",&b);printFC'c=");scanFCUf,&c);delta=b«b-4*a*c;if(delta>0)elseiF(O»=delta)

109");print"“您想继续么(Y/N):");scanfC%c",&ch);〃乳前面必须得加一个空格原因略}while(,y'==ch||"V'==ch);return0;>Switch的用法:电梯程序:

110Mincludeintmain(uoid)

111”);break;case2:printf(“2层开八n”);//break;case3:printf「3层开?

112”);break;default:printf(“没有盖到这一层,

113");break;>return0;}Case是程序的入口,当进入程序后,程序会从上往下执行,如果有break,那么会中断程序,如果没有,那么会一直执行。■switch(表达式)■{■case常量表达式1:语句1;■case常量表达式2:语句2;■case常量表达式n:语句n;■default:语句n+1;

114Break的用法:break4flcontinuebreakbreak如果用于循环是用来终止循环break如果用于switch,是用于终lbswitchbnmk不筋直接用于if,除非if属于循环内部的一个千句#includeintmain(void)inti;/*switch(2)ricase2:printf("哈哈!

115");break;//OK,break可以用于switch#/for(i=0;i<3;++i)rif(3>2)break;〃break虽然是if内部的语句,〃但break终止的福息外部的for循环printf("嘿嘎!

116");)return0;#includeintmain(void)(inti,j,for(i=0,i<3;++i)(for(j=l;j<4,++j)break;V/break只熊终止距离它最叫妁崎杯printf("同志们好!

117"),}

118在多层循环中,Break只能终止他最近的循环。在多层switch中,break也是只能终止距离他最近的switchopincludeintmain()f{intx=l,y=0,a=0,b=0;switch(x)//第一个switch{case1:switch(v)//第二个switch{case0:a++;break;//终止的是第二个switchcase1:b++;break;)b=100;break;//终止的是第一个switchcase2:a++;b++;break;)“_printf("%d%d

119",a,b);〃26行return0;}Break只能用于循环和switch,不能用于if。如果用于if,必须要当循环中嵌套if的时候。Continue的用法:continue用于跳过本次循环余下的语句,转去判断是否需要执行下次循环case3:for(1;2;㉚(

120A;B;continue;〃如果执行该语句,则执行完该语句C;D;)O上图中,如果执行continue,那么C,D将不会被执行,会执行3.whilel(表达式)(A;B;continue;C;D;)在上图中,如果执行了continue,那么后面的C,D将不再执行,而会去执行表达式。

121intmain(void)rtinti;charch;scanf(?,%d/,,&i);printf(z/i=%d

122”,i);while((ch=getchar())!='

123')continue;intj;scanf(飞d",&j);printfj=%d

124”,j);return0;)数组:-非重点数组的使用:#includeintmain(void)(inta[5]={1,2,3,4,5};//a是数组的名字,3表示数组元素的个数,〃并且这5过热元素分别用这0]a[l]...a[4]inti;for(i=0;i<5;++i)printf(,,%d

125w,a[i]);|return0;)

126为什么需要数组1:为了解决大量同类型数据的存储和使用问题。2:用数组可以模拟现实世界。lnta[25]:一维数组,可以当做一个线性结构。Inta[8][6]:可以当做一个平面,意思是8行6列。有48

127个元素。Inta⑶⑷⑸:可以当做一个三维立体。Inta⑶⑷⑸⑹:可以当做一个四维空间。数组的分类一维数组怎样定义一维数组:•为n个变量分配存储空间:数组内存空间是连续的。•所有的变量类型必须相同:数组不可能第一个元素是整形,第二个元素是浮点型。•所有变量所占用的字节必须相等。例子:int[5]数组不是学习重点的原因?数组一旦定义,其长度是死的。有关一维数组的操作-都需要自己另外编程序实现而我们通常用第三方软件(工具)如数据库等方便直接地实现。对数组的操作:初始化赋值排序求最大/小值倒置查找插入删除,初始化:初始化完全初始与int[[5]={1,2,3,4,5};不完全初始化,未被初始化的元素自动为零inta[5]={1,2,3};不初始化,所有元素是垃圾值inta[5];清零

128inta[5]={0};错误写法:inta[5];a[5]={心2,3,4,5};〃错误只有在定义数组的同时才可以整体赋值,其他情况下整体赋值都是错误的inta[5]={1,2,3,4,5};a[5]=100;//error因为没有a[5]这个元素,上图中a[5]前面如果没有加上数据类型,那么这里的a[5]不是指一个数组,其中的5只的是下标。inta[5]={1,2,3,4,5}:intb[5];如果要把a数组中的值全部复制给b数组错误的写法:b=a;//error正确的写法for(i=0;i<5;++i)>[1]=a[i];上图中,数组的5个元素不是用a来代表的,是用a0/al...a4来代表的,所以说数组名a代表的不是数组的5个元素,数组名代表的是数组的第一个元素的地址。•赋值

129intmain(void){,inta[5];inti;scanf&a[0]),printfC*a[0]=%d

130",a[0]);scanf("d”,&a[3]);printfC*a[3]=另d

131",a[3]);for(i=0;i<5;++i)printfC*%d"a[i]);return0;把一个数组元素给全部倒过来:口includeintmain(void){inta[8]={1,2,3,4,5,6,7,8};inti,j;intt;i=0;j=7;while(i

132*,a[i]);

133return0;

134•排序•求最大/小值•倒置•查找,插入•删除二维数组:二维数组inta[3][4];总共是12个元素,可以当做3行4列看待,这12个元素的名字依次是a[0][0]a[l][0]a[2][0]a[i][j]a[0][1]a[0][2]a[0][3]a[ULUa[l][2]a[l][3]表示第i+1行第j+1列的元素[2][3]intatm][n];该二维数组右下角位置的元素只能是][n-1]二维数组的初始化:初始化inta[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};inta[3][4]={(1,2,3,4},{5,6,7,8),{9,10,11,12}输出二维数组内容:

135intmain(void)(inta[3][4]={(1,2,3,4),{5,6,7,8),{9,10,11,12));inti,j;〃馀出数组内容for(i=0;i<3;++i)(for(j=0;j<4;++j)printf(*%d”,a[i][j]);printf(*

136*):|return0:多维数组:是否存在多维数组:不存在因为内存是线性一维的,在内存中是不分行不分列的。N维数组可以当做每个元素是n-1维数组的一维数组。•••••••••••多维数组是否存在多维数组不存在因为内存是线性一维的n维数组可以当做每个元素是n-1维数组的一维数组比如:Iinta[3][4];该数组是含有3个元素的一维数组只不过每个元素都可以再分成4个小元素inta[3][4][5];该数组是含有3个元素的一维数组只不过每个元素都是4行5列的二维数组

137函数(第二个重点):

138“max是函蓼的名字,i刊j是形式参数,简称形参void表示函数没有返回值voidmax(inti,intj)rIif(i>J)printf("%d

139",i);elseprintf(飞d

140”,j);intmain(void)inta,b,c,d,e,f;a=1,b=2;c=3,d=9,e=-5,f=100;max(a,b);max(c,d);max(e,f);if(a>b)printf(*%d

141z,a);printf(*%d

142,z,b);if(c>d)printf(飞d

143”,c);elseprintf(飞d

144”,d);if(e>f)printf(飞d

145”,e);elseprintf(//%d

146\f);*/为什么需要函数:•避免了重复性操作。•有利于程序的模块化。(自上而下,逐步细化,大问题分解成小问题)用它作为参照,可以对比JAVA和C#面向对象的思想。C

147语言基本单位是函数,C#、C++和JAVA基本单位是类。什么叫做函数

148#includeintf(void)〃括号中的void表示该函数不能接受数据int表示函数返回值是int类型的数据{return10;//向主调函数返回10)voidg(void)〃8行函数名前面的void表示该函数没有返回值{.—return10;//error与8行行首的void相矛盾}intmain(void)intj=88;J=f0;printf(*%d

149*,j);//j=g();//error因为g函数没有返回值return0;}•逻辑上:能够完成特定功能的独立的代码块。物理上:能够接收数据【也可以不接收数据】,能够对接收的数据进行处理【也可以不对数据进行处理能够将数据处理的结果返【也可以没有返回值•总结:函数是个工具,他是为了解决大量类似问题而设计的,函数可以当做黑匣子(内部原理不用管)。如何定义函数•函数的返回值,函数的名字(函数的形参列表)|函数的执行体}•函数定义的本质:详细描述函数之所以能够实现某个特定功能的具体方法。函数中的变量叫做形参;数组中的变量叫元素。

150一旦函数执行完毕,其内部的形参所占空间就被收回。,return表达式的含义:Return是终止被调函数,向主调函数返回表达式的值,如果表达式为空,则只终止函数,不向被主函数返回任何值。例子:voidf()(retuiji;"return只用来终止函数,不向主调函数返回任何值)intf()return10;〃第一,终止函数,第二:向主调函数返回10}Break是用来终止(就近的)循环和switch语句。而return是用来终止被调函数的。口includevoidf(void){inti;for(i=0;i<5;++i)rprintf("大家辛苦了!

151");return;}printf("同志们好!

152*);Jintmain(void)fJf0;return0;)•函数返回值的类型,也称为函数的类型,因为如果函数名前的返回值类型和函数执行体中的return表达式中表达式的类型不同的话,则最终函数返回值的类型以

153函数名前的返回值类型为准。例:#includeintf()(return10.5;〃因为函数的返回值类型是int〃所以最终f返回的是10而不是10.5)intmain(void)rJinti=99;doublex=6.6;X=f();printf(*%lf

154/,,x);return0;)在上图中,函数的返回值以函数前的数值类型为准。函数的分类•有参函数和无参函数。•有返回值和无返回值。•库函数和用户自定义函数。,普通函数和主函数(main函数)1:一个程序有且只有一个主函数。2:主函数可以调用普通函数,普通不能调用主函数。3:普通函数可以相互调用。4:主函数是程序的入口,也是函数的出口。5:值传递函数和地址传递函数。

155//max是函婺的名字,i和J是形式参数,简称形参void表示函数没有返回值voidmaxi(inti,intj){if(i>j)printf("%d

156",i);elseprintf(*%d

157*,j);}intmax2(inti,intj)(if(i>J)returni;elsereturnj;}intmain(void){inta,b,c,d,e,f;a=1,b=2;c=3,d=9,e=-5,f=100;printf(飞d

158”,max2(a,b));printf(飞d

159”,max2(c,d));printfC%d

160^,max2(e,f));/*maxi(a,b);maxi(c,d);maxi(e,f);♦/return0;)|判断一个数是否是素数:

161intmain(void)(intval;inti;scanf("%d”,&val);for(i=2;i

162");elseprintf("No!

163");return0;)使用函数判断一个数是否是素数:

164*2009年11月4日11:18:51判断一个数字是否是素数用单独的函数来实现,代码的可重用性提高itincludeboolIsPrime(intval){inti;for(i=2;i

165");elseprintf("No!

166");return0;)函数和程序的调用应该注意的地方:

167intf(inti)(return10;}intmain(void)(inti=99;printf(*%d

168*,i);i=f(5);printf(*%d

169*,i),|return0;}函数的声明:#includevoidf(void){printf("哈哈!

170");)intmainCvoid){1f();Ireturn0;}当函数没有返回值时,那么规范的写法是要在函数中写明void的。在上图中,第一个void表示没有返回值,而第二个void表示不接收形参,也就是函数不接收数据。如果想把函数写在程序的后面,那么需要写函数声明:

171j^oidf(void);//函数声明,分号不能丢掉intmain(void)(f();return0;}voidf(void){printf("哈哈!

172");}函数声明的含义是告诉编译器f()是个函数名。如果不加函数声明,那么编译器在编译到f的时候,不知道f是个什么,如果加了函数声明,那么编译器编译到f的时候,就知道f是个函数。•需要注意的是,调用语句需要放在定义语句的后面,也就是说,定义函数的语句要放在调用语句的前面。

173*|2009年11月4日11:01:35一定要明白该程序为什么是错误的一定要明白该程序第9行生效之后程序为什么就正确了♦/#include//voidf(void);〃9行voidg(void)ff();//因为函数f的定义放在了调用f语句的后面,所有语法出错)voidf(void)printf("哈哈!

174");}intmain(void)fjg();return0;}

175如果函数调用写在了函数定义的前面,则必须加函数前置声明,函数前置声明的作用是:1:告诉编译器即将可能出现的若干个字母代表的是一个函数。“打招呼”2:告诉编译器即将可能出现的若干个字母所代表的函数的形参和返回值的具体情况。3:函数声明必须是一个语句,也就是在函数声明后需加分号。4:对库函数的声明也就是系统函数。是通过#include<库函数所在的文件的名字.h>来实现的。如stdio.h形参和实参要求:1:形参和实参个数是——对应的。

1762:形参和实参的位置也是——对应的。3:形参和实参的数据类型需要相互兼容。•如何在软件开发中合理的设计函数来解决实际问题。求1到某个数字之间的数是否是素数,并将他输出:合理设计函数1|/*2009年11月4日11:18:51判断一个数字是否是素数只用一个函数实现,不好,代码的利用率不高#includeintmain(void)(intval;inti;scanf&val);for(i=2;i

177");elseprintf(*No!

178");return0;)/*2009年11月4日11:18:51判断一个数字是否是素数用单独的函数来实现,代码的可重用性提高*./

179#includeboolIsPrime(intval){..inti;for(i=2;i

180");elseprintf("No!

181");return0;

1822009年11月4日11:18:51求1到某个数字之间(包括该数字)所有的素数,并将其输出只用main函数实现,有局限性:L代码的重用性不高2.代码不容易理解*/#includeintmain(void)fIintval;inti;intj;scanf(飞d”,&val);for(i=2;i<=val;++i)(〃判断i是否是素数,是输出,不是不输出for(j=2:j

183",i);return0;合理的设计函数4:

1842009年11月4日11:18:51求1到某个数字之间(包括该数字)所有的素数,并将其输出用1个函数来判断一个数字是否是素数优占•代码比如何设计函数3.cpp更容易理解代码的可重用性比如何设计函数_3.cpp高缺点:可重用性仍然不是非常高,比如有1000个数字,求它们每个数字从1到它本身的素数则for(i=2:i<=val;++i){if(IsPrime(i))printf(*%d

185*,i);)要写1000次#includeboolIsPrime(intm)(inti;for(i=2;i

186*,i);

187return0;

188[/*2009年11月4日11:56:29用两个函数来实现求1到某个数字之间所有的素数,并将其输出本程序和如何合理设计函数_4.cpp相比较代码量更少,可重用性更高一*/#include//本函数的功能是:判断m是否是素数,是返回true,不是返回falseboolIsPrime(intm)(inti;for(i=2;i

189”,i);}}intmain(void)(intval;scanf&val);TraverseVal(val);return0;}常用的系统函数和如何通过书籍来学习函数:Turboc2.0实用大全一机械工业出版社

190常用的系统函数IdoubleJqrt(doublex);求的x的平方根intabs(intx)求x的绝对值doublefabs(doublex)求x的绝对值递归:(略)栈:相当于一个杯子(容器)变量的作用域和存储方式:变量的作用域和存储方式:按作用域分:I全局变量局部变量按变量的存储方式静态变量自动变量寄存器变量全局变量和局部变量:局部变量:局部变曷在一个函数内部定义的变量或者函数的形参都统称为局部变量voidf(inti){intj=20;}Ii和j都属于局部变量局部变量的使用范围只能在本函数内部使用。

191全部变量:全局变量在所有函数外部定义的变量叫全局变量全局变量使用范围力从定义位置开始到整个程序结束*2009年11月6日9:33:02一定要明白该程序为什么是错的,也要明白把9到12行代码放在14行后面,为什么程序就0K了#includevoidg()//9{printf("k=%d

192*,k);}//12intk=1000;〃14行voidf(void)(g();printf("k=%d

193*,k);intmain(void)(f();return0;)|全局变量和局部变量命名冲突的问题:在同一个范围之内不能定义两个一样的局部变量:

194*include/oidf(inti){I..inti;printf(*i=%d

195*»i);}intmain(void)(f(8);在一个函数内部,如果定义的局部函数的名字和全局变量名一样时,局部变量会屏蔽掉全局变量:ttincludeinti=99;voidf(inti)_{Iprintf(*i=%d

196”,i);}intmain(void)(f(8);return0;)上例中最终的输出结果是8,因为局部变量把全局变量给屏蔽掉了。指针:(C语言的灵魂)内存的存储是以一个字节为一个编号,也就是8位合在一起给一个编号,不是0,1就给编号。内存分为很多个单元,每个单元就会分配一个编号。

197地址:内存单元的一个编号。而指针和地址一个概念的。也就是说指针就是地址。#includeintmain(void)int*p;//p是变量的名字,int*表示p变量存放的是int类型变量的地址inti=3;p=&i;//OK//p=i;//error,因为类型不一致,p只能存放int类型变量的地址,不能存〃放int类型变量的值//p=55;//error原因同上return0;普通变量:只能存放一个值。指针变量:同样是一个变量,但是指针变量存放其他变量的地址。#includeintmain(void)(int*p;〃p是变量的名字,int♦表示p变量存放的是int类型变量的地址//int*p;不表示定义了一个名字叫做*p的变量int*p;应该这样理蟀:p是变量名,p变量的数据类型是int*类型//所谓int♦类型实际就是存放int变量地址的类型inti=3;intj;P=&i;/*1.p保存了i的地址,因此p指向i2.p不是i,i也不是p,更准确的说:修改p的值不影响i的值,修改i的值也不会影响P的值3.如果一个指针变量指向了某个普通变量,则*指针变量就完全等同于普通变量例子:如果P是个指针变量.并且p存放了普通变量i的地址则P指向了普通变量i*p就完全等同于i或者说:在所有出现*P的地方都可以替换成i在所有出现i的地方都可以替换成*P*P就是以p的内容为地址的变量*/j=*P;//等价于j二i;printf(*i=%d,j=%d

198*,i,j);return0;*p代表的是p所指向的那个变量。在上图中*p和i是同一个东西,但是*p和p不是同一个东西。在上图中,int*p是一个声明,开头的int*是他的数据类型。P是变量的名字。不能理解我定义了一个整形

199变量,这个整形变量的名字叫做*p。所谓int*类型,实际就是存放int变量地址的类型。*p代表的是以p的内容为地址的变量。解析:p的内容是一个地址,在上图中,p的内容就是i的地址,*p其指向的变量当然就是i变量了。指针和指针变量:指针就是地址,地址就是指针。地址就是内存单元的编号。指针变量:存放地址的变量。而指针只是一个值,这个值是内存单元的一个编号。指针变量才是一个变量,他里面才可以存放数据。指针和指针变量是两个不同的概念,但是需要注意的是,通常我们在叙述时会把指针变量简称为指针,实际他们含义并不一样。指针的重要性:指针:表示一些复杂的数据结构快速的传递数据使函数返回一个以上的值能直接访问硬件能够方便的处理字符串是理解面向对象语言中引用的基础|J息结:指针是c语言的灵魂指针的分类:

200指针的分类1.1基本类型指针2.指针和数组3.指针和函数4.指针和结构体5.多级指针指针的定义:•地址:内存单元的编号,是一个从。开始的非负整数。范围:cpu对内存是通过控制、数据、地址三条总线来进行控制的。斯宋体-71pV]|CMIHKI_GB2312能直接访问能够方便的Gj"向4结:指针指针的定义地址内存单从零开范围:字符串-3uI到厂II正I0-指针的分类控制:cup会先把内存中的数据读入,进行处理后,在返回给内存,然后内存在把数据写入硬盘。数据:用于数据的传输,不管是把内存中的数据发送给CPU,还是把CPU的数据写如内存条,都是由数据线来

201完成的,但是数据传输的方向则是由控制线来控制的。地址:地址线则是确定数据要写入内存中的那个单元。所谓的一个单元就是一个字节。口「~,也加_82312^|U|M|||:=|能直接访.里堆能够方便的处理字符串:是理解面向对象语言中引用的基础总结:指骨是c语言的灵魂指针的定义1地址I内存.2元的编号,从零阡始的非负整效范围'"一二:cf呦的分类•14-'A'15,•-16-•17-।一条地址总线能控制2的1次方,一般的机器有32个地址线,最终能够控制2的32个单元,而每个单元是八位,而最终我们的内存能够存储2的32次方*8位。则换算为G的话,最终大小为4G.那么地址总线的范围则是4G大。指针:指针就是地址,地址就是指针。指针变量就是存放内存单元编号的变量。指针变量和指针是两个不同的概念。指针的本质就是一个操作受限的非负整数。指针不能进行算术运算-相力口乘除。但是能相减。如果两个指针变量指向的是同一块连续空间的不同存储单元,则这两个指针变量才可以相减。类似于同一个小区同一楼层

202六牌号相减表示两房间隔。这时才有现实意义。基本类型的指针:Uincludeintmain(void)(int*p;inti=5;*P=i;printf*p);return0,1}Int*p:p只能存放int类型的地址。P;&i:把i的地址赋给p。然后p就指向了i,*p就等于i。其实就是1:该语句保存了i的地址。2:p保存了i的地址,所以p指向i。3:p既然指向i,*p就是i。*p:表示以p的内容为地址的变量。*p:p是有指向的,p里面是个垃圾值,*p则是说以p的内容为地址的变量。因为不知道p的值是多少,所以不知道*p到底代表的是那个变量。而*p=i,i=5,最终的结果就是把5赋给了一个所不知道的单元。#includeintmain(void)inti=5;int*p;int*q;P=&i;//*q=p;//error语法编译会出错

203*q=*p;/errorP=Q;//Q是垃圾值,q赋给P,_P也变成垃圾值printf(*%d

204*,*q);〃13行/*q的空间是属于本程序的,所以本程序可以读写q的内容,但是如果q内部是垃圾值,则本程序不能读写*q的内容因为此时*q所代表的内存单元的控制权限并没有分配给本程序所以本程序运行到13行时就会立即出错♦/return0;)上图中,第一个error是数据类型不符合,不能相互转换。*q代表的是整形,因为*q代表的是以q的地址为内容的变量。而p是地址(int*)类型。第二个error同样有错,因为q没有赋值。经典指针程序-互换两个数字:1:先用函数来互换:

205voidhuhuan(inta,intb)(intt;|tt=a;a=b;b=t;return;)intmain(void)(inta=3;intb=5;huhuan(a,b);printf(*a=%d,b=%d

206”,a,b);最终的输出结果没有互换,因为函数的a,b已经执行完成,分配给内存的空间已经释放了,所以最终a,b的值还是主函数a,b的值。互换的是形参的a,b0和主函数没有关系。

207在上图中,输出的值也是没有互换的,输出的同样是3

208,5,需要注意的是,互换的只是p、q的内容,局部函数变化了,但是主函数是没有变化的。最终正确的程序:

209voidhuhuan_l(int,int);voidhuhuan_2(int*,int*);voidhuhuan_3(int*,int*);intmain(void)rinta=3;intb=5;huhuan_3(&a,&b);//huhuan_2(*p,*q);是错误的,//huhuan_2(a,b);也是错误的printf("a=%d,b=%d

210”,a,b);return0;)〃不能完成互换物能voidhuhuan_l(inta,intb)(一intt;t=a;a=b;b=t;return;)〃不能完成互换为能voidhuhuan_2(int*p,int*q)rint*t;//如果要互换p和q的值,则t必须是int*,〃不能是int,否则会出错t=P;P=Q;Q=t;)〃可以完成互换顼能voidhuhuan_3(int*p,int*q)f-intt;//如果要互换*p和*q的值,贝!It必须定义成int,//不能定义成int*,否则语法出错t=*p;//p^int*,*p^int*p=*q;*Q=t;)

211*号的三种含义:1:乘法2:定义指针变量。Int*p,定义了一个名字叫p的变量,int*表示p只能存放int变量的地址。3:指针运算符。该运算符是放在已经定义好的指针变量的前面。如果p是一个已经定义好的指针变量,贝HP表示以p的内容为地址的变量。注意理解形参,实参,和局部变量的关系。#includeintmain(void)(int*p:〃",价J,int*p:也',价「int*p:inti=5:charch='A':p=&i:'i*p以p的内容为J也川*p=99:printf(i=%d,*p=i,*p)://p=&ch://p=ch://error//p=5://errorreturn0:指针可以是函数返回一个以上的值:

212intf(inti,intj)(return100://return88:)intmain(void)tinta=3,b=5:a=f(a,b):b=f(a,b):不使用指针的话,只能使用用return来返回一个值。如何通过被调函数修改主调函数普通变量的值如何通过被调函数修改主调函数件通变量的值1.实参必须为该普通变量的地地2.形参必须为指针变良3.在被调函效中通过*形善名=....」的方式就可以修改主调函数相关变坦的值voidg(int*p,int*q)(ft)=1:*q=2:)Iintmain(void)(inta=3,b=5:g(&a,&b):printf(%d%d

213,a,b):return0;指针和数组:指针和一维数组:(数组名下标与指针关系指针变量的运算)

214•一维数组名:一维数组名是个指针常量,他存放的是一维数组第一个元素的地址。#includeintmain(void)rinta[5];〃a是数组名5是数组元素的个数元素就是变量a[0]-a[4]inta⑶⑷;〃3行4列a[0][0]是第一个元素a[i]㈤第i+1行j+1列intb[5];//a=b;//errora是常量printf(*%#X

215*,&a[0]);printf(*%#X

216*,a);return0;在Vc++6.0中的输出结果是:0X12FF6C0X12FF6CPressanykeytocontinue总结:一维数组名一维数组名是个指针常量它存放的是一维数组第一个元素的地址常量是不能被改变的,也就是说,一维数组名是不能被改变的。数组名a存放的是一维数组第一个元素的地址,也就是a=&a0printf("%#X

217〃,&a[O]);=====printf("%#X

218〃,a);指针和二维数组:下标和指针的关系:,如果p是个指针变量,则p[i]永远等价于*(p+i)

219intmain(void)(inta[5]=<1,2,3,4,5}.inti;for(i=0;i<5;++i)IprintfC%d

220*,a[i]);//a[i]==*(a+i)return0;}l确定一个一维数组需要几个参数,【如果一个函数要处理一个一维数组,则形参需要接收该数组的哪些信息。】确定一个一维数组需要两个参数,1:数组名,从数组的名称就可以知道数组的第一个值,因为一维数组的名称就是数组的第一个元素的地址。2:是数组的个数。来计算该数组有多少个值。区别于字符串(只需要一个参数一首地址)因为字符串默认其后面都有一个“Q”作为结束标志。而数组并没有相关约定。

221〃f函数可以输出任何一个一维数组的内容voidf(int*pArr,intlen)(*pArr♦(pArr+1)T)1intmain(void)(inta[5]={1,2,3,4,5}.intb[6]={T,-2,-3,4,5,-6};intc[100]={1,99,22,33);f(a,5);〃a是int♦return0;}在上图中,a是个指针变量,所以上面局部函数f的pArr则要定义成指针函数才可以,而len则是int类型。代表接收的是整型的数字。1#include//f函数可以输出任何一个一维数组的内容voidf(int*pArr,intlen)rinti;for(i=0;i

2222009年11月14日10:45:51一定要明白10行的pArr[3]和17行19行的a[3]是同一个变量*/#includevoidf(int*pArr,intlen)fpArrL3]=88;〃1。行)intmain(void)inta[6]={1,2,3,4,5,6};printf("%d

223",a[3]);〃17行f(a,6);printf(飞d

224",a[3]);//19行return0;)/♦在Vc++6.0中的输出结果是:488Pressanykeytocontinue*/在上图中因为数组a的名称代表的是a的第一个元素的地址,所以在函数f中所定义的指针变量pArr和a是相同的,因为a也是指针类型。也就是说pArr=a=a[0],pArr[l]=a[l]=*(pArr+l)=*(a+l),pArr[2]=a[2]=*(pArr+2)=*(a+2).所以在f函数中pAir[3]=a[3],所以第二个printf输出的结果是88.总结:pArr[i]=a[i]=*(pArr+i)=*(a+i)在没有学习指针时,可将a⑶认为是数组中第4个元素,但现在应该对其内部原理有更深刻认识。这里下标也当成指针了,从首元素开始向后移动3个,即指向第4个元素。#includevoidf(int*pArr,intlen)inti;for(i=0;i

225*);)

226intmain(void)rintb[6]={-1,-2,-3,4,5,-6};f(b,6);b[i]return0;)在上图中因为数组a的名称代表的是a的第一个元素的地址,所以在函数f中所定义的指针变量pArr和a是相同的,因为a也是指针变量类型。也就是说pArr=a=a[0],pArr[l]=a[l]=*(pArr+l)=*(a+l),pArr[2]=a[2]=*(pArr+2)=*(a+2).通过上图,我们知道,我们在f函数中修改数组的值,相当于修改主函数中相对应的值。何谓变量地址/一个指针占几个字节Sizeof(变量名/数据类型)其返回值就是该变量或数据类型所占字节数。一个指针变量无论其指向变量占几个字节,其本身所占大小都是4字节。*p具体指向几个字节,要靠前面类型确定,如果为int则为4字节,如果double则占8字节。CPU与内存交互时有32根线,每根线只能是1或0两个状态,所有总共有232个状态。1个状态对应一个单元。如全为0全为1等。内存中第一个单元,即32根线状态全为0。00000000000000000000000000000000

227其大小为4字节所有每个地址(硬件所能访问)的用4个字节保存(而不是一位bit)一个变量的地址一用该变量首字节的地址表示。这也就是为什么指针变量始终只占4字节的原因。接下来是:138课动态分配内存(很重要)专题:138讲动态内存分配(所有高级语言,没有C里深刻,对JAVA、C#理解有益)传统数组的缺点:1.数组长度必须事先指定,而且只能是常整数,不能是变量彳列子inta[5];〃必须事先指定,而且只能是常整数intlen=5;inta[len];//error2.传统形式定义的数组,该数组的内存程序员无法手动释放数组一旦定义,系统为数组分配的内存空间就会一直存在,除非数组所在的函数运行终止。在一个函数运行期间,系统为该函数中的数组分配的空间会一直存在。直到该函数运行完毕时,数组的空间才会被系统自动释放(不是清零)。例子:voidf(void){inta[5]={l,2,3,4,5))〃数组a占20个字节的内存空间,程序员无法手动编程释放它,数组a只能在f()函数结束被系统释放3.数组的长度一旦定义,数组长度就不能再更改。数组的长度不能在函数运行的过程中动态的扩充或缩小4.传统方式定义的数组不能跨函数使用A函数定义的数组,只有在A函数运行期间才可以被其他函数使用,但A函数运行完毕后,A函数中的数组将无法在被其他函数使用。#includevoidg(int*pArr,intlen)pArr[2]=88;//parr[2]=a[2]等价于voidf(void)inta[5]={1,2,3,4,5};//数组a只在f()执行时有效g(a,5);printf(*%d

228*,a[2]);

229}intmain(void)(fO;//结果:88//printf(*a[0]=%d

230*,a[0]);//errorreturn0;为什么需要动态分配内存很好的解决的了传统数组的4个缺陷动态内存分配举例—动态数组的构造难点/*2011-05-01ma11oc是memory(内存)allocate(分配)的缩写动态内存空间是怎么造出来的?*/#include#includeintmain(void)inti=5;〃分配了4个字节,静态分配int*p=(int*)malloc(100);/*1.要使用malloc函数,必须要添加malloc.h头文件2.malloc函数只有一个形参,并且形参是整型3.100表示请求系统为本程序分配100个字节4.malloc函数只能返回第一个字节的地址,但此时并不能确定该变量的类型,只有将这个地址被强制类型转化成存放整型变量的地址,这时才传达出指向整型变量的信息。5.系统总共分配了104个字节的内存空间,p变量本身占4个字节(静态分配),p所指向的内存占100个字节(动态分配)若为int则可存25个,若为char则可存100个变量。6.p本身所占的内存是静态分配的,p所指向的内存是动态分配的*/free(p);//free(p)表示把p说指向的内存空间给释放掉,〃P本身的内存不能释放,只有main函数终止时,由系统自动释放*p=5;

231〃2011-05-01目的:malloc使用一2*/#include#includevoidf(int*q)//q是p的拷贝或副本q等价于p*4等价于*p*q=200则*p=200(//*p=200;//errorf()没有p变量,p是在main。函数定义的//q=200;//errorq是指针变量(地址),200是整数intq=200;//OK!类型一致//**q语法错误!*q整型变量,只有指针变量前可以加*//free(q);〃把q指向的内存释放掉intmain(void)(int*p=(int*)malloc(sizeof(int));//sizeof(int)=4;*p=10;P代表的就是•个这int变量,*p这个整型变量的内存分配方式和inti=5;不同。〃*P是内存是动态分配的,inti是静态的。printf("同志们好!

232");return0:

233*p);//IO*p);//200printf("%d

234",f(p);printf("%d

235",//f()函数中free(q)作用后,则输出-572662307(垃圾值)return0;2011-05-02目的:动态•维数组示例realloc(pArr,100)〃扩充动态内存空间(原来50变100;原来150变100)〃保留原来动态内存中未被截取的内容*/^include#includeintmain(void){//inta[5];〃系统静态地分配20个字节的空间给数组aintlen;int*pArr;printf(〃请输入你要存放的元素个数:〃);scanf&len);//5pArr=(int*)malloc(4*len);〃pArr指向这20个字节动态空间的前4个字节/*动态的构造了一个一维数组,该数组的长度len,数组名是pArr,数组元素类型是int类似与intpArr[len];len可以根据需要变化*/〃对一维数组进行操作,如:对动态一维数组进行赋值for(inti=0;i

236");〃对一维数组进行输出for(i=0;i

237*,pArr[i]);

238free(pA门');〃动态空间被释放printf("%d

239",*(pArr+1));〃动态空间被释放,原来动态数组数元素内容为垃圾值-572662307return0:/*在VC++6.0输出结果:请输入你要存放的元素个数:446810动态数组元素为:468使用动态数组的优点:1.动态数组长度不需要事先给定;2.内存空间可以手动释放;3.在程序运行中,动态内存空间大小可以通过realloc函数手动扩充或缩小静态内存和动态内存的比较静态内存是由系统自动分配,有系统自动释放静态内存是在栈分配的动态内存是由程序员手动分配、手动释放动态内存是在堆分配的/*2011-05-02目的:多级指针一自己画几个示意图就会豁然开朗。ttincludeintmain(void)(inti=10;//iint*p=&i;//最终*p就是i;int**q=&p;//q只能存放int*类型的地址即p的地址&pint***r=&q;//r只能存放int**类型的地址即q的地址&q//r=&p;//error!因为r是int***类型,只能存放int**类型变量的地址

240।***r=**q二*p二i;=iprintf("i-%d

241”,***r);*r=q;**r=*q:printf("i=%d

242”,**q);*q=p;**q=*Pprintf(,zi二%d

243”,*p);*p=i;printfCi=%d

244",i);return0;)-在VC++6.0输出结果:/*i二10i=10i=101=10*/#include〃多级指针在函数中的应用voidf(int**q)(**q=100;〃*q就是p)voidg()(inti=10;int*p=&i;printf("i=%d*p=%d

245”,i,*p);f(&p);〃p是int*类型&p就是int**类型printf("i=%d*p=%d

246*,i,*p);}intmain(void){g();return0;一在VC++6.0输出结果:i=10*p=10

247i=100*p=100ttincludettincludevoidf(int*q)〃q是p的拷贝副本(*q=1;}voidg(int**r)(**r-2;}voidh(int***s)(***s=3;}voidi(int(****t=4;}//要想修改函数变量的值,只能发送该变量的地址,修改一个以上的值,必须用指针intmain(void){int*p=(int*)malloc(4);printf("*p=%d

248",*p);〃垃圾值f(p);〃调用的是指针printf("*p二%d

249”,*p);//Ig(aP);〃调用的是指针变量的地址printf("*p=%d

250",*p);//2//h(&(&p));//errorC2102:'requires1-valueint**pp=&p;〃pp是存放p地址的指针,int**整型指针的指针类型h(&pp);〃调用的是存放p指针的指针的地址int***整型指针的指针的指针类型printfC*p=%d

251*,*p);//3int***ppp=&pp;i(&ppp);〃调用的是一个二级指针的指针的地址,int****整型四级指针

252printf(/r*p=%d

253*,*p);//4return0;跨函数使用内存的问题难点/*2011-05-02目的:跨函数使用内存函数内的静态空间,不能被其他函数调用访问*/♦♦includevoidf(int**q)//理解为int**qinti=5;〃*q等价于p//*q=i;*q=&i;)intmain(void)*p和**q都不等价于p//error*q等价于p推出p=i:错!//**q=*p=i;int*p;f(&p);*P);printf("畀d

254",return0;/*结果:5本语句语法没有问题,但逻辑上有问题内存越界:程序访问了一个不该被访问的内存函数内的静态空间,不能被其他函数调用访问函数中的内存空间,随函数终止而被释放。内存空间释放后的内容不属于其他函数,其他函数无权限访问。但释放后的内存空间的地址是可以被其他函数读取的o但指针变量可以存贮任何函数中静态内存空间的地址,P都能存垃圾,P想存谁存谁。只是它此时已经没有权限读取(访问)i这个地址的数据了,出错。*//*2011-05-02目的:动态内存可以跨函数访问程序运行在栈顶进行静态空间是在栈里面分配的,函数终止本质叫做出栈,所以静态空间随着函数终止而释放,动态空间是在堆里面分配的,与栈无关,与函数终止无关,不随着函数终止而释放。

255堆和栈相关深入知识就需要《数据结构》和《操作系统》两门课学习,而这两门课难度大,理论性强,短期内收不到立竿见影的成效,属于内功心法,因此大多培训班已经取消了学习。可以用free。释放*/ftinclude#includevoidf(int**q)〃*q等价p已经声明了q的类型为ini**(*q=(int*)malloc(sizeof(int));〃sizeof(整数类型)/*不要用4,因为c语言只规定shortint字节数小于int字节数小于longint字节数,没有规定明确的字节数,无统一硬性规定。不同软件系统可能出现不同,统一用sizeof(inl)来获取实际值int*p;在p声明的情况下,构造动态空间也可以写成p=(int*)malloc(sizeof(int));*///*q等价p,等价于p=(int*)malloc(sizeof(int));//q=5;//error!q指针//*q=5;//error!p=5**q=5;//OK!等价于*p=5intmain(void)(int*p;f(&P);〃只有调用变量的地址,才能改变变量的值printf("%d

256",*p);〃£函数中,没有free(q);所以动态空间仍然保留,动态空间中的内容可以被访问return0;一在VC++6.0输出结果:

257枚举什么是枚举把一个事物所以可能的取值一一列举出来/*日期:2011-05-04目的:枚举*/#include〃自定义了一个数据类型,并没有定义变量,该数据类型的名字enumWeekDayenumWeekDay{//MonDay,TuesDay,WednesDay,ThursDay,FriDay,SaturdDay,SundayMonDay=10,TuesDay,WednesDay,ThursDay,FriDay,SaturdDay,Sunday};〃分号intmain(void)(//intday;〃day定义成int类型范围太大不合适,day的取值只可能有7个(0-6),浪费空间enumWeekDayday=FriDay;〃初始化一个enumWeekDay类型变量dayprintf(*%d

258*,day);return0;/*---在VC++6.0输出结果:14*/怎么使用枚举日期:2011-05-04目的:枚举2*/ttincludeCstdio.h>enumweekday

259(MonDay,TuesDay,WednesDay,ThursDay,FriDay,SaturdDay,Sunday);voidf(enumweekdayi)〃本函数的目的只是期望接受0-6之间的数字,将形参定义为枚举(switch(i):(case0:printf(^MonDay!

260");break;case1:printf(*TuesDay!

261");break;case2:printf(z/WednesDay!

262");break;case3:printf(*ThrusDay!

263");break;case4:printfCFriDay!

264*);break;case5:printfC*ThursDay!

265*);break;case6:printf("SunDay!

266");break;intmain(void)(f(FriDay);〃虽然FriDay本质上就是5,但直接写出f(5);就是错的,也不可能写成Friday大小写敏感return0;)

267枚举的优缺点优点:代码更安全(强制输入),比较直观(有意义)缺点:书写麻烦,不能出错。总结:当是有限个元素时,用枚举更安全,高效。位运算符约翰•冯•诺依曼(JohnVonNouma,1903—1957),美藉匈牙利人被称为计算机之父:2大贡献二进制计算机设备分类:运算器控制器存储器输入设备输出设备什么是进制数字是本质,进制只是不同表现方式一个十六进制位,要用4个二进制数表示,(1)16=(0001)z前面补齐二进制逢二进一十进制逢十进一dec八进制逢八进一oct0数字inti=05;十六进制逢十六进hexOx数字0X数字inti=0x5;inti=0X5;生活中:七进制七天进周十二进制十二月进年二十四进制二十四小时进日六十进制六十分钟进小时六十秒钟进分钟汇编里1101B二进制13570八进制2049D十进制3FB9H十六进制十进制(D)二进制(B)八进制(0)十六进制(H)000011112102231133410044510155611066711177810001089100111910101012a(A)11101113b(B)12110014c(013110115d(D)14111016e(E)15111117f(F)16100002010

268017=7+1*8=150x17=7+1*16=251234=4+1*10三次方+2*10二次方+3*10一次方0x32c=c+3*16二次方+2*16一次方=4354最高塞数是位数T#includeintmain(void),(inti=0x32c;printfCi=猊

269",i);printf("i=%x

270”,i);printf("i=%o

271",i);/*printf的用法%d以十进制输出%x或%X以十六进制输出%o或%0以八进制输出*/return0;#includeintmain(void){inti=1000;print(*%X

272*,i)//3E8printf("翩X

273",i)//0X3E8%#X推荐return0;补码:原码:也叫符号绝对值最高位0表示正1表示负,其余二进制位是该数字的绝对值的二进制位在计算机中,从未被使用!反码反码运行不便,也没有在计算机中应用移码

274表示数值平移n位,n称为移码量移码主要用于浮点数的阶码的存储补码地址是内存单元编号从。到4G-1即2的32次方-1总线若是32位,则有32个0,1主要解决整数的存储int4字节32位个0,1A已知十进制求二进制求正整数的二进制除2取余,直到商为零,余数倒序排列求负整数的二进制先求出与该负数相对应的正整数的二进制代码,然后,将所有位取反末尾加1,不够位数时,左边补一4字节int-5先求5的二进制00000000000000000000000000000101所有位取反,末尾加11111111111111111111111111111101116进制:FFFFFFFB2字节shortint(-3)先求3的二进制0000000000000011所有位取反,末尾加11111111111111101用十六进制表示:FFFD求零的二进制全是零B已知二进制求十进制如果首位是0,则表明是正整数,按普通方法来求如果首位是1,则表明是负整数,将所有位取反末尾加1,所得数字就是该负数的绝对值习题:FFFFFFF5已知二进制求其代表的整数是多少?11111111111111111111111111110101由于最高位是1,所以最终是负数,先对其所有取反00000000000000000000000000001010末尾加1后00000000000000000000000000001011该值为11所以最终结果:-11如果全是零,则对应的十进制数字就是零C二进制到十六进制4位一段从右到左分别转化不够左边初零(00101110)2-(2E)16D十六进制到二进制

275一位转化成4位,不够左边补0(1)16―(00000000000000000000000000000001)2E二进制转到八进制从右往左,三位一段不够被0F八进制与十六进制不能直接转化。通过中间进制。进制总结:进制属于什么知识点,许多人爱不懂装懂。学习好它有利于将来学习底层如汇编等知识,但要往高级语言发展则不需要掌握,另外学好它对后面位运算等有帮助。学习后应掌握:在在VC++6.0中一个int类型变量所能存储的数字的范围是多少32位系统,32个0,1组合表示的内存单元,8个十六进制数组合)int类型变量所能存储的最大正数用十六进制表示:7FFFFFFFint类型变量所能存储的绝对值最大负整数用十六进制表示:80000000最小负数的二进制代码是多少1(0-031个0)最大正数的二进制代码是多少0(1-131个1)已知一个整数的二进制代码求原始的数字按"已知二进制求十进制"求数字超过最大正数会怎样变成负数01111111=12710000000-128不同数据类型转化丢失最高位.只截留后者类型所占的字节数。例如:int类型转化为char则高3位字节被截取。只保留最后一位字节。结构体(非重点)为什么需要结构体为了表示一些复杂的事物,而普通的基本类型无法满足实际要求。什么叫结构体把一些基本类型数据组合在一起形成的一个新的复合数据类型。如何定义结构体3种方式://第一种只是定义了一个新的数据类型,并没有定义变量推荐采用1structStudent{Intage;Floatscore;Charsex;);〃第二种structStudent{Intage;Floatscore;Charsex;}st;

276//第三种struct{Intage;Floatscore;Charsex;}st;怎样强用结构体变量赋值和初始化定义的同时可以整体赋值。如果定义完之后,则只能单个赋初值。如果取出结构体变量中的每一个成员{重点}1结构体变量名.成员名2指针变量名->成员名(更常用)它会在计算机内或转化成(*指针变量名).成员名的方式来执行。所以两者是等价的。例子:StructStudent(Intage;Floatscore;Charsex;);Intmain(void)(StructStudentst={80,66.6f,'F'};〃初始化定义的时候赋值66.6在C语言中默认是double类型,如果希望一个实数是float类型,则必须在末尾加f或F,因此66.6是double,66.6f或66.6F是floatstructStudentst2;st2.age=10;st2.score=88;st2.sex='F';//第二种方式单独赋值StructStudent*pst=&st;//&st不能写成stPst->age=88;//通过结构体指针变量printf(*%d%f

277”,st.age,pst->score);Return0;理解:1pst->age会在计算机内部转化成(*pst).age的方式来执行,没有为什么,这就是->的含义,这也是一种硬性规定。2所以pst->age等价于(*pst).age也等价于st.age3pst->的含义:pst所指向的那个结构体变量中的age这个成员。结构体变量的大小略大于其内部成员类型所占字节数之和。试:sizeof(struct)若想通过函数对主函数结构体变量进行修改,则主函数必须发送地址,外函数定义指针结构体变量,通过外函数内部语句完成对变量的修改。而仅想输出、读取操作,则不用传地址,定义指针过程。例:

278/*2009年11月24日9:17:43通过函数完成对结构体变量的输入和输出*/#include#includestructStudent(intage;charsex;charname[100];};〃分号不能省voidInputStudent(structStudent*);voidOutputStudent(structStudentss);intmain(void)(structStudentst;〃15行InputStudent(&st);〃对结构体变量输入必须发送st的地址〃printf("%d%c%s

279",st.age,st.sex,st.name);//此行和下行输出函数功能相同OutputStudent(st);〃对结构体变量输出可以发送st的地址也可以直接发送st的内容return0;)voidOutputStudent(structStudentss)printf(*%d%c%s

280”,ss.age,ss.sex,ss.name);voidInputStudent(structStudent*pstu)〃pstu只占4个字节((*pstu).age=10;//pstu->name="张三丰";或(*pstu).name="张三丰";都是error,提示错误信息:cannotconvertfrom*char[5]'to,char[100]'strcpy(pstu->name,"张三丰");〃用字符串拷贝命令解决问题pstu->sex='F';)/*

281〃本函数无法修改主函数15行st的值所以本函数是错误的voidInputStudent(structStudentstu)(stu.age=10;strcpy(stu.name,"张三”);〃不能写成stu.name="张三”;stu.sex='F';)*/结构体:应该发送地址还是内容设计函数的目的:必须考虑功能单一,还要考虑安全因素C++中指针前可加const则只能读而不能修改其指向的变量。指针的优点:耗用内在小(4字节)快速传递数据执行速度快。因此:推荐使用结构体变量作为函数参数来传递/*2009年11月24日9:17:43示例:发送地址还是发送内容目的:指针的优点之一:快速的传递数据,耗用内存小执行速度快*/ttincludettincludestructStudent(intage;charsex;charname[100];};〃分号不能省voidInputStudent(structStudent*);voidOutputStudent(structStudent*);intmain(void)(structStudentst;〃15行〃printf("%d

282”,sizeof(st));InputStudent(&st);〃对结构体变量输入必须发送st的地址

283OutputStudent(&st);〃对结构体变量输出可以发送st的地址也可以直接发送st的内容但为了减少内存的耗费,也为了提高执行速度,推荐发送地址return0;)voidOutputStudent(structStudent*pst)(printf("%d%c%s

284”,pst->age,pst->sex,pst->name);)voidInputStudent(structStudent*pstu)〃pstu只占4个字节((*pstu).age=10;strcpy(pstu->name,“张三”);pstu->sex='F';结构体变量的运算不能加减乘除操作,只能相互赋值。例如:structStudent|Intage;Charsex;Char[100];};StructStudentstrl,str2;Strl=str2/str2=strl;都是正确的。举例:动态构造存放学生信息的结构体数组#include#include//必须先添加头文件mallocstructStudent(intage;floatscore;charname[100];);intmain(void){intlen;structStudent*pArr;

285inti,j;structStudentt;〃动态的构造一维数组printf(”请输入学生的个数:

286");printf(*len=");scanf&len);pArr=(structStudent*)malloc(len*sizeof(structStudent));//printf(,,%d

287/z,sizeof(structStudent));//108字节〃输入for(i=0;ipArr[j+l].score)//>升序(降序(t=pArr[j];//注意t的类型为StructStudentpArrtj]=pArr[j+l];pArr[j+l]=t;))printf("

288

289学生的信息是:

290");〃输出for(i=0;i

291〃,i+1);

292printf(*age=%d

293”,pArr[i].age);printf(*name=%s

294*,pArr[i].name);printf(*score=%f

295*,pArr[i].score);printf(*

296*);return0;总结:对于一个人事管理或图书管理项目,分析流程:第一步;存储第二步:操作第三步:输出前两个过程最难、最核心是“数据结构”研究的重点,一般都屏蔽了。数组和变量虽然都可以存储,但都不完美。比如:人事关系图、交通图等,都不好用数组保存。从事关系结构只能用“树”还保存,而对于两个起终点:公交线路查询,实现时间最小/距离最短/花费最低等功能,只能用“图”来存。而图和树都必须有指针知识,它们属于较高深的思想层次的东西。因此要学好数据结构必须要懂得指针。若感兴趣:可以继续学习郝斌老师的《数据结构》教学视频。链表(较难)C语言和数据结构的连接(过渡)链表是数据结构第一部分而是c语言最后一章内容,由此可以比较两者难算法:通俗定义:解题的方法和步骤狭义定义:对存储数据的操作对不同的存储结构,要完成某一个功能所执行的操作是不一样比如:要输出数组中所有的元素的操作和要输出链表中所有的元素的操作是不一样的这说明:算法是依附于存储结构的不同的存储结构,所执行的算法是不一样的广义定义:

297广义的算法也叫泛型C++无论数据是如何存储的,对该数据的操作都是一样的分层思想,站在更高的层次看,把内部的实现给屏蔽数组和链表都是线性的,都是先输出一个元素后,再输出下一个元素我们至少可以通过两种结构来存储数据数组优点:存取速度快缺点:需要一整块连续的空间(对于庞大数据,往往没有一个适合的较大的连续的空间如a[30000000000000])插入和删除元素效率很低(插入和删除中间某个元素,其后的所有都要前后移动)链表优点:插入删除元素效率高缺点:查找某个位置的元素效率低(由于不是连续的,不同由下标直接找,必须由头至尾逐••比对查找)两者各有所长,至今没有出现一个更优的存储方式,可集数组、链表优点于一身。链表专业术语:首结点:W放第一个有效数据的结点尾结点:存放最后一个有效数据的结点,指针域的指针为NULL,尾结点的标土心头结点:头结点的数据类型和首结点的类型是一模一样的头结点是首结点前面的那个节点头结点并不存在有效数据设置头结点的目的是为了方便对链表的操作头指针:存放头结点地址的指针变量确定一个链表需要一个参数,头指针对于每个链表元素,分为左右两部分,左边为数据单元,右边为下一元素地址。例:#include#include#includestructNode(intdata;〃数据域structNode*pNext;〃指针域);〃函数声明

298structNode*create_list(void);voidtraverse_list(structNode*);intmain(void)(structNode*pHead=NULL;pHead=create_list();“create」ist():而建一个非循环单链表,并将该链表的头结点的地址付给pHeadtraverse_list(pHead);return0;)structNode*create_list(void)intlen;〃用来存放有效节点的个数inti;intval;〃用来临时存放用户输入的结点的值〃分配了一个不存放有效数据的头结点structNode*pHead=(structNode*)malloc(sizeof(structNode));if(NULL=pHead)(printf(〃分配失败,程序终止!

299");exit(-1);}structNode*pTail=pHead;pTail->pNext=NULL;printf(〃请输入您需要生成的链表节点的个数:len=〃);scanf&len);for(i=0;i

300");exit(-l);〃终止程序}pNew->data=val;pTail->pNext=pNew;

301pNew->pNext=NULL;pTail=pNew;}returnpHead;voidtraverse_list(structNode*pHead)(structNode*p=pHead->pNext;while(NULL!=p)(printf("%d”,p->data);p=p->pNext;)printf("

302");return;)对于以上例题:不要求逐行敲出,但要能看懂。字符串的处理两种:字符数组字符指针位运算&按位与一每一位都按位与(区别&j取地址)1&1=11&0=00&0=00&1=0I按位或一每一位都按位与〜取反一每一位取反C按位异或一相同为零不同为11'0=10"1=1ri=oo'o=o«按位左移一左移n位相当于乘以2的n次方i«3表示把i的所有二进制位左移动3位,右边补零面试题:A)i=i*8;B)i=i«3;

303请问上述两个语句,哪个语句执行的速度快答案:B快乘法在运算器里,运行原理比较复杂按位左移,简单!»按位右移一右移n位相当于除以2的n次方,首位为0补0,首位是1#1i»3表示把i的所有二进制位右移动3位,左边补零防止过度右移,容易丧失精度和意义位运算的现实意义:通过位运算符,我们可以对数据的操作精确到每一位。NULL二进制全部为零的含义:--0000000000的含义1.数值零2.字符串结束标记‘\0'3.空指针NULLNULL表示零,而这个零不代表数字零,而表示的内存单元的编号零我们计算机规定了,以零为编号的存储单元的内容不可读,不可写free(p);4=NULL;*P=0;错!把0号单元改写!0单元是非常重要的数据。程序员不可能读写出0号单元信息纯C的知识(略)文件不是用‘流’的思想,用函数实现,于javaC++没联系宏typedef期末考试1.什么叫分配内存,什么叫释放内存分配内存:操作系统把某一块内存空间的使用权力分配给该程序内存释放:操作系统把分配给该程序的内存空间的使用权力收回,该程序就不能使用这块内存空间附注:释放内存不是把该内存的数据清零

3041.变量为什么必须初始化不初始化,变量通常是垃圾值,很可能是上次程序结束遗留下来的数据。2.详细说明系统如何执行:inti=5;这条语句的1>Vc++6.0软件请求操作系统为i分配存储空间2>操作系统会在内存中寻找一块空闲的区域,把该区域当作i来使用3>Vc++6.0会把i和这块空间区域关联起来,今后对字母i操作就是对这块空闲的区域操作。4>把5存储到字母i所关联的内存区域中附注:所谓内存区域也就是内存的•块存:储单兀3.详细列出C语言所有基本类型intlongintshortintcharfloatdouble4.在printf函数中,int用%d输出,请问:longintchardoublefloat分别用什么输出?%ld%c%lf%f5.函数的优点1>避免重复操作2>有利于程序的模块化6.谈谈你对函数的理解7.什么是指针,什么是地址,什么是指针变量,三者之间的关系?地址是内存单元的编号指针就是地址指针和地址是同一个概念指针变量是存放内存单元编号的变量指针变量和指针是两个完全不同的概念,只不过人们通常把指针变量称作指针8.请写出静态变量和动态变量的异同相同点:都需要分配内存不同点:静态变量是由系统自动分配,自动释放,程序员无法在程序运行的过程当中手动分配,也无法在程序运行的过程中手动释放。静态变量是在栈中分配的,只有在函数终止之后,静态变量的存储空间会被系统自动释放。动态内存是由程序员手动分配,程序员可以在程序运行的过程当中手动分配,手动释放。

305动态变量是在堆中分配的,程序员可以在行是执行过程中的任何时刻手动释放动态变量的空间不需要等到函数终止才释放。10.C语言中哪些知识点是我们学习的重点,请一一列举出来流程控制函数指针静态内存和动态内存11.for(l;2;3)A;B;1>2成立,会继续执行哪条语句:A2>3执行完毕后,会继续执行哪条语句:23>A执行完毕后,会继续执行哪个语句:34>1总共会执行几次:1次12.for(l;2;3)for(4;5;6)(A;B;)C;1>6执行完毕后,会继续执行哪个语句:52>5成立,会继续执行哪个语句:A3>5不成立,会继续执行哪个语句:34>2不成立,会继续执行哪个语句:C5>2成立,会继续执行哪个语句:46>A和B语句是否一定会被执行不会(2或5不成)7>C语句是否一定会执行是13.for(l;2;3)|while(4)5;6;break;if(7)8;9;}10;

3061>5执行完毕后,会继续执行哪个语句:42>break终止什么?终止for,break终止最里层包裹它的循环3>如果8是break语句,贝执行完毕之后会继续执行哪个语句104>如果7不成立,会继续执行哪条语句9方法:调整清楚for(1;2;3)while(4)5;)6;break;if(7)(8;)9;}10;14判断下列程序语法上是否有错误,说出错误原因A)int*p;*p=10;错p没有指向,*p数据不可读和操作B)char*p;charch=A;p=&ch;错A改成'A'A非法无意义C)inti,j;i=j=0;int*p;p=&i;对i=j=0;从右向左D)int*p;int**q;q=&p;对指针的指针是int**类型E)int*p;inti=5;p=&i;*p=10;对p指向i,*p=5;把10赋值给*p15编程实现:如果x大于0,贝的为1.如果x小于0,贝的为-1,如果x等于0,贝Uy为0,以下程序段中,不能根据x值正确计算出y值的是CDA)if(x>0)y=l;elseif(x=0)y=0;elsey=-l;B)y=0;if(x>0)y=l;elseif(x<0)y=-l;C)y=0;1£6>=0);(;空语句)if(x>0)y=l;D)if(x>=0)if(x>0)y=l;

307elsey=0;16.若变量已正确定义,有以下程序段inta=3,b=5,c=7;if(a>b)a=b;c=a;if(c!=a)c=b;printf(*%d,%d,%d

308*,a,b,c);输出结果是:BA)程序段有语法错误B)3,5,3C)3,5,5D)3,5,717.执行以下程序后,输出的个数是:6^includeintmain(void)(inti,j;for(i=l;i<5;i++)for(j=2;j<=i;j++)printf("%c

309",';return0;18.有以下程序ttincludeintmain(void)(inti,s=0;for(i=l;i<10;i+=2)s+=i+l;//s=s+(i+1);printf("%d

310”,s);return0;)程序执行后的结果是:DA)自然数1〜9的累加和B)自然数1〜10的累加和0自然数1〜9中的奇数之和D)自然数1〜10中偶数之和19.若有一些定义和语句inta=4;intb=3;int*p;int*q;int*w;

311p=&a;q=&b;w=q;q=NULL;则以下选项中错误的语句是AA)*q=0;B)w=q;C)*p=88;D)*p=*w;20以下程序#includevoidfun(char*a,char*b)a=b;〃指针ab相互指向,则他们的值相同(*a)++;)intmain(void)(charcl=,A',c2-a,*pl,*p2;pl=&cl;p2=&c2;fun(pl,p2);printf("%c%c

312”,cl,c2);}程序运行后的输出结果是:Ab实验程序/*^includevoidfun(char*a,char*b){printf(^c%c

313^,*a,*b);//Aaa=b;printf(^c枇

314”,*a,*b);//aa(*a)++;printf(^c%c

315",*a,*b);//bb}intmain(void)(charcl=,A*,c2-a,*pl,*p2;pl=&cl;p2=&c2;fun(pl,p2);printfC%c%c

316z/,cl,c2);//Ab

317#includeintmain(void)(inti=0;intj=1;int*a=&i;int*b=&j;a=b;//OK互为指向*a=*b=l;printf(*%d%d

318”,*a,*b);//I1*/*a+=l;printf("%d%d

319”,*a,*b);//22指针a和指针互为指向,改变*a的值,就是改变*b的值/*a=a+2;〃把指针a的址编号加2,b不指向a,〃1)仍然指向a原来的地址无法知道与a地址相隔2个单元的内容*a.printf(飞d%d

320”,*a,*b);//12450882return0;)21.若有定义:intk;以下程序段的输出结果是:##2##4for(intk=2;k<6;K++,K++)printfk);K++,K++=1个循环因子22.break23.进制转化24.C的一些认识问题。此致:郝斌老师的C语言教程全部结束。课堂讲解全程动手敲代码,讲解细致,对于重要知识点的讲解不厌其烦,是一个难得的C语言入门教程。在这里对老师的辛勤付出表示感谢。2014-3-8

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。
关闭