
C++程序设计(谭浩强完整版).ppt
930页C++程序设计程序设计 谭浩强编著谭浩强编著 清华大学出版社清华大学出版社 课件制作:南京理工大学课件制作:南京理工大学 陈清华陈清华 朱红朱红1第一章第一章C++概述概述 C++语言发展历史语言发展历史 自从自从1946年第一台电子数字计算机年第一台电子数字计算机ENIAC问世以来,随着计算机应用领域的不断扩大,问世以来,随着计算机应用领域的不断扩大,促进了计算机技术的高速发展,尤其是近年促进了计算机技术的高速发展,尤其是近年来计算机的硬件和软件都是日新月异作为来计算机的硬件和软件都是日新月异作为应用计算机的一种工具应用计算机的一种工具—程序设计语言,得程序设计语言,得到不断的充实和完善每年都有新的程序设到不断的充实和完善每年都有新的程序设计语言问世,老的程序设计语言不断地更新计语言问世,老的程序设计语言不断地更新换代 220世世纪纪60年年代代,,Martin Richards为为计计算算机机软软件件人人员员在在开开发发系系统统软软件件时时,,作作为为记记述述语语言言使使用用而而开开发发了了BCPL语语言言(Basic Combined Programming Language)。
1970年年,,Ken Thompson在在继继承承BCPL语语言言的的许许多多优优点点的的基基础础上上发发明明了了实实用用的的B语语言言到到了了1972年年,,贝贝尔尔实实验验室室的的Dennis Ritchie和和Brian kernighan在在B语语言言的的基基础础上上,作作了了进进一一步步的的充充实实和和完完善善,,设设计计出出了了C语语言言当当时时,,设设计计C语语言言是是为为了了编编写写UNIX操操作作系系统统的的以以后后,C语语言言经经过过多多次次改改进进,并并开开始始流流行行C++是是在在C语语言言的的基基础础上上发发展展和和完完善善的的,,而而C是是吸收了其它语言的优点逐步成为实用性很强的语言吸收了其它语言的优点逐步成为实用性很强的语言3C语言的主要特点是:语言的主要特点是:1、、C语语言言是是一一种种结结构构化化的的程程序序设设计计语语言言,,语语言言本本身身简简洁洁、、使使用用灵灵活活方方便便既既适适用用于于设设计计和和编编写写大大的的系系统统程程序序,,又又适适用用于于编编写写小小的的控控制制程程序序,,也也适适用科学计算用科学计算2、、它它既既有有高高级级语语言言的的特特点点,,又又具具有有汇汇编编语语言言的的特特点点。
运运算算符符丰丰富富,,除除了了提提供供对对数数据据的的算算术术逻逻辑辑运运算算外外,,还还提提供供了了二二进进制制的的位位运运算算并并且且也也提提供供了了灵灵活活的的数数据据结结构构用用C语语言言编编写写的的程程序序表表述述灵灵活活方方便便,,功功能能强强大大用用C语语言言开开发发的的程程序序,,其其结结构构性性好好,,目目标程序质量高,程序执行效率高标程序质量高,程序执行效率高43、、程程序序的的可可移移植植性性好好用用C语语言言在在某某一一种种型型号号的的计计算算机机上上开开发发的的程程序序,,基基本本上上可可以以不不作作修修改改,,而而直直接接移植到其它型号和不同档次的计算机上运行移植到其它型号和不同档次的计算机上运行4、、程程序序的的语语法法结结构构不不够够严严密密,,程程序序设设计计的的自自由由度度大大这这对对于于比比较较精精通通C语语言言的的程程序序设设计计者者来来说说,,可可以以设设计计出出高高质质量量的的非非常常通通用用的的程程序序但但对对于于初初学学者者来来说说,,要要能能比比较较熟熟练练运运用用C语语言言来来编编写写程程序序,,并并不不是是一一件件容容易易的的事事情情。
与与其其它它高高级级语语言言相相比比而而言言,,调调试试程程序序比比较较困困难难往往往往是是编编好好程程序序输输入入计计算算机机后后,,编编译译时时容容易易通通过过,,而而在在执执行行时时还还会会出出错错但但只只要要对对C语语言言的的语语法法规规则则真真正正领领会会,,编编写写程程序序及及调调试试程程序序还是比较容易掌握的还是比较容易掌握的5随随着着C语语言言应应用用的的推推广广,,C语语言言存存在在的的一一些些缺缺陷陷或或不不足足也也开开始始流流露露出出来来,,并并受受到到大大家家的的关关注注如如::C语语言言对对数数据据类类型型检检查查的的机机制制比比较较弱弱;;缺缺少少支支持持代代码码重重用用的的结结构构;;随随着着软软件件工工程程规规模模的的扩扩大大,,难难以以适适应应开开发发特大型的程度等等特大型的程度等等6为为了了克克服服C语语言言本本身身存存在在的的缺缺点点,,并并保保持持C语语言言简简洁洁、、高高效效,,与与汇汇编编语语言言接接近近的的特特点点,,1980年年,,贝贝尔尔实实验验室室的的Bjarne Stroustrup博博士士及及其其同同事事对对C语语言言进进行行了了改改进进和和扩扩充充,,并并把把Simula 67中中类类的的概概念念引引入入到到C中中。
并并在在1983年年由由Rick Maseitti提提议议正正式式命命名名为为C++((C Plus Plus))后后来来,,又又把把运运算算符符的的重重载载、、引引用用、、虚虚函函数数等等功功能能加加入入到到C++中中,,使使C++的的功能日趋完善功能日趋完善当当前前用用得得较较为为广广泛泛的的C++有有::VC++ ((Visual C Plus Plus))、、 BC++((Borland C Plus Plus))、、AT&T C++等7简单的简单的C++程序介绍程序介绍高级语言编译过程高级语言编译过程源程序源程序(文本文件)(文本文件)*.CPP目标文件目标文件(二进制文件)(二进制文件)*.OBJ可执行文件可执行文件(二进制文件)(二进制文件)*.EXE库文件库文件(各种函数)(各种函数)在在Vitual C++系统中,可直接从源程序编译连接至可执行系统中,可直接从源程序编译连接至可执行程序,但依然要生成程序,但依然要生成*.OBJ及及*.EXE这两个文件这两个文件F7编译编译连接连接compilelink8一个简单的一个简单的C++程序程序#include
选项2)选择源程序存放的目录和输入源程序名,单击)选择源程序存放的目录和输入源程序名,单击“确定确定”3))在在编辑器中编写源程序编辑器中编写源程序4)单击)单击F7或或“编译编译”中的中的“重建全部重建全部”编译源程编译源程序,若编译通过,单击序,若编译通过,单击“执行执行”,在,在DOS屏上看屏上看结果结果,,任按一键返回编辑器任按一键返回编辑器10启动启动VC++编译系统编译系统11VC++编译编译系统界面系统界面单击单击“File”菜菜单中单中“New”命命令令12选择选择“Files”选项选项卡卡选择选择C++源源文件命令文件命令输入文件名输入文件名输入文件输入文件存放位置存放位置单击选择单击选择驱动器驱动器选择驱动选择驱动器或目录器或目录13C++源文件源文件编辑界面编辑界面输入输入C++源代码源代码14可以将此源可以将此源代码另起文代码另起文件名存盘件名存盘15选择编译命令,将源文选择编译命令,将源文件件.cpp生成生成.obj文件文件16如果编译出错,会出现提示信息,如果编译出错,会出现提示信息,指出错误的位置及种类指出错误的位置及种类错误所在行错误所在行错误的原因错误的原因17双击错误双击错误所在行所在行光标移到该行光标移到该行18生成可执生成可执行文件行文件通过后单通过后单击该命令击该命令运行程序运行程序19运行结果显示运行结果显示在在DOS屏上屏上注意:不可以在软盘上注意:不可以在软盘上运行程序!应该把保存运行程序!应该把保存在软盘中的源文件拷贝在软盘中的源文件拷贝到硬盘的目录中再运行到硬盘的目录中再运行!20源程序所在目录源程序所在目录未编译前,只未编译前,只有一个源程序有一个源程序21编译运行后,出编译运行后,出现众多附加文件现众多附加文件同时,产生一个同时,产生一个子目录子目录Debug22Debug目录中,有目录中,有obj和和EXE文件文件23#include 一般用四个字节表示整一般用四个字节表示整数举例举例)内存内存CPU内存内存data外存外存Program8硬盘硬盘 软盘软盘261514 13 12 11 109876543210有符号数有符号数无符号数无符号数0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 132767327670 1 1 1 1 1 1 1 1 1 1 1 1 1 1 03276632766…………0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1110 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0001 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1-1(补码补码)655351 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0-265534…………1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1-32767327691 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0-327683276827常量与变量常量与变量常量:在程序运行过程中,其值一直保持不变的量常量:在程序运行过程中,其值一直保持不变的量为常量常量也区分不同的类型:常量也区分不同的类型:30,,40 为整型,为整型,30.0,,40.0为实型,为实型,编辑器只是根据其表面形式来判断其编辑器只是根据其表面形式来判断其类型。 类型变量:在程序运行过程中,其值可以改变的量为变量:在程序运行过程中,其值可以改变的量为变量变量在程序的执行中能够赋值,发生变化变量在程序的执行中能够赋值,发生变化变量有一个名字,有一个名字,并在使用之前要说明其类型并在使用之前要说明其类型,一经,一经说明,说明,就在内存中占据与其类型相应的存储单元就在内存中占据与其类型相应的存储单元28#include 序的基本前提30变量名的命名方法:变量名的命名方法:变量名、数组名、函数名变量名、数组名、函数名…称为称为标识符标识符标识符只能由标识符只能由字母、数字、下划线字母、数字、下划线这三种字符组成,且第这三种字符组成,且第一个字符必须为字母或下划线,长度不大于一个字符必须为字母或下划线,长度不大于247个字符,个字符,大小写不通用大小写不通用关键字不能作为标识符)关键字不能作为标识符)关键字即是关键字即是VC++的语法要求中使用的字的语法要求中使用的字如如 int if while 等 正确的标识符:正确的标识符:INT, sum , de12, SUM等变量必须使变量必须使用前定义,以分配空间用前定义,以分配空间举例说明举例说明31abc English 2xy x-y if Else b(3) ‘def’ Chine_bb b3y AbsFloat float一般变量都是用匈牙利命名法命名的一般变量都是用匈牙利命名法命名的int nCount; char chChoice;32整型数据整型数据整型常量:整型常量:常量是根据其表面形式来判定,整型量即是没有小数点的常量是根据其表面形式来判定,整型量即是没有小数点的整数,范围:整数,范围:-231~((231-1)) ,有三种形式,有三种形式:1)十进制(默认方式))十进制(默认方式)43 1345 876542)八进制)八进制 以以0开头开头 043,, 056,, 0113)十六进制)十六进制 以以0x开头开头 0x12 0xa3 0x34 0xdf(举例说明)(举例说明)33#include 分为有符号型与无符号型有符号型:有符号型: short 在内存中占两个字节,范围为在内存中占两个字节,范围为-215~((215-1)) int 在内存中占四个字节,范围为在内存中占四个字节,范围为-231~((231-1))long在内存中占四个字节,范围为在内存中占四个字节,范围为-2-31~231-1无符号型:无符号型:最高位不表示符号位最高位不表示符号位unsigned short 在内存中占两个字节,范围为在内存中占两个字节,范围为0~216-1unsigned int 在内存中占四个字节,范围为在内存中占四个字节,范围为0~232-1unsigned long在内存中占四个字节,范围为在内存中占四个字节,范围为0~232-1351))整型常量整型常量亦有长短之分,常量中无亦有长短之分,常量中无unsigned型,但一型,但一个非负的整型常量可以赋给个非负的整型常量可以赋给unsigned型的变量型的变量 2)若一个常量定义为长整型数,则在其后加)若一个常量定义为长整型数,则在其后加l或或L进行区进行区分如:如:32l 32L 564L等,内存为其分配四个字节存储。 等,内存为其分配四个字节存储 一个数在内存中为一个数在内存中为1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1当这个数为有符号数时,是当这个数为有符号数时,是-1;为无符号数时,是;为无符号数时,是232-1内存中的数是以内存中的数是以补码补码的形式存放的举例说明)的形式存放的举例说明)1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 136#include 面必须是整数实型变量分单精度实型变量分单精度 float 和双精度和双精度 double 两种形式:两种形式:float:占四个字节,提供占四个字节,提供7~8位有效数字位有效数字double: 占八个字节,提供占八个字节,提供15~16位有效数字位有效数字举例说明举例说明38#include 称为尾数,尾数决定有效数字,即数字的精度J 表示指数(阶码)表示指数(阶码)R 是基数,可取是基数,可取2,,4,,8,,16等,对具体机器而言,基数等,对具体机器而言,基数取好后,就不能再变了取好后,就不能再变了数有正有负数有正有负, 所以设置数符所以设置数符; 阶码亦有正负阶码亦有正负, 所以设置阶所以设置阶符符40一般用一般用4个字节表示一个浮点数,也有用个字节表示一个浮点数,也有用8个字个字节表示的节表示的字长一定,尾数越多,精度越高;阶码越多,字长一定,尾数越多,精度越高;阶码越多,范围越大范围越大当计算机中出现小于机器所能表示的最小数当计算机中出现小于机器所能表示的最小数时,机器只能当零来处理时,机器只能当零来处理,,当出现超过机器所能当出现超过机器所能表示的最大数时,出现溢出现象表示的最大数时,出现溢出现象,一旦出现溢出,,一旦出现溢出,就会停止运算就会停止运算定点数,浮点数均会出现溢出现定点数,浮点数均会出现溢出现象41字符型数据(字符型数据(char)字符型数据实际上是作为字符型数据实际上是作为整型数据整型数据在内存中存储的在内存中存储的计算机是以字符编码的形式处理字符的,因此,我们在计算机内部计算机是以字符编码的形式处理字符的,因此,我们在计算机内部是以是以ASCII码码的形式表示所有字符的。 所以的形式表示所有字符的所以7位二进制数即可表示出位二进制数即可表示出一个字符,一个字符,我们用一个字节的容量(我们用一个字节的容量(8位)存储一个字符位)存储一个字符例如:字符例如:字符A的的ASCII码为码为0x41或或65,在内存中表示为:,在内存中表示为:01000001在程序中表示为:在程序中表示为:char grade ;//定义一个字符型的变量空间定义一个字符型的变量空间(1个字节个字节)grade=‘A’; //必须用必须用‘ ’表示,否则易与标识符混同表示,否则易与标识符混同 ‘ ’内括起来的字符表示该字符的内括起来的字符表示该字符的ASCII码42进一步,由于在内存中的形式与整型数据相同,所以,进一步,由于在内存中的形式与整型数据相同,所以,可以直接用可以直接用其整型值给变量赋值其整型值给变量赋值char grade;grade=65;以下的赋值形式均是等同的以下的赋值形式均是等同的grade='A'; grade=65 ; grade=0x41; grade=0101;#include 如回车、退格等,可用两种方式表示这些字符1)用)用ASCII码的形式码的形式 char re=13;2)用转义字符)用转义字符 char re=‘\n’;((p15)44转义字符转义字符含含 义义 ASCII代码代码\a响铃响铃7\n\n换行,将当前位置移到下一行开头换行,将当前位置移到下一行开头10\t\t水平制表(跳到下一个水平制表(跳到下一个tab位置)位置)9\b\b退格,将当前位置移到前一列退格,将当前位置移到前一列8\r\r回车,将当前位置移到本行开头回车,将当前位置移到本行开头13\f\f换页,将当前位置移到下页开头换页,将当前位置移到下页开头12\ v竖向跳格竖向跳格8 \\\\反斜杠字符反斜杠字符“\\”92\\′单引号(撇号)字符单引号(撇号)字符39\\"双引号字符双引号字符34\0空字符空字符0\\ddd1到到3位位8进制数所代表的字符进制数所代表的字符 \\xhh1到到2位位16进制数所代表的字符进制数所代表的字符 45转义字符虽然包含转义字符虽然包含2个或多个字符,但它只代个或多个字符,但它只代表一个字符。 表一个字符编译系统在见到字符编译系统在见到字符““\””时,时,会接着找它后面的字符,把它处理成一个字会接着找它后面的字符,把它处理成一个字符,在内存中只占一个字节符,在内存中只占一个字节 46典型转义字符典型转义字符 ::‘\n’换行换行 ‘\b’ 退格退格 '\t' 下一下一个输出区个输出区若输出中包含这些特定格式,则再加一个若输出中包含这些特定格式,则再加一个\输出输出 c:\tc\tc 表示为表示为cout<<"c:\\tc\\tc";可以用转义字符表示任一一个可以用转义字符表示任一一个ASCII字符字符 ‘\ddd’ (八进制)八进制) ‘\xhh‘ (十六进制)(十六进制)'\101' '\x41' '\x61' '\141' 47#include 结束如:如:"CHINA" 0x430x480x490x550x41\0'a'在内存中占一个字节在内存中占一个字节 "a"占两个字节占两个字节aa\0实际上实际上内存是对应字符的内存是对应字符的ASCII码形式码形式010000110100100001001001010101010100000100000000CHINA\001100001011000010000000049标识符常量标识符常量在在C++中中有有二二种种方方法法定定义义标标识识符符常常量量,,一一种种是是使使用用编编译译预预处理指令;另一种是使用处理指令;另一种是使用C++的常量说明符的常量说明符const例如:例如: #define PRICE 30 //在程序中凡是出现在程序中凡是出现PRICE均用均用30替代替代 #define PI 3.1415926 #define S ““China””const float pi=3.1415926; //将将变量变量pi定义为定义为常量常量(举例说明)(举例说明)50#include 若合法,则指出常量的数据类型32767 35u 1.25e3.43L 0.0086e-32‘\87’ “Computer System” “a” ‘a’ ‘\96\45’-0+0.5-.56752变量变量1) 在在程程序序的的执执行行过过程程中中,,其其值值可可以以改改变变的的量量称为变量称为变量2) 变量名必须用标识符来标识变量名必须用标识符来标识3) 变变量量根根据据其其取取值值的的不不同同值值域域,,分分为为不不同同类类型型的的变变量量::整整型型变变量量、、实实型型变变量量、、字字符符型型变变量、构造型变量、指针型变量等等量、构造型变量、指针型变量等等534) 对对于于任任一一变变量量,,编编译译程程序序要要为为其其分分配配若若干干个个字字节节((连连续续的的))的的内内存存单单元元,,以以便便保保存存变变量的取值量的取值5) 当当要要改改变变一一个个变变量量的的值值时时,,就就是是把把变变量量的的新新的的取取值值存存放放到到为为该该变变量量所所分分配配的的内内存存单单元元中中;;用用到到一一个个变变量量的的值值时时,,就就是是从从该该内内存存单单元中取出数据。 元中取出数据6) 不不管管什什么么类类型型的的变变量量,,通通常常均均是是变变量量的的说说明在前,使用变量在后明在前,使用变量在后54int i, j, k;//定义了三个整型变量定义了三个整型变量i,j,kfloat x,y,z;//定义了三个实型变量定义了三个实型变量x,y,zchar c1,c2; //说明了二个字符型变量说明了二个字符型变量c1,c2double dv1;;//说明了一个双精度型变量说明了一个双精度型变量dv1k四个字节的四个字节的连续空间连续空间j四个字节的四个字节的连续空间连续空间i四个字节的四个字节的连续空间连续空间z四个字节的四个字节的连续空间连续空间y四个字节的四个字节的连续空间连续空间x四个字节的四个字节的连续空间连续空间dv1八个字节的八个字节的连续空间连续空间c21个字节的个字节的空间空间c11个字节的个字节的空间空间开辟空间后开辟空间后, 空空间中为随机值间中为随机值55变量赋初值变量赋初值在定义变量的在定义变量的同时同时给变量赋值,即在内存中开辟出一个空给变量赋值,即在内存中开辟出一个空间后马上给此空间赋值间后马上给此空间赋值但这个空间的值并不是固定不变的,但这个空间的值并不是固定不变的,在程序的运行中一样在程序的运行中一样可以改变。 可以改变 char a='\x64', b='d'; int a1=6, a2=98; a=‘A’; b=‘\n’; a1=011; a2=121; int a=4; //定义语句,在开辟空间后马上为空间赋定义语句,在开辟空间后马上为空间赋值值 a=6; //重新为该空间赋值重新为该空间赋值a4 656算术运算符和算术表达式算术运算符和算术表达式一、算术运算符和算术表达式一、算术运算符和算术表达式+ -- * // % 用算术运算符连接起来的式子是算术表达式用算术运算符连接起来的式子是算术表达式两个整数相除结果为整数两个整数相除结果为整数 1/2=0 5/2=2整数才可求余,余数的符号与左边数的符号相同整数才可求余,余数的符号与左边数的符号相同3%2=1 -3%2=-1 3%-2=1 -3%-2=-1 8%4=0二、优先级与结合性二、优先级与结合性()() * / % + —57三、强制转换类型三、强制转换类型(类型名)(表达式)(类型名)(表达式)((double) a (int) (x+y) (int) 6.2%4=2在强制类型运算后原变量不变,但得到一个所需类在强制类型运算后原变量不变,但得到一个所需类型的中间变量。 型的中间变量如:如:int x; float y=5.8; x=(int)y;x=5y=5.8y的值没有改的值没有改变,仍是单精变,仍是单精度浮点型度浮点型58四、自增、自减运算符四、自增、自减运算符 (难点)难点) ++ ----i6i37 int i, j; i=3; j = ++i;i=4 j=4 ++在前在前, 先运算先运算,后赋后赋值值 int i, j; i=3; j = i++;i=4 j=3 ++在后在后, 先赋值先赋值,后运后运算算j44i3j34i=6; i++; i=i+1 i=7 ++i; i=i+1 i=7 i=6; i----; i=i--1 i=5 ----i ; i=i--1 i=5i6 7591))自增、自减运算符只能用于变量,不可用于常量和表自增、自减运算符只能用于变量,不可用于常量和表达式达式因为表达式在内存内没有具体空间,常量所占的空间不能因为表达式在内存内没有具体空间,常量所占的空间不能重新赋值重新赋值3++ ((x+y)++ (--i)++若若i=3, j=2 (i++) +j 等于等于5i=4, j=22)结合方式自右至左,优先级最高,向右取最大)结合方式自右至左,优先级最高,向右取最大--i++ --(i++) i+++j (i++) +j60赋值运算符和赋值表达式赋值运算符和赋值表达式bmw=2002"="左边左边必须是变量名。 必须是变量名若若“ = ” 两边变量类型不同,在赋值时要进两边变量类型不同,在赋值时要进行行类型转换类型转换转换原则:根据左边变量的类型转换转换原则:根据左边变量的类型转换61少字节少字节多字节多字节1)若多字节变量为)若多字节变量为unsigned ,则转换后多余字节补则转换后多余字节补零0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 11 1 1 1 1 1 1 1unsignedshort int a=-1;unsigned long b;b=a;a ab b621 1 1 1 1 1 1 1 1 1 1 1 1 1 1 11 1 1 1 1 1 1 1有符号型,符号扩展有符号型,符号扩展short int a=-1;long b;b=a;2)若多字节变量为有符号型,则转换后扩展少字)若多字节变量为有符号型,则转换后扩展少字节的最高位节的最高位转换后,数据的符号不变转换后,数据的符号不变a ab b63多字节多字节少字节少字节低位照搬低位照搬1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1int a=-1;short int b;b=a;b=-1int a=65535;short int b;b=a;b=-1b ba a1 1 1 1 1 1 1 164赋值表达式赋值表达式a=b=5 ;; b=5 a=5"="的结合性为的结合性为自右至左自右至左复合的赋值运算符复合的赋值运算符a+=3 a=a+3 x*=y+3 x=x*(y+3)x/=x-4 x=x/(x-4) x+=y x=x+yi+=j-- i=i+(j--)65a=12; a+=a-=a*a;12a a=a-(a * a) =12-(12*12)=-132 a=a+(-132)=-132-132=-264-132-26466关系运算符和关系表达式关系运算符和关系表达式关系运算符(比较运算)关系运算符(比较运算) < > <= >= = = !=1. = = 与与 =2. a=5; 赋值运算赋值运算 a= =5;;判断是否相等判断是否相等2.< > <= >= 的优先级大于的优先级大于= = !=3. 算术运算符的优先级大于关系运算符的优先级算术运算符的优先级大于关系运算符的优先级67关系表达式:用关系运算符将表达式连接起来称为关系表达式:用关系运算符将表达式连接起来称为关系表达式。 其值非真即假在关系表达式其值非真即假在C++语言中,用非语言中,用非0代表真,用代表真,用0表示假关系表达式的结果只有两个,关系表达式的结果只有两个,真为真为1,假为,假为0 a=2 b=3 c=4a>2 a>b+c a= =2 a= ='a'a>'a' b=a= =2'a'>'A' b= ='a'+1c-a= =a00100110168 逻辑运算符逻辑运算符 1.运算符运算符 与与&& 或或 || 非非!! A B 结果结果000010100111有有0出出0,全,全1出出1A,B同时成立同时成立&&A B 结果结果000011101111有有1出出1,全,全0出出0A或或B有一个成立有一个成立| |A 结果结果0 11 0有有0出出1,,有有1出出0!!69江苏籍的男生江苏籍的男生江苏籍的学生和所有男生江苏籍的学生和所有男生非江苏籍的学生非江苏籍的学生江苏籍江苏籍&&男生男生例如:两个条件:例如:两个条件:江苏籍江苏籍 男生男生江苏籍江苏籍||男生男生!江苏籍!江苏籍注意:注意:1.优先级:优先级:!&&| | !!算术算术关系关系逻辑逻辑赋值赋值逗号逗号703.不可写为不可写为 1 两种 5>3 && 2 || 8<4-!04.当前面的表达式可以得出整个表达式的结果时,当前面的表达式可以得出整个表达式的结果时,不必再求后面的表达式不必再求后面的表达式a&&b&&c 当当a为为0时,表达式为时,表达式为0,不必求,不必求b与与ca||b||c 当当a为为1时,表达式为时,表达式为1,不必求,不必求b与与c71x=4 y=5i= ++x= =5 || ++y= =6x=5 y=5 i=1i= x++= =5&& y++= =6x=5 y=5 i=0判断某年是否为闰年判断某年是否为闰年1)能被)能被400整除整除2)能被)能被4整除,不能被整除,不能被100整除整除 (2200年不是年不是)year%400= =0year%4= =0&& year%100!=0(year%400= =0) || (year%4= =0&&year%100!=0)72当当c==4时,以下的值各多少?时,以下的值各多少?(c=1)&&(c=3)&&(c=5)(c= =1)||(c= =2) || (c= =5)(c!=2) && (c!=4) &&(c>=1)&&(c<=5)10073sizeof()()运算符运算符 sizeof()运运算算符符是是一一个个单单目目运运算算符符,,用用于于计计算算某某一一个个操作数类型的字节数操作数类型的字节数。 其格式为:其格式为:sizeof((<类型类型>))sizeof((int)) //其值为其值为4sizeof((float)) //其值为其值为4sizeof((double) //其值为其值为8sizeof((char) //其值为其值为174逗号运算符和逗号表达式逗号运算符和逗号表达式表达式表达式1,表达式,表达式2,表达式,表达式3,,…,表达式,表达式n顺序求解,结果为最后一个表达式的值,并且优先顺序求解,结果为最后一个表达式的值,并且优先级最低a=(3+4, 5*6, 2+1); a=3a=3*3, a+6, a+7;16(a=3*5, a*4), a+520a=9a=1575下列语句中表达式中下列语句中表达式中i, j的值各为多少的值各为多少1、、int i=0, j=0; 2、、 int i=0, j=1; i=3, (j++)+i ; i+=j*=3;3、、int i=1, j=0; 4、、int i=1, j=1; j=i=((i=3)*2); i+=j+=2;i=3,j=1i=3,j=3i=6,j=6i=4,j=376各类数值型数据间的混合运算各类数值型数据间的混合运算整型、实型、字符型数据间可以混合运算。 整型、实型、字符型数据间可以混合运算floatdoublelongunsignedintchar10+'a'+1.5-87.65*'b'在进行运算时,在进行运算时,不同类型的数据要先转换成同一类不同类型的数据要先转换成同一类型的数据再进行运算型的数据再进行运算转换规则如下:转换规则如下:77第三章第三章 简单的输入输出简单的输入输出78 输入语句:输入语句:cin程序在执行期间,程序在执行期间,接收外部信息的操作称为接收外部信息的操作称为程序的输入程序的输入;而把;而把程序向外部发送信息的操程序向外部发送信息的操作称为程序的输出作称为程序的输出在C++中没有专门的输中没有专门的输入输出语句,所有输入输出是通过入输出语句,所有输入输出是通过输入输出输入输出流流来实现的来实现的 79要要使使用用C++提提供供的的输输入入输输出出时时,,必必须须在在程程序序的开头增加一行:的开头增加一行:#include 第五章)作详细介绍80 输入十进制整数和实数cin >> <变量名变量名1>《《 >> <变量名变量名2> ...... 》》(举例说明)(举例说明)int a,b;cin>>a>>b;//程序运行至此停下,等待从键盘输入变量值程序运行至此停下,等待从键盘输入变量值键盘输入:键盘输入:3 5 a:5.578i1:34ch1:ach2:b83若若要要把把从从键键盘盘上上输输入入的的每每一一个个字字符符,,包包括括空空格格和和回回车车键键都都作作为为一一个个输输入入字字符符赋赋给给字字符符型型变变量量时时,,必必须须使用函数使用函数cin.get()其格式为:其格式为:cin.get(<字符型变量字符型变量>);;cin.get()从从输输入入行行中中取取出出一一个个字字符符,,并并将将它它赋赋给给字字符符型型变变量量这这个个语语句句一一次次只只能能从从输输入入行行中中提提取取一一个个字符char c1;cin.get(c1);84char ch1,ch2,ch3;cin.get(ch1);cin.get(ch2);cin.get(ch3);输入:输入:A B 当要求按八进制或十六进制输入数据时,制数据当要求按八进制或十六进制输入数据时,在在cin中必须指明相应的数据类型:中必须指明相应的数据类型:hex为十六进为十六进制;制;oct为八进制;为八进制;dec为十进制为十进制 86int i,j,k,l;cin>>hex>>i;//指明输入为十六进制数指明输入为十六进制数cin>>oct>>j;//指明输入为八进制数指明输入为八进制数cin>>k;//输入仍为八进制数输入仍为八进制数cin>>dec>>l;//指明输入为十进制数指明输入为十进制数当执行到语句当执行到语句cin时,若输入的数据为:时,若输入的数据为:11 11 12 12 如如上上例例中中,,输输入入k的的值值时时,,仍为八进制仍为八进制883、、输输入入数数据据的的格格式式、、个个数数和和类类型型必必须须与与cin中中所所列列举举的的变变量量类类型型一一一一对对应应一一旦旦输输入入出出错错,,不不仅仅使使当当前前的的输输入入数数据据不不正正确确,,而而且且使使得得后后面面的的提提取取数数据据也也不正确cin>>a,b; cin>>a b; cin>>ab; int a, b;cin>>a>>b; 89输出数据输出数据cout与输入与输入cin对应的输出是对应的输出是cout输出流当当要要输输出出一一个个表表达达式式的的值值时时,,可可使使用用cout来来实实现现,,其一般格式为:其一般格式为:cout << <表达式表达式> 《《<< <表达式表达式>......》》;其中运算符其中运算符“<<”称为插入运算符,它将紧跟其后称为插入运算符,它将紧跟其后的表达式的值,输出到显示器的表达式的值,输出到显示器当前光标当前光标的位置 90int a=6;float f1=12.4;char s1[ ]=“abcd”;cout<int i1=4,i2=5;float a=3.5;cout<<“a*i1=“<
如上面的两个输出语句可改写为:如上面的两个输出语句可改写为:cout < 一旦按指定的宽一旦按指定的宽度输出其后的输出项后,又回到原来的缺省输出方式度输出其后的输出项后,又回到原来的缺省输出方式 94输出八、十六进制数和科学表示法的实数输出八、十六进制数和科学表示法的实数对对于于整整型型数数据据可可指指定定以以十十六六进进制制或或八八进进制制输输出出,,而而对对于于实实型型数数据据可可指指定定以以科科学学表表示示法法形形式式输输出出例例如如,,设设有有如如下一个程序:下一个程序:#include 对对实实数数的的输输出出,,也也是是这这样样,,一一旦旦指指明明按按科科学学表表示示法法输输出出实实数数,,则则接接着着的的输输出出均均按按科科学学表表示示法法输输出出,,直直到到指指明明以以定定点点数数输输出出为为止止明明确确指指定定按按定定点点数数格格式式输输出出((缺缺省省的的输输出出方方式式))的的语句为:语句为:cout.setf(ios::fixed,ios::floatfield);96第四章第四章 C++的流程控制语句的流程控制语句97程序的三种基本结构程序的三种基本结构1、顺序、顺序AB2、选择、选择条件?条件?真真假假ABx>y??真真假假z=xz=y983、循环、循环A当当P为真为真当型当型i++i<10PAYN99直到直到P为真为真A直到型直到型i>=10i++PAYN100if语句语句判断选择判断选择语句,有三种形式:语句,有三种形式:1)if(表达式)(表达式) 语句语句语句语句条件条件真真假假语句语句2语句语句1条件条件真真假假2) if(表达式)(表达式) 语句语句1 else 语句语句2 if (a>b) cout<b) cout<
后可跟复合语句 2) 注意注意 ;的位置 3) 注意多重注意多重 if else 的搭配if (a>b) { a=1; b=0; }else { a=0; b=1; } a=0b=1a=1b=0a>b真真假假104if (i >j) i++;if (i>j); i++;i+ +i>j真真假假if 总是与它上面最近的总是与它上面最近的 else 配对,如要改变,用复合语配对,如要改变,用复合语句{句{ }注意书写格式注意书写格式,相互配对的语句要对齐相互配对的语句要对齐i>j真真假假i+ +105例:输入两个实数,按代数值由小到大次序输出这两个数例:输入两个实数,按代数值由小到大次序输出这两个数void main( void ){ float a,b,t; //定义变量定义变量cout<<“ Input 2 Real Number:\n";//在屏幕上的提示信息在屏幕上的提示信息 cin>>a>>b; //给变量赋值给变量赋值 a:7, b:3 if(a>b) { t=a; a=b; b=t; }//交换数据,用中间变量交换数据,用中间变量 cout<
++中的唯一的三目运算符表达式表达式1?表达式?表达式2 :表达式:表达式3表达式表达式3表达式表达式2表达式表达式1真真假假max=a>b?a:b ; // 求求a, b中的大者中的大者当当 a=2 b=1 a>b为真,表达式的值等于为真,表达式的值等于a, max值为值为2当当 a=1 b=2 a>b为假,表达式的值等于为假,表达式的值等于b, max值为值为2注意:注意:1.条件运算符的优先级比赋值运算符高条件运算符的优先级比赋值运算符高 2. x=(x=3) ? x+2 : x-33.2. 结合方向自左至右结合方向自左至右 a>b?a:c>d?c:d4.3. 三个表达式的类型可不同三个表达式的类型可不同 z=a>b?'A':a+bx=5108x=9, y=6, z=5;x=((x+y)%z>=x%z+y%z)?1:0;cout<<"x= "< 多分支选择语句if语句只有两个分支,而实际问题中常常语句只有两个分支,而实际问题中常常需要用到多分支的选择如,成绩分为需要用到多分支的选择如,成绩分为A(100~85)、、B(84~70)、、C(69~60)、、D(60以下以下)等‘A’100~85Y‘B’Y84~70‘C’Y69~60‘D’Yno passNNNN显示出错显示出错113cin.get(grade);if(grade= =‘A’) cout<<“100~85\n”;else if (grade= =‘B’) cout<<“84~70\n”; else if (grade= =‘C’) cout<<“69~60\n”; else if (grade= =‘D’) cout<<“no pass\n”; else cout<<“error\n”; 114switch(表达式)表达式) {{ case 常量表达式常量表达式1:语句:语句1 case 常量表达式常量表达式2:语句:语句2 … … case 常量表达式常量表达式n:语句:语句n default:语句:语句n+1 }}switch(grade) {{ case ‘A’::cout<<“100~85\n”; case ‘B’::cout<<“84~70\n”; case ‘C’::cout<<“69~60\n”; case ‘D’::cout<<“no pass\n”; default::cout<<“error\n”; }}如果如果grade为为 ‘A’,则结则结果为果为100~8584~7069~60no passerror115其流程为:先计算表达式的值,然后顺序地其流程为:先计算表达式的值,然后顺序地与与case子句中所列出的各个常量进行比较,若子句中所列出的各个常量进行比较,若表达式的值与常量中的值相等,就开始进入表达式的值与常量中的值相等,就开始进入相应的相应的case语句执行程序,语句执行程序,遇到遇到case和和default也不再进行判断,直至也不再进行判断,直至switch语句结束。 语句结束如果如果要使其在执行完相应的语句后中止执行下一要使其在执行完相应的语句后中止执行下一语句,可以在语句后加语句,可以在语句后加break116switch(grade) {{ case ‘A’::cout<<“100~85\n”; break; case ‘B’::cout<<“84~70\n”; break; case ‘C’::cout<<“69~60\n”; break; case ‘D’::cout<<“no pass\n”; break; default::cout<<“error\n”; }}117注意:注意:1、、switch与与if不同,它仅能判断一种逻辑关系,即不同,它仅能判断一种逻辑关系,即表达式是否表达式是否等于等于指定的常量,而指定的常量,而 if 可以计算并判断可以计算并判断各种表达式各种表达式2、、case子句后必须为常量,常常是整型和字符型子句后必须为常量,常常是整型和字符型3、、default可以省略,这时,不满足条件什么也不可以省略,这时,不满足条件什么也不执行。 执行1184、、case和和default只起标号的作用,只起标号的作用,顺序可以颠倒顺序可以颠倒,,颠倒时注意后面的颠倒时注意后面的break语句5、多个、多个case语句可以共用一组程序语句可以共用一组程序 case ‘A’: case ‘B’: case ‘C’: cout<<“pass!\n”;119void main(void ){ int i=10; switch(i) { case 9: i++; case 10: i++; case 11: i++; default: i++; } cout<<“i=”<
由键盘输入,输出其中最大的数 122while语句语句while ( 表达式)表达式) {{ 语句组语句组1 }}{语句组{语句组2}}表达式表达式语句组语句组1真真语句组语句组2假假a=3;while(a<100) a=a+5;cout<<“a=“<
括起2、循环体内或表达式中必须有使循环结束的条件,、循环体内或表达式中必须有使循环结束的条件,即一定有一个循环变量即一定有一个循环变量3、、while表达式可以成为语句,要特别小心表达式可以成为语句,要特别小心125k=2;while(k!=0) cout< 表达式,至少执行一次循环体当第一当第一次循环表达式的值为真时,次循环表达式的值为真时,while与与do—while的结果完全一样,否则结果不相同的结果完全一样,否则结果不相同134x=0,y=0;do { y++; x*=x; } while ((x>0)&&(y>5));cout<<“y=“< 也进入不了循环体2、、for语句中的三个表达式可以部分省略或全部省略,语句中的三个表达式可以部分省略或全部省略,但但;;不能省略,不能省略,若省略表达式若省略表达式2,则表示循环条件,则表示循环条件为真为真3、、for语句中三个表达式可以是任何有效的语句中三个表达式可以是任何有效的C语言表达式语言表达式139void main(void){ char i, j ; for (i=‘a’,j=‘z’ ; i 环的嵌套注意:注意:1、循环体内有多个语句要用{}括起来循环体内有多个语句要用{}括起来2、书写格式要清晰书写格式要清晰for ( ; ; ) { ..... for ( ; ; ) { ....... } } 142void main(void){ int i, j, k=0, m=0; for ( i=0; i<2; i++) { for ( j=0; j<3; j++) k++; k- =j; } m=i+j; cout<<“k=“< 最小公倍数为两数之积除以最大公约数4*6/2=122、若、若r=0,则算法结束,,则算法结束,n为最大公约数,否则做为最大公约数,否则做33、、mn , nr , 回到回到1m=4 n=2 r=m%n=4%2=0所以,公约数所以,公约数=2146最大公约数:能同时被最大公约数:能同时被m和和n整除的最大数整除的最大数r=m>n?n:mfor(i=1; i 项,得出后一项比前一项大多少倍通项:通项:t=x*x/((2*n)*(2*n-1))第第n项项/第第n-1项:项:表明前一项比后一项大表明前一项比后一项大t倍倍,即后一项乘即后一项乘t等于前一等于前一项项后一项=后一项=(-1)×前一项前一项×t149S=0;term=1;n=1;//一定要赋初值一定要赋初值while(fabs(term)>=1e-5){S=S+term;term=(-1)*term*x*x/((2*n)*(2*n-1));n++;}term=(-1)*term*t;前一项前一项当前项当前项旧的旧的新的新的后一项=后一项=(-1)×前一项前一项×t设通项为设通项为term,则可以写出迭代公式,则可以写出迭代公式t=x*x/((2*n)*(2*n-1))150t=x*x/((2*n)*(2*n-1))第第n项项/第第n-1项:项:第一项:第一项:term=1;第一次循环:第一次循环:S=S+term; term=(-1)*term*t;第二次循环:第二次循环:S=S+term; term=(-1)*term*t;这时这时左边的左边的term代表第二项,而代表第二项,而右边的右边的term为第一项。 为第一项这时这时左边的左边的term代表第三项,而代表第三项,而右边的右边的term为第二项为第二项term=(-1)*term*t;前一项前一项当前项当前项同样是同样是term,在循环中不断用旧的数值去推导赋值出新的,在循环中不断用旧的数值去推导赋值出新的数值151S=0;term=1;n=1;//一定要赋初值一定要赋初值while(fabs(term)>=1e-5){S=S+term;term=(-1)*term*x*x/((2*n)*(2*n-1));n++;}旧的旧的新的新的152break语句和语句和continue语句语句break在在switch语句中,可以语句中,可以使流程跳过判断体使流程跳过判断体,,执执行下面的程序行下面的程序在循环体中,也可以从循环体内跳在循环体中,也可以从循环体内跳出循环体,提前结束循环出循环体,提前结束循环for ( ; ; ) { cin>>x; if (x= =123) break; } 当输入当输入123时,结束循环时,结束循环break 只能退出一层循环或只能退出一层循环或switch语句153a=10 ; y=0;do { a+=2; y+=a; cout<<“a=“<50) break; } while (a=14);第一次:第一次:a=12 y=12输出:输出:a=12 , y=12第二次:第二次:a=16 y=28输出:输出:a=16 , y=28第三次:第三次:a=16 y=44输出:输出:a=16 , y=44第四次:第四次:a=16 y=60输出:输出:a=16 , y=60154continue:其作用为:其作用为结束本次循环结束本次循环,即跳过循环体中下面,即跳过循环体中下面尚未执行的语句,尚未执行的语句,接着进行下一次是否执行循环的判定接着进行下一次是否执行循环的判定。 void main(void){ int i; for (i=1 ; i<=5 ; i++ ) { if (i%2) cout<<“*”; else continue; cout<<“#”; } cout<<“ $\n”;}ii<=5i%2输出输出输出:输出:*#*#*#$1真真1*#2真真0无无3真真1*#4真真0无无5真真1*#6假假$155void main(void){ int i, j, x=0 ; for (i=0 ; i<2; i++) { x++; for (j=0;j<=3; j++) { if ( j%2 ) continue; x++; } x++; } cout<<“x=“<< x< for(... ; ... ; ... ){ ........ break; ........}158continue:其作用为:其作用为结束本次循环结束本次循环,即跳过循环体,即跳过循环体中下面尚未执行的语句,中下面尚未执行的语句,接着进行下一次是否执行接着进行下一次是否执行循环的判定循环的判定for(... ; ... ; ... ){ ........ continue; ........}while( ...... ){ ........ continue; ........}159求素数:只可以被求素数:只可以被1与自身整除的数与自身整除的数判断一个数判断一个数 t 是否为素数,用是否为素数,用2到到t-1循环除for( i=2; i 可将循环次数降低t/2(i>=t/2)160求范围内的素数求范围内的素数(50~100)::for(t=50, k=0 ; t<=100; t++){ for( i=2; i 请编写程序计算陌生人给百万富翁多少这个契约请编写程序计算陌生人给百万富翁多少钱,百万富翁给陌生人多少钱?钱,百万富翁给陌生人多少钱?163利用循环语句编程,打印下列图形:利用循环语句编程,打印下列图形: * * * * * * * * * * * * * * * *找规律:找规律: 上面四行上面四行 行号行号空格空格星号星号131222313404 for(i=0;i<4;i++){for(j=4-i-1;j>0;j--)cout<<" ";for(k=1;k<=i+1;k++)cout<<" * ";cout< 同 131 131/11=11 12+32+12=11分析:分析:数字应该从数字应该从100循环到循环到999将每位数字剥出,判断其是否满足条件将每位数字剥出,判断其是否满足条件169满足以下条件三位数满足以下条件三位数n,它除以,它除以11所得到的商等于所得到的商等于n的各位数字的平方和,且其中至少有两位数字相的各位数字的平方和,且其中至少有两位数字相同 131 131/11=11 12+32+12=11分析:分析:用用a,b,c分别代表三位数,分别代表三位数,a,b,c分别从分别从0循环到循环到9,组,组成所有可能的三位数,然后找出满足条件的数来成所有可能的三位数,然后找出满足条件的数来170求求n=1000时时π的近似值的近似值分析:分析:通项:通项:s=s×t迭代算法:迭代算法:上次迭代上次迭代的结果的结果本次计算本次计算的结果的结果迭代结束条件:迭代结束条件:迭代迭代 1000次次注意注意s与与t的初始值的初始值n从从1开始迭代开始迭代 s=1171下面程序的功能是用公式求下面程序的功能是用公式求π的近似值,直到最后一项的值的近似值,直到最后一项的值小于小于10-6为止。 请填空void main(void ){ int i=1; ______ pi=0; while (i*i<=10e+6) { pi=______________ ; i++; } pi=sqrt (6.0 *pi) ; cout<<“ pi=”< 成某一特定的任务C++是由函数构成的,是由函数构成的,函数是函数是C++的基本模块的基本模块有的函数完成某一操作;有的函数计算出一有的函数完成某一操作;有的函数计算出一个值通常,一个函数即能完成某一特定操个值通常,一个函数即能完成某一特定操作,又能计算数值作,又能计算数值175为什么要使用函数?为什么要使用函数?1、避免重复的编程避免重复的编程2、使程序更加模块化,便于阅读、修改使程序更加模块化,便于阅读、修改参数(多个)参数(多个)函数值函数值(唯一)唯一)函数体函数体所编写的函数应尽量少与主调函数发生所编写的函数应尽量少与主调函数发生联系,这样便于移植联系,这样便于移植176说明:说明:1、一个源程序文件由一个或多个函数组成,编译程序以文、一个源程序文件由一个或多个函数组成,编译程序以文件而不是以函数为单位进行编译的件而不是以函数为单位进行编译的2、一个程序可以由多个源文件组成,可以分别编译,统一、一个程序可以由多个源文件组成,可以分别编译,统一执行3、一个程序必须有且只有一个、一个程序必须有且只有一个main( )函数,函数,C++从从main( )函数开始执行函数开始执行4、、C++语言中,语言中,所有函数都是平行独立的,无主次、相互所有函数都是平行独立的,无主次、相互包含之分包含之分。 函数可以嵌套调用,不可嵌套定义函数可以嵌套调用,不可嵌套定义5、从使用角度来说,分标准函数和用户自定义函数;从形、从使用角度来说,分标准函数和用户自定义函数;从形式来说,分无参函数和有参函数式来说,分无参函数和有参函数177库函数是库函数是C++编译系统已预定义的函数编译系统已预定义的函数,用户根据,用户根据需要可以直接使用这类函数库函数也称为标准函需要可以直接使用这类函数库函数也称为标准函数为了方便用户进行程序设计,为了方便用户进行程序设计,C++把一些常用数学把一些常用数学计算函数(如计算函数(如sqrt()、、exp()等)、字符串处理函数、等)、字符串处理函数、标准输入输出函数等,都作为库函数提供给用户,标准输入输出函数等,都作为库函数提供给用户,用户可以直接使用系统提供的库函数用户可以直接使用系统提供的库函数库函数有很多个,当用户使用任一库函数时,在程库函数有很多个,当用户使用任一库函数时,在程序中必须包含相应的头文件序中必须包含相应的头文件 如如 #include 用户在程序中,根据应用的程序定义为一个函数用户在程序中,根据应用的需要,由的需要,由用户自己定义函数用户自己定义函数,这类函数称为用户,这类函数称为用户自定义的函数自定义的函数 根据定义函数或调用时是否要给出参数,又可将函根据定义函数或调用时是否要给出参数,又可将函数分为:无参函数和有参函数数分为:无参函数和有参函数 179函数定义的一般形式函数定义的一般形式一、无参函数一、无参函数主调函数并不将数据传给被调函数主调函数并不将数据传给被调函数类型说明类型说明 函数名(函数名(void)) {{ 函数体函数体 }} 无参函数主要用于完成某一操作无参函数主要用于完成某一操作不传递参数不传递参数参数(多个)参数(多个)函数值函数值(唯一)唯一)函数体函数体180void main(void ){ printstar ( ); print_message ( ); printstar( );}void printstar (void ){ cout<<“* * * * * * * * * * *\n”;} void print_message (void){ cout<<“ How do you do! \n”;} 调用函数调用函数调用函数调用函数调用函数调用函数函数类型函数类型函数名函数名函数体函数体两个被调函数两个被调函数主要用于完成主要用于完成打印操作。 打印操作181输出:输出: * * * * * * * * * * * How do you do! * * * * * * * * * * * 182二、有参函数二、有参函数主调函数和被调函数之间有数据传递主调函数和被调函数之间有数据传递主调函数可以将参数传递给被调函数,被调函数函数可以将参数传递给被调函数,被调函数中的结果也可以带回主调函数中的结果也可以带回主调函数类型说明类型说明 函数名(函数名(形式参数列表说明形式参数列表说明 )) {{ 函数体函数体 }} 183int max (int x,int y){ int z; z=(x>y)? x : y ; return z;} void main (void ){ int a,b,c; cin>>a>>b; c=max (a , b) ; cout<<“The max is”<< c< 实参可以是常量、实参可以是常量、变量或复杂的表达式,不管是哪种情况,变量或复杂的表达式,不管是哪种情况,在在调用时实参必须是一个确定的值调用时实参必须是一个确定的值形参与实参类型相同,一一对应形参与实参类型相同,一一对应形参必须要定义类型形参必须要定义类型,因为在定义被调函数,因为在定义被调函数时,不知道具体要操作时,不知道具体要操作什么数什么数,而定义的是,而定义的是要操作要操作什么类型什么类型的数186int max (int x,int y){ int z; z=(x>y)? x : y ; return z;} void main (void ){ int a,b,c; cin>>a>>b; c=max (a+b , a*b) ; cout<<“The max is”< 调用结束调用结束后,形参所占用的内存单元被释放后,形参所占用的内存单元被释放2、实参对形参变量的传递是、实参对形参变量的传递是“值传递值传递”,即单向传递即单向传递在在内存中实参、形参分占不同的单元内存中实参、形参分占不同的单元3、形参只作用于被调函数,可以在别的函数中使用相同的、形参只作用于被调函数,可以在别的函数中使用相同的变量名5a8b实参实参xy形参形参58188void fun(int a, int b){ a=a*10; b=b+a; cout<
的数形参是被调函数中的变量;形参是被调函数中的变量;实参是主调函数实参是主调函数赋给被调函数的特定值赋给被调函数的特定值在函数调用语句中,在函数调用语句中,实参不必定义数据类型实参不必定义数据类型,,因为实参传递的是因为实参传递的是一个具体的值一个具体的值(常量常量),程序可依据这个数值,程序可依据这个数值的表面形式来判断其类型,并将其赋值到对的表面形式来判断其类型,并将其赋值到对应的形参变量中应的形参变量中191函数的返回值函数的返回值函数的返回值通过函数的返回值通过return语句获得语句获得函数只函数只能有唯一的返回值能有唯一的返回值函数返回值的类型就是函数的类型函数返回值的类型就是函数的类型return语句可以是一个表达式,函数先计算语句可以是一个表达式,函数先计算表达式后再返回值表达式后再返回值return语句还可以终止函数,并将控制返回语句还可以终止函数,并将控制返回到主调函数到主调函数一个函数中可以有一个以上的一个函数中可以有一个以上的return语句,执行语句,执行到哪一个到哪一个return语句,哪一个语句起作用语句,哪一个语句起作用 192int add ( int a, int b){ return (a+b);} int max ( int a, int b){ if (x>y) return x ; else return y;} 若函数体内没有若函数体内没有return语语句,就一直执行到函数体句,就一直执行到函数体的末尾,然后返回到主调的末尾,然后返回到主调函数的调用处。 函数的调用处先计算,后返回先计算,后返回可以有多个可以有多个return语句语句193不带返回值的函数可说明为不带返回值的函数可说明为void型函数的类型与函数参数的类型没有关系函数的类型与函数参数的类型没有关系double blink ( int a, int b)如果函数的类型和如果函数的类型和return表达式中的类型不一致,表达式中的类型不一致,则以函数的类型为准则以函数的类型为准函数的类型决定返回值的函数的类型决定返回值的类型对数值型数据,可以自动进行类型转换对数值型数据,可以自动进行类型转换 既然函数有返回值,这个值当然应属于某一个确定既然函数有返回值,这个值当然应属于某一个确定的类型,应当在定义函数时指定函数值的类型的类型,应当在定义函数时指定函数值的类型 int max (float a, float b) // 函数值为整型函数值为整型 函数返回值的类型,也是函数的类型函数返回值的类型,也是函数的类型194参数(多个)参数(多个)函数值函数值(唯一)唯一)函数体函数体int max ( int a, int b){ int z; z=x>y?x:y; return z; } 如果有函数返回如果有函数返回值值,返回值就是函返回值就是函数值数值,必须惟一。 必须惟一如果有函数返回如果有函数返回值值, 函数的类型就函数的类型就是返回值的类型是返回值的类型函数体的类型、形式参数的类型必须函数体的类型、形式参数的类型必须在函数的定义中体现出来在函数的定义中体现出来195函数的调用函数的调用函数调用的一般形式函数调用的一般形式函数名(实参列表);函数名(实参列表);形参与实参类型相同,一一对应形参与实参类型相同,一一对应 i=2; f (i, ++i);函数调用的方式函数调用的方式作为语句作为语句 printstar( );作为表达式作为表达式 c=max (a,b);作为另一个函数的参数作为另一个函数的参数 cout< 197float max(float x, float y){ float z; z=(x>y)? x : y ; return z;} void main (void){ float a,b, c; cin>>a>>b; c=max (a+b , a*b) ; cout<<“The max is”< 200void main(void){ int i=2, x=5, j=7; void fun(int,int); fun ( j, 6); cout<>x; y=f1(x); cout<<“x=“< 时,累加结束205float fun(float x){ float s=1, t=1; do { t=t/x; s+=t; }while (t>0.00001); return s;}void main(void){ float x; cin>>x; cout<<“s=“< 在主函数中输入一个不小于在主函数中输入一个不小于6 6的偶数的偶数n n,函数中输出以下形式的结果,函数中输出以下形式的结果∶∶34=3+31 210函数的嵌套调用函数的嵌套调用C语言中,语言中,所有函数都是平行独立的,无主次、相所有函数都是平行独立的,无主次、相互包含之分互包含之分函数可以嵌套调用,不可嵌套定义函数可以嵌套调用,不可嵌套定义int max ( int a, int b){ int c; int min ( int a, int b) { return ( ab? a : b);} int max ( int a, int b){ int c; c=min(a,b); return ( a>b? a : b);} int min ( int a, int b){ return ( a
函数212int power(int m,int n)//m^n{int i,product=m;for(i=1;i 问第岁问第4个人多少岁,他说比第个人多少岁,他说比第3个人大个人大2岁问第3个人多少岁,他说比第个人多少岁,他说比第2个人大个人大2岁问第2个人多少岁,他说比第个人多少岁,他说比第1个人大个人大2岁问第1个人多个人多少岁,他说是少岁,他说是10岁请问第岁请问第5个人多大?个人多大?age(5)=age(4)+2age(4)=age(3)+2age(3)=age(2)+2age(2)=age(1)+2age(1)=10age(n)=10 n=1age(n-1)+2 n>1int age ( int n ){ int c; c=age(n-1)+2; return c;}void main(void){ int age(int); cout< 必须有递归终止条件必须有递归终止条件216用递归方法求用递归方法求n!n!=1 n=0,1n*(n-1)! n>1float fac (int n){ float y; if ((n= =0)|| (n= =1) y=1; else y=n*fac(n-1); return y;}void main (void){ float y; int n; cout<<“Input n:\n”; cin>>n ; cout< 不同218void main (void){ int i=5; cin>>i; f(i);}void f(int n ){if(n= =0) return; else {cout< 在在C++中,作用域共分为五类:中,作用域共分为五类:块作用域、文件作块作用域、文件作用域、函数原型作用域、函数作用域和类的作用域用域、函数原型作用域、函数作用域和类的作用域 222块作用域块作用域我们把用花括号括起来的一部分程序称为一个块我们把用花括号括起来的一部分程序称为一个块在块内说明的标识符,只能在该块内引用,即其在块内说明的标识符,只能在该块内引用,即其作用域在该块内,开始于标识符的说明处,结束作用域在该块内,开始于标识符的说明处,结束于块的结尾处于块的结尾处 在一个函数内部定义的变量或在一个块中定义的变在一个函数内部定义的变量或在一个块中定义的变量称为局部变量量称为局部变量 223在函数内或复合语句内部定义的变量,其作用域是在函数内或复合语句内部定义的变量,其作用域是从定义的位置起到函数体或复合语句的结束从定义的位置起到函数体或复合语句的结束形参形参也是局部变量也是局部变量float f1( int a){ int b,c; .....}float f2( int x, int y){ int i, j; .....}void main(void ){ int m, n; .....}x,y,i,j 有效有效a,b,c有效有效m,n有效有效224主函数主函数main中定义的变量,也只在主函数中有效,中定义的变量,也只在主函数中有效,同样属于局部变量同样属于局部变量。 不同的函数可以使用相同名字的局部变量,它们在不同的函数可以使用相同名字的局部变量,它们在内存中分属不同的存储区间,互不干扰内存中分属不同的存储区间,互不干扰void main(void){ int x=10; { int x=20; cout< 在函数外定义的变量称为全局变量全局变量的作用域称为文件作用域,即在整个文件全局变量的作用域称为文件作用域,即在整个文件中都是可以访问的中都是可以访问的 其缺省的作用范围是其缺省的作用范围是:从定义全局变量的位置开始从定义全局变量的位置开始到该源程序文件结束到该源程序文件结束当在块作用域内的变量与全局变量同名时,当在块作用域内的变量与全局变量同名时,局部变局部变量优先 229p,q有效有效int p=1, q=5;float f1( int a){ int b,c; .....}char c1,c2;main( ){ int m, n; .....}a,b,c有效有效m,n有效有效c1,c2有效有效全局变量全局变量局部变量局部变量全局变量全局变量增加了函数间数据联系的渠道增加了函数间数据联系的渠道,在函数调,在函数调用时可以得到多于一个的返回值用时可以得到多于一个的返回值2304int min;int max (int x, int y){ int z; min=(x 231在同一个源文件中,外部变量与局部变量同名,则在局部在同一个源文件中,外部变量与局部变量同名,则在局部变量的作用范围内,外部变量不起作用变量的作用范围内,外部变量不起作用int a=3, b=5;int max(int a, int b){ int c; c=a>b? a:b; return c;}void main(void){ int a=8; cout< float tt(int x , float y); //函数函数tt的原型说明的原型说明 由于所说明的标识符与该函数的定义及调用无关,由于所说明的标识符与该函数的定义及调用无关,所以,所以,可以在函数原型说明中只作参数的类型说可以在函数原型说明中只作参数的类型说明,而省略参量名明,而省略参量名 float tt (int , float); 235int i=0;int workover(int i){ i=(i%i)*((i*i)/(2*i)+4); cout<<“i=“<
运行结束动态存储:在程序运行期间根据需要分配存储空间,动态存储:在程序运行期间根据需要分配存储空间,函数函数结束后立即释放空间结束后立即释放空间若一个函数在程序中被调用两次,若一个函数在程序中被调用两次,则每次分配的单元有可能不同则每次分配的单元有可能不同程序区程序区静态存储区静态存储区动态存储区动态存储区全局变量全局变量静态局部变量静态局部变量动态局部变量动态局部变量238局部变量局部变量的分类的分类动态变量(动态变量(auto):默认,存储在动态区):默认,存储在动态区寄存器变量(寄存器变量(register):):在在cpu内部存储内部存储静态局部变量(静态局部变量(static):存储在静态区):存储在静态区动态局部变量未被赋值时,动态局部变量未被赋值时,其值为随机值其值为随机值其作用域的函其作用域的函数或复合语句结束时,数或复合语句结束时,空间被程序收回空间被程序收回程程序序执执行行到到静静态态局局部部变变量量时时,,为为其其在在静静态态区区开开辟辟存存储储空空间间,,该空间一直被保留,该空间一直被保留,直到程序运行结束直到程序运行结束由于存储在静态区,静态局部变量或全局变量未赋初值时,由于存储在静态区,静态局部变量或全局变量未赋初值时,系统自动使之为系统自动使之为0。 239int fun(int a){ int c; static int b=3; c=a+ b++; return c;}void main(void){ int x=2, y; y=fun(x); cout< 2、静态(、静态(static)存储类别)存储类别1、、extern 存储类别存储类别全局变量是在函数的外部定义的,编译时全局变量是在函数的外部定义的,编译时分配在静态存储分配在静态存储区,如果未赋初值,其值为区,如果未赋初值,其值为0它仅能在本文件中引用它仅能在本文件中引用,即使在其它文件中用,即使在其它文件中用extern说明说明也不能使用也不能使用相当于限制了全局变量的作用域范围相当于限制了全局变量的作用域范围244程序的作用是:给定程序的作用是:给定b的值,输入的值,输入a和和m,,求求a×b和和am的值文件文件file1.c中的内容为:中的内容为:int a;void main(void){ extern int power (int); int b=3, c, d, m; cin>>a>>m; c=a*b; cout<
对应,在别的函数中不能引用全局静态变量全局静态变量::static 在函数外部定义,在函数外部定义,只限在本文件中使只限在本文件中使用用,与,与extern对应对应当变量名相同致使作用域相重时,起作用的是当变量名相同致使作用域相重时,起作用的是最近说明最近说明的的那个变量那个变量全局变量全局变量静态静态 static 外部外部 extern自动自动 auto局部变量局部变量静态静态 static 寄存器寄存器 register 246主调函数主调函数调用处调用处被调函数被调函数主调函数主调函数调用处调用处被调函数被调函数内联函数内联函数 将被调函数体的代将被调函数体的代码直接插到调用处码直接插到调用处内联函数内联函数247内联函数的实质是用存储空间(使用更内联函数的实质是用存储空间(使用更多的存储空间)来换取时间(减少执行时间)多的存储空间)来换取时间(减少执行时间).内联函数的定义方法是,在函数定义时,内联函数的定义方法是,在函数定义时,在函数的类型前增加修饰词在函数的类型前增加修饰词inline 248inline int max (int x, int y){ int z; z=(x>y)? x : y ; return z;} void main (void ){ int a,b,c; cin>>a>>b; c=max (a+b , a*b) ; cout<<“The max is”< 语句外,所有的函数均可定义为内联函数2、、内内联联函函数数也也要要定定义义在在前前,,调调用用在在后后形形参参与与实实参参之之间间的关系与一般的函数相同的关系与一般的函数相同3、、对对于于用用户户指指定定的的内内联联函函数数,,编编译译器器是是否否作作为为内内联联函函数数来来处处理理由由编编译译器器自自行行决决定定说说明明内内联联函函数数时时,,只只是是请请求求编编译译器器当当出出现现这这种种函函数数调调用用时时,,作作为为内内联联函函数数的的扩扩展展来来实实现现,,而不是命令编译器要这样去做而不是命令编译器要这样去做4、、正正如如前前面面所所述述,,内内联联函函数数的的实实质质是是采采用用空空间间换换取取时时间间,,即即可可加加速速程程序序的的执执行行,,当当出出现现多多次次调调用用同同一一内内联联函函数数时时,,程程序序本本身身占占用用的的空空间间将将有有所所增增加加如如上上例例中中,,内内联联函函数数仅仅调用一次时,并不增加程序占用的存储间调用一次时,并不增加程序占用的存储间250具有缺省参数值和参数个数可变的函数具有缺省参数值和参数个数可变的函数在在C++中定义函数时,允许给参数指定一个缺中定义函数时,允许给参数指定一个缺省的值。 省的值在调用函数时,若明确给出了这种实在调用函数时,若明确给出了这种实参的值,则使用相应实参的值;若没有给出相参的值,则使用相应实参的值;若没有给出相应的实参,则使用缺省的值举例说明)应的实参,则使用缺省的值举例说明) 251int fac(int n=2){ int t=1; for(int i=1;i<=n;i++) t=t*i; return t;}void main(void){ cout<< fac(6) < 了缺省值,后面函数的定义不可有缺省值错误!错误!254参数个数可变的函数到目前为止,在定义函数时,都明确规定了函数的参数个数及类型在调用函数时,实参的个数必须与形参相同在调用具有缺省参数值的函数时,本质上,实参的个数与形参的个数仍是相同的,由于参数具有缺省值,因此,在调用时可省略在某些应用中,在定义在某些应用中,在定义函数时,并不能确定函数的参数个数,参数的个数在调时才能确定函数时,并不能确定函数的参数个数,参数的个数在调时才能确定在C++中允许定义参数个数可变的函数 255首先,必须包含头文件“stdarg.h”,因为要用到里面的三个库函数 va_start( )、va_arg( )和va_end( )其次,要说明一个va_list类型的变量va_list与int,float类同,它是C++系统预定义的一个数据类型(非float),只有通过这种类型的变量才能从实际参数表中取出可变有参数如:va_list ap;ab...ap(va_list)变量(可变参数)va_start(ap,b):初始化va_arg(ap,int):依次取参数va_end(ap):正确结束256va_start():有两个参数,va_start(ap,b); b即为可变参数前的最后一个确定的参数。 va_arg():有两个参数,va_arg(ap,int) int即为可变参数的数据类型名int temp;temp=va_arg(ap,int);va_end():完成收尾工作va_end(ap);在调用参数个数可变的函数时,必定有一个参数指明可变参数的个数或总的实参个数如第一个参数值为总的实际参数的个数257使用参数数目可变的函数时要注意以下几点:1、在定义函数时,固定参数部分必须放在参数表的前面,可变参数在后面,并用省略号“...”表示可变参数在函数调用时,可以没有可变的参数2、必须使用函数va_start()来初始化可变参数,为取第一个可变的参数作好准备工作;使用函数va_arg()依次取各个可变的参数值;最后用函数va_end()做好结束工作,以便能正确地返回3、在调用参数个数可变的函数时,必定有一个参数指明可变参数的个数或总的实参个数258函数的重载函数的重载所谓函数的重载是指完成不同功能的函数可以具所谓函数的重载是指完成不同功能的函数可以具有有相同的函数名相同的函数名 C++的编译器是根据的编译器是根据函数的实参函数的实参来确定应该调用来确定应该调用哪一个函数的。 哪一个函数的 int fun(int a, int b){ return a+b; }int fun (int a){ return a*a; }void main(void){ cout< 这个标识符称为这个标识符称为宏名宏名,,编译前编译前的替代过程称为的替代过程称为“宏展开宏展开” define 标识符标识符 字符串字符串264#define PRICE 30 void main(void){ int num, total; /*定义变量定义变量*/ num=10; /*变量赋值变量赋值*/ total=num*PRICE; cout<<"total=“< 与宏名相同,也不进行置换4、在进行宏定义中,可以用已定义的宏名,进行、在进行宏定义中,可以用已定义的宏名,进行层层置换层层置换267# define R 3.0# define PI 3.1415926# define L 2*PI*R# define S PI*R*Rvoid main(void){ cout<<“L=“< 串中的非形参字符保持不变define S(a, b) a*barea=S(3,2)3*2机械机械地将实参代入地将实参代入宏定义的形参形式宏定义的形参形式S(a,b)等同于等同于 a*bS(3,2)等同于等同于 3*2270#define PI 3.1415926#define S(r) PI*r*rvoid main(void){ float a, area, b; a=3.6; b=4.0; area=S(a); cout<<“r=“<
定义宏时在宏名与带参数的括弧间不能有空格define S_ (r) P*r*r 带参数的宏与函数调用的区别带参数的宏与函数调用的区别相同:有实参、形参,代入调用相同:有实参、形参,代入调用不同之处:不同之处:1、、函数调用先求表达式的值,然后代入形参函数调用先求表达式的值,然后代入形参,而宏只是,而宏只是机机械替换械替换2、、函数调用时形参、实参进行类型定义函数调用时形参、实参进行类型定义,而宏不需要,只,而宏不需要,只是作为是作为字符串替代字符串替代3、、函数调用是在运行程序时进行的,其目标代码短,但程函数调用是在运行程序时进行的,其目标代码短,但程序执行时间长序执行时间长而宏调用是在编译之前完成的,运行时已而宏调用是在编译之前完成的,运行时已将代码替换进程序中,目标代码长,执行时间稍快将代码替换进程序中,目标代码长,执行时间稍快一般用宏表示实时的、短小的表达式一般用宏表示实时的、短小的表达式273#define A 3#define B(a) ((A+1)*a)执行执行 x=3*(A+B(7)); 后,后, x的值为的值为:93#define neg(x) ((-x)+1)int neg( int x){return x+1; }void main(void){ int y; y=neg(1); cout<<“y=“< 即将另外的文件包含到本文件之中 include “文件名文件名”file1.cppBA#include “file2.cpp”ABfile1.cppfile2.cpp275注意:注意:1、文件名是、文件名是C的源文件名,是文本文件,后缀名可的源文件名,是文本文件,后缀名可以任选cpp *.h2、一个、一个#include语句只能指定一个被包含文件语句只能指定一个被包含文件3、文件名用双引号或尖括号括起来文件名用双引号或尖括号括起来4、、包含后所有源文件编译为一个可执行文件包含后所有源文件编译为一个可执行文件276条件编译条件编译C语言允许有选择地对程序的某一部分进行编译语言允许有选择地对程序的某一部分进行编译也就是对一部分源程序指定编译条件也就是对一部分源程序指定编译条件源程序源程序可以将部分源程序可以将部分源程序不不转换为机器码转换为机器码277条件编译有以下几种形式:条件编译有以下几种形式:1、、 # ifdef 标识符标识符 程序段程序段1 # else 程序段程序段2 # end if当标识符已被定义过(用当标识符已被定义过(用#define定义定义),则对程序段,则对程序段1进行编译,进行编译,否则编译程序段否则编译程序段2.# define DEBUG......# ifdef DEBUG cout< define DEBUG......# ifndef DEBUG cout< 当一个完整的程序被存放在多于一个文件中时,称当一个完整的程序被存放在多于一个文件中时,称为程序的多文件组织为程序的多文件组织 282内部函数和外部函数内部函数和外部函数内部函数:函数只限于在本文件中调用,其它文件不能调内部函数:函数只限于在本文件中调用,其它文件不能调用,用用,用static 定义该函数定义该函数static float fac( int n){ ...... }外部函数:函数的默认形式,可以被其它文件调用,用外部函数:函数的默认形式,可以被其它文件调用,用extern 定义该函数调用时,在文件中用定义该函数调用时,在文件中用extern 说明void main(void){ extern enter_string( ); char str[80]; enter_string(str); ..........}说明外部函数说明外部函数283补充算法补充算法方程求解方程求解1、牛顿切线法、牛顿切线法只有为数不多的方程有精确解,一般都是用迭代方法近似只有为数不多的方程有精确解,一般都是用迭代方法近似求方程的解方程求方程的解方程f(x)=0的实数解实际上是曲线的实数解实际上是曲线f (x)在在x轴轴上交点的值。 上交点的值f(x)xyx02841、任选一、任选一x值值x1,在在y1=f(x1)处做切线与处做切线与x轴相交于轴相交于x2处f(x)xyx0f(x1)x1x22、若、若|x2-x1|或或|f(x2)|小于指定的精度,则令小于指定的精度,则令x1=x2,继续做,继续做1当其满足所需的精度时,当其满足所需的精度时,x2就是方程的近似解就是方程的近似解x1x2根据已知点求其切线的公式为:根据已知点求其切线的公式为:这就是牛顿切线法这就是牛顿切线法牛顿切线法收敛快,牛顿切线法收敛快,适用性强,缺陷是必适用性强,缺陷是必须求出方程的导数须求出方程的导数285已知方程为已知方程为f(x)=x*x-a时,用牛顿切线法求方程的解给定时,用牛顿切线法求方程的解给定初值初值x0,精度,精度10-6,算法编程如下算法编程如下cin>>x1; //从键盘输入从键盘输入x0 do{ x0=x1; x1=x0-(x0*x0-a)/(2*x0) ; // } while (fabs(x1-x0)>=1e-6) ;cout>>”x=”>>x1>>endl;旧值算本次循环的新值旧值算本次循环的新值上一循环的新值成为本次循环的旧值上一循环的新值成为本次循环的旧值2862、弦截法、弦截法f(x)xyx1、在、在x轴上取两点轴上取两点x1和和x2, 要确保要确保x1与与x2之间有且只有方程唯一的解之间有且只有方程唯一的解。 x1x2f(x1)f(x2)2、、x1与与x2分别与分别与f(x)相交于相交于y1=f(x1)、、y2=f(x2)3、做直线通过、做直线通过y1、、y2与与x轴交于轴交于x0点x0x2x04、若、若|f(x0)|满足给定的精度,则满足给定的精度,则x0即是方程的解,否则,若即是方程的解,否则,若f(x0)*f(x1)<0,,则则方程的解应在方程的解应在x1与与x0之间,令之间,令x2=x0,继续做,继续做2同理,若理,若f(x0)*f(x1)>0,,则则方程的解应在方程的解应在x2与与x0之间,令之间,令x1=x0,继续,继续做做2 ,直至满足精度为止直至满足精度为止287用两分法求方程的根用两分法求方程的根 x3-5x2+16x-80=0#include x1x22、求出、求出x1,x2的中点的中点x0x0x2x03、若、若|f(x0)|满足给定的精度,则满足给定的精度,则x0即是方程的解,否则,即是方程的解,否则,若若f(x0)*f(x1)<0,,则则方程的解应在方程的解应在x1与与x0之间,令之间,令x2=x0,,继续做继续做2同理,若同理,若f(x0)*f(x1)>0,,则则方程的解应在方程的解应在x2与与x0之间,令之间,令x1=x0,继续做,继续做2 ,直至满足精度为止直至满足精度为止x0=(x1+x2)/2289用两分法求方程的根用两分法求方程的根 x3-5x2+16x-80=0#include 的值,请填空include “math.h”double pi(double eps){ double s, t; int n; for ( ___________; t>eps; n++) { s+=t; t=n*t/(2*n+1); } return ___________ ;}main( ){ double x; cout<<“\nInput a precision:”; cin>>x; cout<< “π=“< 整个数组共用一个名字,而其中的每一项又称整个数组共用一个名字,而其中的每一项又称为一个元素为一个元素一、定义方式:一、定义方式:类型说明符类型说明符 数组名数组名[常量表达式常量表达式]; int a[4]; // 表明表明a数组由数组由4个个int型元素组成型元素组成 定义类型定义类型数组名称数组名称元素个数元素个数296 int a[4]; // 表明表明a数组由数组由4个个int型元素组成型元素组成 其元素分别为:其元素分别为:a[0], a[1], a[2], a[3] 其序号从其序号从0开始开始若存放首地址为若存放首地址为2000H,则在,则在内存中为:内存中为:a[3]a[2]a[1]a[0]2010H200CH2008H2004H2000HC++不允许对数组的大小作动态的定义,不允许对数组的大小作动态的定义,即即数组的数组的大小不能是变量大小不能是变量,必须是常量,必须是常量必须是常数必须是常数297如果要根据不同的数值改变数组的大小,可如果要根据不同的数值改变数组的大小,可用常量表达式如:用常量表达式。 如:#define SIZE 50void main(void){ int art[SIZE]; ......}298二、一维数组元素的引用二、一维数组元素的引用数组必须先定义,具体引用时(赋值、运算、输出)其元数组必须先定义,具体引用时(赋值、运算、输出)其元素素等同于变量等同于变量void main(void ){ int i, a[10]; for ( i=0; i<10; i++) a[i]=i; for ( i=9; i>=0 ; i--) cout<
注意:注意:1、对数组中的一部分元素列举初值,未赋值的部、对数组中的一部分元素列举初值,未赋值的部分是分是0int a[10]= {0,1, 2, 3, 4, 5};2、不能给数组整体赋值,只能一个一个地赋值不能给数组整体赋值,只能一个一个地赋值 int a[10]= {0,1,2,.....,9}; 非法非法int a[10]= {0,1, 2, 3, 4, 5,6,7,8,9};int a[10]= {0,1, 2, 3, 4, 5, 0, 0, 0, 0};3003、可以用、可以用 int a[ ]= {0,1, 2, 3, 4, 5, 6, 7, 8, 9}; 给数给数组赋值,组赋值,编译器会自动计算出内的元素项数,并将编译器会自动计算出内的元素项数,并将数组定义为该长度数组定义为该长度4、用局部、用局部static 或全局定义的数组不赋初值,或全局定义的数组不赋初值,系统系统均默认其为均默认其为‘\0’static int a[10];(即存储在静态数据区中的数组其(即存储在静态数据区中的数组其元素默认为元素默认为0))数组在内存中顺序存放,第一个元素位于地址的最数组在内存中顺序存放,第一个元素位于地址的最低端。 低端0000000000a301求求Fibonacci数列:数列:1,1,2,3,5,8,......的前的前20个数,即个数,即 F1=1 (n=1) F2=1(n=2) Fn=Fn-1+Fn-2 (n>=3) 2113853211....f[7]f[6]f[5]f[5]f[4]f[3]f[2]f[1]f[0]f [i]=f [i-1]+f [i-2]void main (void){ int i; int f [20]={1,1}; for (i=2 ; i<20 ; i++ ) f [i]=f [i-1]+f [i-2]; for ( i=0; i<20; i++) { if (i%5= =0) cout<<“\n”; cout< 将相邻的两个数两两比较,将小的调到前头985420895420859420854920854290854209第一趟第一趟循环循环5次次584209548209542809第二趟第二趟循环循环4次次854209543089543089453089435089430589第三趟第三趟循环循环3次次304430589340589304589304589第四趟第四趟循环循环2次次034589第五趟第五趟循环循环1次次总结:总结:n次数次数趟数趟数j(1~n-1)54321n-j12345共有共有6个数个数for (j=1; j<=n-1; j++) for (i=1; i<=n-j ; i++) { if (a[i]>a[i+1]) { t=a[i]; a[i]=a[i+1]; a[i+1]=t; } } 305一般,元素的序号从一般,元素的序号从0开始,因此,程序可以变动如下:开始,因此,程序可以变动如下:for (j=0; j 若存放首地址为若存放首地址为2000H,,则在内存中为:则在内存中为:a[0][0]a[0][1]a[0][2]a[0][3]a[1][0]a[1][1] a[1][2]a[1][3]a[2][0]a[2][1]a[2][2]a[2][3]2000H2008H2010H 2014H201cH 2020H2028H 202cH即在内存中,多维数组依然是即在内存中,多维数组依然是直线顺序直线顺序排列的,排列的,第第一个元素位于最低地址处一个元素位于最低地址处其元素分别为:其元素分别为:a[0][0], a[0][1], a[0][2], a[0][3], a[1][0], a[1][1], a[1][2], a[1][3], a[2][0], a[2][1], a[2][2], a[2][3] 308二、二维数组的引用二、二维数组的引用与一维数组一样,二维数与一维数组一样,二维数组必须先定义,其维数必组必须先定义,其维数必须是常量具体引用时须是常量具体引用时(赋值、运算、输出)其(赋值、运算、输出)其元素等同于变量元素等同于变量void main(void){ int a[2][3], i, j; cout<<“Input 2*3 numbers\n”; for (i=0; i<2; i++) /* 输入输入 */ for(j=0; j<3; j++) cin>>a[i][j]; for (i=0; i<2; i++) /* 输出输出 */ { for(j=0; j<3; j++) cout<输出:输出: _ _ _1_ _ _2_ _ _3 _ _ _4_ _ _5_ _ _6定义定义赋值赋值输出输出309三、二维数组的初始化三、二维数组的初始化在定义数组的同时给数组元素赋值。 即在编译阶段在定义数组的同时给数组元素赋值即在编译阶段给数组所在的内存赋值给数组所在的内存赋值1、分行赋值、分行赋值int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};2、顺序赋值、顺序赋值int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12}; //依次赋值依次赋值 3103、部分赋值、部分赋值int a[3][4]={{1},{5},{9}}; /* a[0][0]=1, a[1][0]=5, a[2][0]=9 其余元素为其余元素为0 */int a[3][4]={{0,1},{5}}; /* a[0][0]=0, a[0][1]=1, a[1][0]=5 */ 1000500090000100500000003114、、分行或全部赋值时,分行或全部赋值时,可以省略第一维,第二维可以省略第一维,第二维不可省int a[ ][4]={{1,2},{5,6,7,8,}{9,10,11,12}}; 5、不能给数组整体赋值,只能一个一个地赋值不能给数组整体赋值,只能一个一个地赋值 6、用、用static 定义的数组不赋初值,系统均默认其为定义的数组不赋初值,系统均默认其为‘\0’。 static int a[2][3];int a[2][3]={1,2,3,.....,12};312void main(void){ int a[3][3], i, j; for (i=0; i<3; i++) { for (j=0; j<3; j++) if (i= =2) a[i][j]=a[i-1][a[i-1][j]]+1; else a[i][j]=j; cout<
那个元素的值,以及其所在的行号和列号 先考虑解此问题的思路从若干个数中求最大者的先考虑解此问题的思路从若干个数中求最大者的方法很多,我们现在采用方法很多,我们现在采用““打擂台打擂台””算法如果有算法如果有若干人比武,先有一人站在台上,再上去一人与其若干人比武,先有一人站在台上,再上去一人与其交手,败者下台,胜者留台上第三个人再上台与交手,败者下台,胜者留台上第三个人再上台与在台上者比,同样是败者下台,胜者留台上如此在台上者比,同样是败者下台,胜者留台上如此比下去直到所有人都上台比过为止最后留在台上比下去直到所有人都上台比过为止最后留在台上的就是胜者的就是胜者314程序模拟这个方法,开始时把程序模拟这个方法,开始时把a[0][0]a[0][0]的的值赋给变量值赋给变量maxmax,,maxmax就是开始时的擂主,就是开始时的擂主,然后让下一个元素与它比较,将二者中然后让下一个元素与它比较,将二者中值大者保存在值大者保存在maxmax中,然后再让下一个元中,然后再让下一个元素与新的素与新的maxmax比,直到最后一个元素比完比,直到最后一个元素比完为止maxmax最后的值就是数组所有元素中最后的值就是数组所有元素中的最大值。 的最大值315max=a[0][0]; //使使max开始时取开始时取a[0][0]的值的值 for (i=0;i<=2;i++) //从第从第0行到第行到第2行行 for (j=0;j<=3;j++) //从第从第0列到第列到第3列列 if (a[i][j]>max)//如果某元素大于如果某元素大于max { max=a[i][j]; //max将取该元素的值将取该元素的值 row=i; //记下该元素的行号记下该元素的行号i colum=j; //记下该元素的列号记下该元素的列号j } cout< 均成绩,并输出低于平均成绩的学生成绩输入负数结束输入负数结束void main(){ float x[100],sum=0, ave,a; int n=0,i; cout<<“Input score\n”; _________; while(__________) { x[n]=a; _______; _________ cin>>a; }ave=sum/n;cout<<“ave=“< 倒序排列321void main(void){ int x , i, n ; int a[100]; cin>>x; i=0; while(x) { a[i]=x%8; x=x/8; i++; } n=i;for(i=n-1;i>=0;i--) cout<>x; 2536913 25 34 56 7836913 34 56 78x25y25343432336913 34 56 78x25y25343436913 25 56 78x3434y345656324void main(void){ int a[6]={1,4,7,10,12}; int x; for(int i=0;i<5;i++) cout<>x; for(i=0;i<5;i++) { if(a[i]>x) break; }for(int j=i;j<=5;j++){int y=a[j];a[j]=x;x=y;}for( i=0;i<6;i++)cout<>x; 25369 132534 56 78326void main(void){ int a[6]={1,4,7,10,12}; int b[6]; int x; for(int i=0;i<5;i++)cout<>x; for(i=0;i<5;i++)if(a[i] 之间的所有素数 筛法:首先将筛法:首先将1~~n个数为数组置初值个数为数组置初值2的倍数不的倍数不是素数,置是素数,置0;; 3的倍数不是素数,置的倍数不是素数,置0;;5的倍数不的倍数不是素数,置是素数,置0;;....,依次类推,最后将数组中不,依次类推,最后将数组中不是是0的元素输出的元素输出23456789 10 11 12 13 14 15 16 17 18 19 20230507090 11 0 13 0 15 0 17 0 19 0230507000 11 0 13 000 17 0 19 0330数组作为函数参数数组作为函数参数一、数组元素作函数参数一、数组元素作函数参数数组元素作函数实参,用法与一般变量作实参相同,数组元素作函数实参,用法与一般变量作实参相同,是是“值传递值传递”331有两个数据系列分别为:有两个数据系列分别为:int a[8]={26,1007,956,705,574,371,416,517};int b[8]={994,631,772,201,262,763,1000,781};求第三个数据系列求第三个数据系列 c ,要求,要求c中的数据是中的数据是a b中对应中对应数的最大公约数。 数的最大公约数 int a[8]={26, 1007, 956, 705, 574, 371, 416, 517};int b[8]={994, 631, 772, 201, 262, 763, 1000, 781}; c[8]={2, 1, 4, 3 , 2 , 7 , 8, 11}332int gys(int m,int n){ int r; if(m 这时,这时,函数传递的是数组在内存中的地址函数传递的是数组在内存中的地址在在C++中,数组名被认为是中,数组名被认为是数组在内存中存放的数组在内存中存放的首地址首地址实参中的数组地址传到形参中,实参形参实参中的数组地址传到形参中,实参形参共用同共用同一段内存一段内存334void fun(int a[2]){ for(int i=0;i<2;i++) a[i]=a[i]*a[i]; }void main(void){ int b[2]={2,4}; cout<x[j+1]) { t=x[j]; x[j]=x[j+1]; x[j+1]=t;} } void main(void){ int a[5]={20,4,16,8,10}; sort(a, 5 ); for(int i=0;i<5;i++) cout<
void main(void){ static float score[10]={ 100, 90, ...}; float aver; aver=average(score); cout<<“aver=“< 递的是数组在内存中的首地址实参和形参共占实参和形参共占一段内存单元一段内存单元,,形参数组中的值发生变化,也相形参数组中的值发生变化,也相当于实参数组中的值发生变化当于实参数组中的值发生变化 score[8]score[6]score[4]score[2]score[0]array[8]array[6]array[4]array[2]array[0]scorearray339程序中的函数程序中的函数p( )用于计算:用于计算:主函数利用函数完成计算主函数利用函数完成计算int p(int a, int x[], int b, int y[], int n){ int i, s; for(________; i 中数据的个数例如:例如:原数组:原数组:2 2 2 3 4 4 5 6 6 6 6 7 7 8 9 9 10 10 10删除后:删除后:2 3 4 5 6 7 8 9 10 342用多维数组名作函数参数用多维数组名作函数参数同样,实参向形参传递的是数组的首地址同样,实参向形参传递的是数组的首地址如果实参、形参是二维数组,如果实参、形参是二维数组,则形参可以省略第一维则形参可以省略第一维,不,不可省略第二维,且可省略第二维,且第二维必须与实参中的维数相等第二维必须与实参中的维数相等int array[ ][10]int score[5][10]int array[3][10]int score[5][10]int array[ ][8]int score[5][10]错误错误343有一个有一个3×4的矩阵,求其中的最大元素的矩阵,求其中的最大元素int max_value (int array[ ][4]){ int i, j, k, max; max=array[0][0]; for (i=0; i<3; i++) for (j=0; j<4; j++) if (array[i][j]>max) max=array[i][j]; return (max);} void main (void){ static int a[3][4]={{1,3,5,7}, {2,4,6,8},{15,17,34,12}}; cout<<“max is ”< 一、字符数组的定义一、字符数组的定义char 数组名数组名[常量表达式常量表达式];char c[4]; /*每个元素占一个字节每个元素占一个字节 */c[0]=‘I’; c[1]=‘m’; c[2]=‘_’;;类型类型数组名数组名数组大小数组大小345二、字符数组的初始化二、字符数组的初始化与数值数组的初始化相同,取其相应字符的与数值数组的初始化相同,取其相应字符的ASCII值char c[10]={‘I’, ‘ ’, ‘a’, ‘m’, ‘ ’, ‘a’, ‘ ’ , ‘b’, ‘o’, ‘y’}; 随机随机‘y’‘o’‘b’‘ ’‘a’‘ ’‘m’‘a’‘ ’‘I’cc[0]c[9]346如果字符个数大于数组长度,做错误处理;如果数值个数如果字符个数大于数组长度,做错误处理;如果数值个数小于数组长度,后面的字节全部为小于数组长度,后面的字节全部为‘\0’如果省略数组长度,则字符数即为数组长度如果省略数组长度,则字符数即为数组长度static char c[ ]={‘I’, ‘ ’, ‘a’, ‘m’, ‘ ’, ‘a’, ‘ ’ , ‘g’, ‘i’, ‘r’,’l’}; 同理,也可定义和初始化一个二维或多维的字符数组。 分同理,也可定义和初始化一个二维或多维的字符数组分层或省略最后一维层或省略最后一维char st1[ ]={65, 66, 68};‘A’‘B’‘D’347三、字符数组的引用三、字符数组的引用void main(void){ char c[10]={‘I’, ‘ ’, ‘a’, ‘m’, ‘ ’, ‘a’, ‘ ’ , ‘b’, ‘o’, ‘y’}; int i; for (i=0; i<10; i++) cout< 349字符串与字符数组的区别:字符串与字符数组的区别:char a[ ]={‘C’,’H’,’I’,’N’,’A’};char c[ ]=“CHINA”; 随机随机随机随机ANIHC长度占长度占5个个字节字节随机随机‘\0’ANIHC长度占长度占6个字节个字节字符数组字符数组字符串字符串350可以用字符串的形式为字符数组赋初值可以用字符串的形式为字符数组赋初值char c[ ]={“I am a boy”}; /*长度长度11字节,以字节,以‘\0’结结尾尾 */char a[ ]={‘I’, ‘ ’, ‘a’, ‘m’, ‘ ’, ‘a’, ‘ ’ , ‘b’, ‘o’, ‘y’}; /* 长度长度10字节字节 */如果数组定义的长度大于字符串的长度,后面均为如果数组定义的长度大于字符串的长度,后面均为‘\0’char c[10]=“CHINA”; ‘\0’‘\0’‘\0’‘\0’‘\0’ANIHCc‘\0’的的ASCII为为0,,而而‘ ’(空格空格)的的ASCII为为32351char w[ ]={‘T’, ‘u’, ‘r’, ‘b’, ‘o’, ‘\0’};Turbo ‘\0’char w[ ]={“Turbo\0”};Turbo ‘\0’char w[ ]=“Turbo\0”;Turbo ‘\0’char w[ ]=‘Turbo\0’;非法非法352char a[2][5]={“abcd”, “ABCD”};abcd‘\0’ABCD‘\0’在在语句中语句中字符数组不能用赋值语句字符数组不能用赋值语句整体赋值整体赋值。 char str[12];str=“The String”;str为字符数组在内存中存储的地址,一经定义,便成为常为字符数组在内存中存储的地址,一经定义,便成为常量,不可再赋值量,不可再赋值char str[12]=“The String”;;非法,在语句中赋值非法,在语句中赋值定义数组,开辟空定义数组,开辟空间时赋初值间时赋初值353字符数组的输入输出字符数组的输入输出 逐逐个个字字符符的的输输入入输输出出这这种种输输入入输输出出的的方方法法,,通通常常是是使使用循环语句来实现的如:用循环语句来实现的如:char str[10];cout<<“输入十个字符:输入十个字符:”;for(int i=0;i<10;i++) cin>>str[i];//A ......A行将输入的十个字符依次送给数组行将输入的十个字符依次送给数组str中的各个元素中的各个元素定义定义赋值赋值354把把字字符符数数组组作作为为字字符符串串输输入入输输出出对对于于一一维维字字符符数数组组的的输输入入,,在在cincin中中仅仅给给出出数数组组名名;;输输出出时时,,在在coutcout中也只给出中也只给出数组名数组名。 void main (void ){char s1[50],s2[60];cout << “输入二个字符串输入二个字符串:”;cin >> s1;cin >> s2;cout << “\n s1 = “ << s1;cout << “\n s2 = “ << s2 << “\n”; }输入:输入:abcd 个字符送给字符串 定义定义从键盘接收一行字符从键盘接收一行字符输出到输出到‘\0’为为止止357从键盘输入一行字符,统计其中分别有从键盘输入一行字符,统计其中分别有多少大小写字母,多少大小写字母,以以$号结束输入号结束输入从键盘输入一行字符,统计其中分别有从键盘输入一行字符,统计其中分别有多少大小写字母多少大小写字母从键盘输入一行字符,其中的大写变小从键盘输入一行字符,其中的大写变小写,小写变大写写,小写变大写358从键盘接收一行字符,统计有多少个单词数?从键盘接收一行字符,统计有多少个单词数?we are students.weares字母字母字母字母空格空格空格空格字母字母字母字母字母字母空格空格字母字母不能用字母数或空格数来判断,只能用字母和空格不能用字母数或空格数来判断,只能用字母和空格状态变状态变化化的次数来判断的次数来判断设状态变量设状态变量word , 判别到字母时判别到字母时word为为1,判别到非字母,判别到非字母时时word为为0word的初始值为的初始值为0,当从,当从0变为变为1时,单词数加时,单词数加10110011101359void main(void){char s[80];int i=0, word=0,num=0;cin.getline (s,80);while(s[i]!='\0'){ if((s[i]>='a'&&s[i]<='z'||s[i]>='A'&&s[i]<='Z')&&word==0) {word=1;num++; } else if(s[i]==' '||s[i]=='\t') word=0; i++; } cout<<"num="< 后注意:第一个字符串要有足够的空间注意:第一个字符串要有足够的空间空间足够大空间足够大3622、复制两个字符串的函数、复制两个字符串的函数 strcpy (str1, str2)static char str1[20]={“I am a ”};static char str2[ ]={“boy”};strcpy (str1, str2);'\0''\0'amaIstr1'\0'yobstr2'\0''\0'a'\0'yobstr1strcpy ( str1, “CHINA”);'\0'ANIHCstr1strcpy (“CHINA”, str1);str1=str2; str1=“CHINA”; 字符串正确赋值字符串正确赋值均为非法均为非法3633、比较两个字符串的函数、比较两个字符串的函数 strcmp (str1, str2)此函数用来比较此函数用来比较str1和和str2中字符串的内容函数对字符串中字符串的内容函数对字符串中的中的ASCII字符字符逐个两两比较逐个两两比较,直到遇到不同字符或,直到遇到不同字符或‘\0’为止函数值由两个对应字符相减而得。 为止函数值由两个对应字符相减而得该函数具有返回值,返回值是两字符串对应的该函数具有返回值,返回值是两字符串对应的第一个第一个不同不同的的ASCII码的差值码的差值若两个字符串完全相同,函数值为若两个字符串完全相同,函数值为0 if ( strcmp (str1, str2)==0) { ........ }用来判断两字符用来判断两字符串是否相等串是否相等364static char str1[20]={“CHINA”};static char str2[ ]={“CHINB”};cout<< strcmp (str1, str2)< 函数参数为数组名,返回值为数组首字母到函数参数为数组名,返回值为数组首字母到‘\0’的长度并非数组在内存中空间的大小并非数组在内存中空间的大小char s[80];strcpy(s, “abcd”);cout< 6、、 strupr (str1)将将str1中的小写字母转换成大写字母中的小写字母转换成大写字母3687、函数、函数strncmp(字符串字符串1,字符串字符串2 , maxlen)函数原型为函数原型为: int strncmp(char str1[ ], char str2[ ],int m)第三个参数为正整数,它限定了至多比较的字符个数第三个参数为正整数,它限定了至多比较的字符个数若字符串若字符串1或字符串或字符串2的长度小于的长度小于maxlen的值时,函数的的值时,函数的功能与功能与strcmp( )相同当二个字符串的长度均大于当二个字符串的长度均大于maxlen的值时,的值时,maxlen为至为至多要比较的字符个数多要比较的字符个数cout< 贝的字符个数8、函数、函数strncpy(字符数组名字符数组名1, 字符串字符串2, maxlen)函数原型为函数原型为: void strncmp(char str1[ ], char str2[ ],int m)370char s[90],s1[90];strncpy(s,"abcdssfsdfk",3); //Astrncpy(s1,"abcdef " , 90);//Bcout< 最上面的数比较交换024589a[6]a[5]a[4]a[3]a[2]a[1]2、、a[min]与与a[2]比较比较1min1、、min=13、、min=22min4、、 a[min]与与a[3]比较比较024589a[6]a[5]a[4]a[3]a[2]a[1]即即9与与8比较比较假定元素假定元素序号序号为为1的数是最的数是最小的数小的数这时,最小数这时,最小数的序号变为的序号变为2即即8与与5比较比较375024589a[6]a[5]a[4]a[3]a[2]a[1]a[min]与与a[4]比较比较3min min=3 min=44mina[min]与与a[5]比较比较024589a[6]a[5]a[4]a[3]a[2]a[1]024589a[6]a[5]a[4]a[3]a[2]a[1]a[min]与与a[6]比较比较5min min=5 min=66mina[min]与与a[1]交换交换924580a[6]a[5]a[4]a[3]a[2]a[1]第一趟,循环第一趟,循环5次次这时,最小数这时,最小数的序号变为的序号变为3即即5与与4比较比较这时,最小数这时,最小数的序号变为的序号变为4即即4与与2比较比较这时,最小数这时,最小数的序号变为的序号变为5第一趟比较完毕,第一趟比较完毕,最小数是最小数是a[6],最小,最小数的序号为数的序号为6376924580a[6]a[5]a[4]a[3]a[2]a[1]a[min]与与a[3]比较比较2min min=2 min=33mina[min]与与a[4]比较比较924580a[6]a[5]a[4]a[3]a[2]a[1]924580a[6]a[5]a[4]a[3]a[2]a[1]a[min]与与a[5]比较比较4min min=4 min=55mina[min]与与a[6]比较比较924580a[6]a[5]a[4]a[3]a[2]a[1]从第二个数开始从第二个数开始比较,假定最小比较,假定最小数的序号为数的序号为2377984520a[6]a[5]a[4]a[3]a[2]a[1]a[min]与与a[2]交换交换5min min=5第二趟,循环第二趟,循环4次次第二趟比较完毕,第二趟比较完毕,最小数是最小数是a[5],最小,最小数的序号为数的序号为5378984520a[6]a[5]a[4]a[3]a[2]a[1]a[min]与与a[4]比较比较3min min=3 min=44mina[min]与与a[5]比较比较984520a[6]a[5]a[4]a[3]a[2]a[1]984520a[6]a[5]a[4]a[3]a[2]a[1]a[min]与与a[6]比较比较4min min=4 min=44mina[min]与与a[3]交换交换985420a[6]a[5]a[4]a[3]a[2]a[1]第三趟,循环第三趟,循环3次次379985420a[6]a[5]a[4]a[3]a[2]a[1]a[min]与与a[5]比较比较4min min=4 min=44mina[min]与与a[6]比较比较985420a[6]a[5]a[4]a[3]a[2]a[1]985420a[6]a[5]a[4]a[3]a[2]a[1]a[min]与与a[4]交换交换4min min=4第四趟,循环第四趟,循环2次次380985420a[6]a[5]a[4]a[3]a[2]a[1]a[min]与与a[6]比较比较5min min=5 min=55mina[min]与与a[5]交换交换985420a[6]a[5]a[4]a[3]a[2]a[1]第五趟,循环第五趟,循环1次次总结:总结:n次数次数趟数趟数i(1~n-1)54321n-i12345共有共有6个数个数for (i=1; i<=n-1; i++) {{ min=i ; for (j=i; j<=n; j++) if (a[min]>a[j]) min=j ; t=a[min]; a[min]=a[i]; a[i]=t; } 381一般,元素的序号从一般,元素的序号从0开始,因此,程序可以变动如下:开始,因此,程序可以变动如下:for (i=0; i 可以实时查询目前各变量的状态及程序的走向可以选择可以选择是否进入子函数是否进入子函数2))运行到光标处运行到光标处,可以直接使程序运行到,可以直接使程序运行到光标处光标处再进行再进行单步调试,这种方法可以不必运行正确的循环而直接到有单步调试,这种方法可以不必运行正确的循环而直接到有疑问的地方疑问的地方383在在a数组中查找与数组中查找与x值相同的元素所在的位置,数据从值相同的元素所在的位置,数据从a[1]元素开始存放,请填空:元素开始存放,请填空:#define MAX 10void main(void){ int a[MAX+1], x, i; for(i=1;i<=MAX;i++) cin>>__________; cout<<“Enter x:”; cin>>x; a[0]=x; i=MAX;while(x!=___________) ____________________;if(___________) cout< 顺序排列,被调函数返回删除后数组中数据的个数例如:例如:原数组:原数组:2 2 2 3 4 4 5 6 6 6 6 7 7 8 9 9 10 10 10删除后:删除后:2 3 4 5 6 7 8 9 10 387第七章第七章 结构体、共同体和枚举类型结构体、共同体和枚举类型 388定义:定义:将将不同种类型不同种类型的数据有序地的数据有序地组合在一起组合在一起,构,构造出一个造出一个新的数据类型新的数据类型,这种形式称为,这种形式称为结构结构体结构体是多种类型组合的结构体是多种类型组合的数据类型数据类型389struct 结构体名结构体名{{ 成员列表成员列表 };};struct student { int num; char name[20]; char sex; char addr[30]; };结构体名结构体名关键字关键字不同数据不同数据类型组成类型组成的的成员成员分号不能少分号不能少390定义结构体类型变量的方法定义结构体类型变量的方法一、先定义结构体类型再定义变量名一、先定义结构体类型再定义变量名struct student { int num; char name[20]; char sex; int age; float score; char addr[30];};struct student student1, student2;结构体类型名结构体类型名变量变量1变量变量2结构体类型只是一种数据结构体类型只是一种数据类型,不占内存空间,只类型,不占内存空间,只有定义结构体类型有定义结构体类型变量变量时时才开辟内存空间。 才开辟内存空间391# define STUDENT struct student STUDENT { int num; char name[20]; char sex; int age; float score; char addr[30]; }; STUDENT student1,student2;凡是凡是STUDENT的地的地方都用方都用struct student 机械替换机械替换392二、在定义类型的同时定义变量二、在定义类型的同时定义变量struct student { int num; char name[20]; char sex; int age; float score; char addr[30];} student1, student2;structstruct 结构体名结构体名 { { 成员列表成员列表 }变量名列表;}变量名列表; 紧接着定紧接着定义变量义变量393三、直接定义结构体类型变量三、直接定义结构体类型变量struct { int num; char name[20]; char sex; int age; float score; char addr[30]; } student1, student2;struct { 成员列表成员列表 }变量名列表;}变量名列表; 不出现结构体名。 不出现结构体名3942 2、在编译时,仅对、在编译时,仅对变量变量分配空间,不对分配空间,不对类型类型分配分配空间1 1、结构体类型的变量在内存、结构体类型的变量在内存依照其成员的顺序依照其成员的顺序顺顺序排列,所占内存空间的大小是其全体成员所占空序排列,所占内存空间的大小是其全体成员所占空间的间的总和总和3 3、对结构体中各个成员可以单独引用、赋值,其、对结构体中各个成员可以单独引用、赋值,其作用与变量等同作用与变量等同格式:格式:变量名变量名 . . 成员名成员名 student1 . numstudent1 . num3954 4、结构体的成员可以是另一个结构体类型结构体的成员可以是另一个结构体类型struct date{ int month; int day; int year; };struct student{ int num; char name[20]; struct date birthday; };成员类型成员类型成员名成员名5 5、成员名可以与程序中的变量名相同,二者分占不同的内、成员名可以与程序中的变量名相同,二者分占不同的内存单元,互不干扰。 例如,在程序中仍可以定义变量存单元,互不干扰例如,在程序中仍可以定义变量 intint num; num;396结构体类型变量的引用结构体类型变量的引用1 1、不能对结构体变量整体赋值或输出,只能分别对、不能对结构体变量整体赋值或输出,只能分别对各个成各个成员员引用cincin>>student1;>>student1;cincin>>student1.num; student1.num=100;>>student1.num; student1.num=100;可以将一个结构体变量可以将一个结构体变量整体整体赋给另外一个相同类型的结构赋给另外一个相同类型的结构体变量 student2=student1;student2=student1;2 2、嵌套的结构体变量必须逐层引用嵌套的结构体变量必须逐层引用student1.student1.birthday.birthday.dayday=25;=25;3 3、结构体变量中的成员可以同一般变量一样进行运算结构体变量中的成员可以同一般变量一样进行运算student1.birthday.day++; student1.birthday.day++; student1.score+=60;student1.score+=60;错误错误必须用成员名引用必须用成员名引用397对局部变量类型的结构体变量初始化对局部变量类型的结构体变量初始化void main(void){ struct student { long int num; char name[20]; char sex; char addr[30]; } student1={901031, “Li Lin”, ‘M’, “123 Beijing Road”};cout< 这种、同类型的结构体变量之间可以直接赋值这种赋值等同于各个成员的依次赋值赋值等同于各个成员的依次赋值 2 2、、结结构构体体变变量量不不能能直直接接进进行行输输入入输输出出,,它它的的每每一一个个成成员员能能否否直直接接进进行行输输入入输输出出,,取取决决于于其其成成员员的的类类型型,,若若是是基基本本类类型型或或是是字字符符数数组组,,则则可可以以直直接接输输入入输出3 3、、结结构构体体变变量量可可以以作作为为函函数数的的参参数数,,函函数数也也可可以以返返回回结结构构体体的的值值当当函函数数的的形形参参与与实实参参为为结结构构体体类类型型的的变变量量时时,,这这种种结结合合方方式式属属于于值值调调用用方方式式,,即即属属于值传递举例说明)于值传递举例说明)399结构体数组结构体数组结构体数组中的结构体数组中的每个元素都是一个结构体类型的变每个元素都是一个结构体类型的变量量,其中包括该类型的各个成员数组各元素在内,其中包括该类型的各个成员数组各元素在内存中连续存放存中连续存放400一、结构体数组的定义一、结构体数组的定义struct student { int num; char name[20]; char sex; int age; float score; char addr[30];} ;struct student stu[30];struct student { int num; char name[20]; char sex; int age; float score; char addr[30];} stu[30];直接定义直接定义401二、结构体数组的初始化二、结构体数组的初始化struct student { int num; char name[20]; char sex;} stu[3]={ {1011, "Li Lin",'M'}, {1012,"Wang Lan",'F'}, {1013,"Liu Fang",'F'};402struct student { int num; char name[20]; char sex;} stu[ ]={ {1011,"Li Lin",'M'}, {1012,"Wang Lan",'F'}, {1013,"Liu Fang",'F'}};403以下程序的结果是:以下程序的结果是:void main(void){ struct date { int year, month, day; } today; cout< <类型类型> <结构体类型名结构体类型名>::::<静态成员名静态成员名>;;其中类型要与在结构体中定义该成员的类型一致,结构体类型名其中类型要与在结构体中定义该成员的类型一致,结构体类型名指明静态成员属于哪一个结构体指明静态成员属于哪一个结构体 struct s{static int id;int eng;};int s::id=50;这时,未定义结构体变量,这时,未定义结构体变量,但已将静态成员的空间安但已将静态成员的空间安排好排好数据类型结构体类型若有定义:s s1,s2;则变量s1,s2的id成员占用同一存储空间(静态区)406在结构体中说明的静态成员属于引用性说明,必须在文件作用域中的某一个地方对静态的成员进行定义性说明,且仅能说明一次int s::id; 说明id的初值为0(静态变量的缺省初值均为静态变量的缺省初值均为0) 407共用体共用体C++语言中,允许语言中,允许不同的数据类型使用不同的数据类型使用同一存储区域同一存储区域,即,即同一存储区域由不同类型的变量共同表示这种数据类型同一存储区域由不同类型的变量共同表示这种数据类型就是共用体就是共用体union 共用体名共用体名{ 成员表列;成员表列;} 变量表列;变量表列;union data{ int i; char ch; float f;} a, b, c;union data a, b, c;这几个成员在共用体变量中存放在同一地址,相互覆盖,这几个成员在共用体变量中存放在同一地址,相互覆盖,其长度为最长的成员的长度其长度为最长的成员的长度。 408共用体变量的引用共用体变量的引用不能整体引用共用体变量,只能引用变量中不能整体引用共用体变量,只能引用变量中的成员a.i 表示为整型表示为整型a.ch 表示为字符型表示为字符型a.f 表示为符点型表示为符点型409共用体变量的特点共用体变量的特点1、共用体的空间在某一时刻只有一个成员在起作、共用体的空间在某一时刻只有一个成员在起作用2、共用体变量中的成员是最后一次放入的成员共用体变量中的成员是最后一次放入的成员3、共用体变量不能在定义时赋初值共用体变量不能在定义时赋初值4、共用体变量不能作为函数的参数或函数值,但、共用体变量不能作为函数的参数或函数值,但可使用指向共用体的指针变量可使用指向共用体的指针变量5、共用体可以作为结构的成员,结构体也可以作、共用体可以作为结构的成员,结构体也可以作为共用体的成员为共用体的成员410union un{ int i; double y;};struct st{ char a[10]; union un b;};cout< 为枚举类型枚举类型就是将变量的值一一列举出来,枚举类型就是将变量的值一一列举出来,变变量的值仅限于列举出来的值的范围内量的值仅限于列举出来的值的范围内414enum weekday {sun, mon, tue, wed, thu, fri, sat};enum weekday workday, weekend ;workday 和和 weekend 值值只能只能是是sun 到到 sat 其中之一其中之一enum {sun, mon, tue, wed, thu, fri, sat} workday, weekend ;其中其中sun, mon,....,sat称为称为枚举元素枚举元素或枚举常量,为用户定义或枚举常量,为用户定义的标识符,的标识符,所代表的意义所代表的意义由用户决定,在由用户决定,在程序中体现出来程序中体现出来数据类型数据类型可能取的值可能取的值变量变量另一种定义变量的方法另一种定义变量的方法4151 1、枚举元素为常量,不可赋值运算枚举元素为常量,不可赋值运算 sun=0; sun=0; monmon=1;=1;2 2、在定义枚举类型的同时,编译程序按顺序给每个枚举元、在定义枚举类型的同时,编译程序按顺序给每个枚举元素一个对应的序号,序号从素一个对应的序号,序号从0 0开始,后续元素依次加开始,后续元素依次加1 1。 enumenum weekday {sun, weekday {sun, monmon, , tuetue, wed, , wed, thuthu, , frifri, , sat};sat}; 0 , 1, 2, 0 , 1, 2, 3, 4, 5, 6 3, 4, 5, 6 3 3、可以在定义时人为指定枚举元素的序号值可以在定义时人为指定枚举元素的序号值enumenum weekday {sun=9, weekday {sun=9, monmon=2, =2, tuetue, wed, , wed, thuthu, , frifri, , sat};sat}; 9 , 2, 9 , 2, 3, 4, 5, 6 , 7 3, 4, 5, 6 , 7 4 4、、只能给枚举变量赋枚举值只能给枚举变量赋枚举值,若赋序号值必须进行强制类,若赋序号值必须进行强制类型转换。 型转换day=day=monmon ; ; day=1day=1; day=(; day=(enumenum weekday)1;weekday)1;4165、枚举元素可以用来进行比较判断枚举元素可以用来进行比较判断if (workday= = mon) if (workday>sun)6、枚举值可以进行加减一个整数、枚举值可以进行加减一个整数n的运算,得到其前后第的运算,得到其前后第n个元素的值个元素的值workday=sun;workday=(week)(workday+2);workday= = tue7、枚举值可以按整型输出其序号值枚举值可以按整型输出其序号值workday=tue;cout< 字符型占空间字符型占1个字节,整型数占个字节,整型数占4个字节个字节.....内存区的每个字节都有编号,称之为的每个字节都有编号,称之为地址地址2000H2001H2002H2003H2004H35内存内存内存单元内存单元的地址的地址内存单元内存单元的内容的内容4201、直接访问、直接访问按变量地址存取变量的值按变量地址存取变量的值cin>>i; 实际上放到定义实际上放到定义 i 单元单元的的地址中地址中2、间接访问、间接访问将变量的地址存放在另一个单元将变量的地址存放在另一个单元p中中,通过,通过 p 取出变量的地取出变量的地址,再针对变量操作址,再针对变量操作一个变量的地址称为该变量的指针一个变量的地址称为该变量的指针如果在程序中定义了一个变量或数组,那么,这个变量或如果在程序中定义了一个变量或数组,那么,这个变量或数组的地址(指针)也就确定为一个数组的地址(指针)也就确定为一个常量常量ii2000H2000H3000Hp421变量的变量的指针指针和指向变量的和指向变量的指针变量指针变量变量的指针就是变量的指针就是变量的地址变量的地址,,当变量定义后,其指针(地当变量定义后,其指针(地址)是一常量。 址)是一常量 可以可以定义一个变量定义一个变量专门用来专门用来存放存放另一变量的另一变量的地址地址,这种,这种变量我们称之为变量我们称之为指针变量指针变量在编译时同样分配一定字节的在编译时同样分配一定字节的存储单元,未赋初值时,该存储单元内的值是存储单元,未赋初值时,该存储单元内的值是随机随机的指针变量定义的一般形式为:指针变量定义的一般形式为:类型标识符类型标识符 *变量名变量名int *i_point;i2000Hint i; &i ::2000H 指针类型指针类型变量名变量名422指针指针变量变量同样也可以赋值:同样也可以赋值:int i, *i_point;i_point=&i;也可以在定义也可以在定义指针变量指针变量时赋初值:时赋初值:int i;int *i_point=&i; * 在在定义语句定义语句中只表示变量的类型是指针,没有任何计算中只表示变量的类型是指针,没有任何计算意义 * 在语句中表示在语句中表示“指向指向”表示表示“地址地址”一个指针变量只能指向同一类型的变量一个指针变量只能指向同一类型的变量即整型指针变量即整型指针变量只能放整型数据的地址,而不能放其它类型数据的地址。 只能放整型数据的地址,而不能放其它类型数据的地址3000H i_point2000H i2000H4232000H2000H3000H i_pointint i;int *i_point=&i;*i_point=3;表示表示指向指向表示表示类型类型i3424指针变量的引用指针变量的引用指针变量只能指针变量只能存放地址存放地址,不要将非地址数据赋给指针变量不要将非地址数据赋给指针变量int *p, i; p=100; p=&i;void main(void){ int a=10, b=100; int *p1, *p2; p1=&a; p2=&b; cout<
运算int i, *p1; p1=&i; 通过指针对通过指针对变量赋值变量赋值但指针变量未赋值,即但指针变量未赋值,即指针指向未知地址指针指向未知地址用指针变量前,必须用指针变量前,必须对指针变量赋值对指针变量赋值427输入输入a, b两个整数,按大小输出这两个数两个整数,按大小输出这两个数void main(void){ int *p1, *p2, *p, a,b; cin>>a>>b; p1=&a; p2=&b; if (a
表达式为3, a=47532008H2004H2000Ha&ap(*p)++; 4429int a=3, *p;p=&a;++, - -, * 优先级相同,都是右结合性优先级相同,都是右结合性7532008H2004H2000Ha&ap2004H*(p++)首先首先*p ,然后,然后p=p+1,指针指向下一指针指向下一个个int单元单元 表达式为表达式为3, p=2004Hp++; 430int a=3, *p;p=&a;++, - -, * 优先级相同,都是右结合性优先级相同,都是右结合性7532008H2004H2000Ha&ap4++(*p) *p=*p+1 a=4++*p431int a=3, *p;p=&a;++, - -, * 优先级相同,都是右结合性优先级相同,都是右结合性7532008H2004H2000Ha&ap2004H*(++p),首先:,首先:p=p+1, 然后取然后取*p即取p所指的下一个所指的下一个int单元的内容单元的内容表达式为表达式为5 p==2004H*++p 432指针变量作为函数参数:指针变量作为函数参数:函数的参数可以是指针类型,函数的参数可以是指针类型,它的作用是将它的作用是将一个变量的一个变量的地址地址传送到另一个函数中传送到另一个函数中。 指针变量作为函数参数与变量本身作函数参指针变量作为函数参数与变量本身作函数参数不同,数不同,变量作函数参数传递的是具体值变量作函数参数传递的是具体值,,而而指针指针作函数参数传递的是作函数参数传递的是内存的地址内存的地址433输入输入a, b两个整数,按大小输出这两个数两个整数,按大小输出这两个数void main(void){ int *point1, *point2, a,b; cin>>a>>b; point1=&a; point2=&b; if (a
两个整数,按大小输出这两个数void main(void){ int *point1, *point2, a,b; cin>>a>>b; point1=&a; point2=&b; if (a
了的值函数调用函数调用不能改变实参指针变量的值,但不能改变实参指针变量的值,但可可以改变实参指针变量所指向变量的值以改变实参指针变量所指向变量的值436void grt(int *x , int *y , int *z){ cout<< ++*x<<‘,’<< ++*y<<‘,’<<*(z++)< 址,一样可以用指针来表示C++规定:规定:数组数组名就是数组的起始地址名就是数组的起始地址;又规定:;又规定:数组的指数组的指针就是数组的起始地址针就是数组的起始地址数组元素的指针就数组元素的指针就是数组元素的地址是数组元素的地址442一、指向数组元素的指针变量的定义与赋值一、指向数组元素的指针变量的定义与赋值int a[10], *p;p=&a[0]; p=a;p是变量,是变量,a为常量2024H2020H201CH2018H2014H2010H200CH2008H2004H2000Ha[9]a[8]a[7]a[6]a[5]a[4]a[3]a[2]a[1]a[0]ap&a[0]若数组元素为若数组元素为int型,则指向其的指针变型,则指向其的指针变量也应定义为量也应定义为int型int a[10];int *p=a; int *p=&a[0];数组第一个元素的地址数组第一个元素的地址直接用数组名赋值直接用数组名赋值这两种情况均为赋初值这两种情况均为赋初值443二、通过指针引用数组元素二、通过指针引用数组元素int a[10];int *p=a; 2024H2020H201CH2018H2014H2010H200CH2008H2004H2000Ha[9]a[8]a[7]a[6]a[5]a[4]a[3]a[2]a[1]a[0]ap&a[0]*p=1; a[0]=1; 1C++C++规定,规定,p+1p+1指向数组的指向数组的下一下一个元素个元素,,而不是下一个字节。 而不是下一个字节p+1)=2;a[1]=2;2*++p=2;p=p+1; *p=2; p=2004H为指针变量赋初值为指针变量赋初值通过指针变量为通过指针变量为数组元素赋值数组元素赋值指针变量也重新赋值指针变量也重新赋值444*(a+1)=2;*(a+1)与与a[1]等同a=2;a为常量,不可赋值为常量,不可赋值p+i 或或 a+i 均表示均表示 a[i] 的地址的地址 &a[i]2024H2020H201CH2018H2014H2010H200CH2008H2004H2000Ha[9]a[8]a[7]a[6]a[5]a[4]a[3]a[2]a[1]a[0]ap&a[0]12*(p+1)=2;a[1]=2;*++p=2;错误错误*(a+i)a[i]*(p+i)p[i]p=p+1; *p=2; p=2004H445用用指向数组的指针变量指向数组的指针变量输出数组的全部元素输出数组的全部元素void main(void){ int a[10], i; int *p; for (i=0; i<10; i++) cin>>a[i]; for (p=a; p>a[i]; for (i=0; i<10; i++) cout<<*p++<<‘\t’;}输入数组元素输入数组元素指针变量赋初值指针变量赋初值指向下一元素指向下一元素输出指针指向的数据输出指针指向的数据*p, p=p+1输出数据后指针加输出数据后指针加1446void main(void){ int x[ ]={1,2,3}; int s, i, *p; s=1; p=x; for (i=0; i<3; i++) s*=*(p+i); cout< 这样,这样,实参、形参共同指向同一段内存单元实参、形参共同指向同一段内存单元,,内存单元中的数据发生变化,这种变化会反应到主内存单元中的数据发生变化,这种变化会反应到主调函数内调函数内在函数调用时,在函数调用时,形参数组并没有另外开辟新的存储形参数组并没有另外开辟新的存储单元单元,而是以实参数组的首地址作为形参数组的首,而是以实参数组的首地址作为形参数组的首地址这样形参数组的元素值发生了变化也就使实这样形参数组的元素值发生了变化也就使实参数组的元素值发生了变化参数组的元素值发生了变化449void main(void){ int array[10]; ...... f(array, 10); .....}f(int arr[ ], int n) { ......}实参数组实参数组形参数组形参数组,必须进行类型说明必须进行类型说明用数组名作形参,因为接收的是地址,用数组名作形参,因为接收的是地址,所以可以不指定具体的元素个数所以可以不指定具体的元素个数1、形参实参都用数组名、形参实参都用数组名4502028H2024H2020H201CH2014H2010H200CH2008H2004H2000Harray[9]array[8]array[7]array[6]array[5]array[4]array[3]array[2]array[1]array[0]array,arrarr[0]指向同一指向同一存储区间存储区间4512、实参用数组名,形参用指针变量、实参用数组名,形参用指针变量void main(void){ int a [10]; ...... f(a, 10); .....}f(int *x, int n ){ ......}实参数组实参数组形参指针形参指针4523、形参实参都用指针变量、形参实参都用指针变量void main(void){ int a [10],,*p; p=a; ...... f(p, 10); .....}f(int *x, int n ) { ......}实参指针实参指针形参指针形参指针实参指针变量调用前必须赋值实参指针变量调用前必须赋值4534、实参为指针变量,形参为数组名、实参为指针变量,形参为数组名void main(void){ int a [10],,*p; p=a; ...... f(p, 10); .....}f(int x[ ], int n ) { ......}实参指针实参指针形参数组形参数组454将数组中的将数组中的n个数按相反顺序存放。 个数按相反顺序存放void inv(int x[ ], int n){ int t, i, j, m=(n-1)/2; for (i=0;i<=m; i++) { j=n-1-i; t=x[i]; x[i]=x[j]; x[j]=t; }} void main(void){ int i, a[10]={3,7,9,11,0,6,7,5,4,2}; inv(a,10); for (i=0;i<10; i++) cout<
写对换,把最大的数与最后一个数对换写3 3个个函数:函数:①①输入输入1010个数;个数;②②进行处理;进行处理;③③输出输出1010个数457编写函数编写函数 int fun(int x, int *pp),其功能是,求出其功能是,求出能整除能整除x且不是偶数的各整数,并按照从小到大的且不是偶数的各整数,并按照从小到大的顺序放在顺序放在pp指向的内存中,函数返回值为这些整指向的内存中,函数返回值为这些整数的个数数的个数若若x的值为的值为30,, 数组中的数为数组中的数为1,,3,,5,,15,函数返回,函数返回4458int fun(int x, int *pp){ int k=0; for(int i=1;i 是小写字符则不必转换)460void change(char *pchar){ while(*pchar) { if(*pchar>='a'&&*pchar<='z') *pchar=*pchar-32; pchar++; if(*pchar==0)break; pchar++; }}void main(void){ char str[100]; cin.getline(str,100); change(str); cout< 地址这样形参数组的元素值发生了变化也就使实这样形参数组的元素值发生了变化也就使实参数组的元素值发生了变化参数组的元素值发生了变化462既然数组做形参没有开辟新的内存单元,接受的只既然数组做形参没有开辟新的内存单元,接受的只是实参数组的首地址,那么,这个首地址也可以在是实参数组的首地址,那么,这个首地址也可以在被调函数中用一个被调函数中用一个指针变量指针变量来接受,通过在被调函来接受,通过在被调函数中对这个数中对这个指针变量的指针变量的指向指向进行操作而使实参数组进行操作而使实参数组发生变化发生变化ap实参实参,在主调函在主调函数开辟的空间数开辟的空间形参形参,用指针变用指针变量来接受地址量来接受地址实际上在被调函数中只开辟了实际上在被调函数中只开辟了p的空间,里面放的是的空间,里面放的是a的值463四、指向多维数组的指针和指针变量四、指向多维数组的指针和指针变量用指针变量也可以指向多维数组,表示的同样是多维数组用指针变量也可以指向多维数组,表示的同样是多维数组的首地址的首地址int a[3][4]; //首地址为首地址为2000H a[2][3]a[2][2]a[2][1]a[2][0]a[1][3]a[1][2]a[1][1]a[1][0]a[0][3]a[0][2]a[0][1]a[0][0]200CH2008H2004H2000Haa[2]a[1]a[0]2000H2010H2020H可以将可以将a数组看作一个一维数组,这个一维数组的数组看作一个一维数组,这个一维数组的每个元素每个元素又是一个具有又是一个具有4个个int型数据的一维数组型数据的一维数组,这样,,这样,我们就可我们就可以利用一维数组的概念来以利用一维数组的概念来标记标记一些写法。 一些写法a[0][0]a[0][1]a[0][2]a[0][3]a[1][0]a[1][1] a[1][2]a[1][3]a[2][0]a[2][1]a[2][2]a[2][3]2000H2008H2010H 2014H201cH 2020H2028H 202cH464a[0]=*(a+0)a+0为为a[0]的地址的地址&a[0],其值为,其值为2000Ha[1]=*(a+1)a+1为为a[1]的地址的地址&a[1],其值为,其值为2010Ha[2]=*(a+2)a+2为为a[2]的地址的地址&a[2],其值为,其值为2020Ha[2][3]a[2][2]a[2][1]a[2][0]a[1][3]a[1][2]a[1][1]a[1][0]a[0][3]a[0][2]a[0][1]a[0][0]200CH2008H2004H2000Haa[2]a[1]a[0]2000H2010H2020H a[0]为一维数组名为一维数组名,其数组有四个,其数组有四个int型的元素:型的元素: a[0][0],,a[0][1],,a[0][2],,a[0][3]同样,同样,a[0]代表一维数组的首地址,所以,代表一维数组的首地址,所以,a[0]为为&a[0][0]。 465a[2][3]a[2][2]a[2][1]a[2][0]a[1][3]a[1][2]a[1][1]a[1][0]a[0][3]a[0][2]a[0][1]a[0][0]200CH2008H2004H2000H2020H2010H2000Haa[2]a[1]a[0]a[0]代表一维数组的首地址代表一维数组的首地址,也就是也就是一维数组名一维数组名,a[0]为为&a[0][0]a[0]为为&a[0][0]a[0][0]=*(a[0]+0)b[0] = *(b+0)a[0]+1为为&a[0][1]a[0][1]=*(a[0]+1)b[1] = *(b+1)a[0]+2为为&a[0][2]a[0][2]=*(a[0]+2)b[2] = *(b+2)a[0]+3为为&a[0][3]a[0][3]=*(a[0]+3)b[3] = *(b+3)a[1]+2为为&a[1][2]a[1][2]=*(a[1]+2)行行列列把把a[0]看成看成一维数组一维数组ba[i][j]=*(a[i]+j)466a为二维数组名为二维数组名,,a+1为为a[1]的的地址地址,也就是数组第,也就是数组第一行的地址,所以一行的地址,所以a为为行指针行指针。 a[1]为一维数组名为一维数组名,,a[1]+1为为a[1][1]的的地址地址,也就是,也就是数组第一行第一列的地址,所以数组第一行第一列的地址,所以a[1]为为列指针列指针a[2][3]a[2][2]a[2][1]a[2][0]a[1][3]a[1][2]a[1][1]a[1][0]a[0][3]a[0][2]a[0][1]a[0][0]200CH2008H2004H2000H2020H2010H2000Haa[2]a[1]a[0]a[1]+2为为&a[1][2]a[1][2]=*(a[1]+2)行行列列a[i][j]=*(a[i]+j)467可以看到:可以看到:a, a+0 , *(a+0), a[0], &a[0][0]表示的都表示的都是是2000H,即二维数组的首地址即二维数组的首地址 实际上,实际上,a[0], a[1], a[2]并不是并不是实际的元素实际的元素,它们在,它们在内存内存并不占具体的存储单元并不占具体的存储单元,只是为了我们表示方,只是为了我们表示方便起见而设计出的一种表示方式便起见而设计出的一种表示方式a为行指针,加为行指针,加1移动一行移动一行a或或a[0]为列指针,加为列指针,加1移动一列。 移动一列a[2][3]a[2][2]a[2][1]a[2][0]a[1][3]a[1][2]a[1][1]a[1][0]a[0][3]a[0][2]a[0][1]a[0][0]200CH2008H2004H2000H2020H2010H2000Haa[2]a[1]a[0]468a[1]=*(a+1)*(a+1)+2=&a[1][2]*(*(a+1)+2)=a[1][2]**(a+1)=*(a[1])=*(*(a+1)+0)=a[1][0](*(a+1))[1]=*(*(a+1)+1)=a[1][1]*(a+1)[1]=*((a+1)[1])=*(*((a+1)+1))=**(a+2)=a[2][0]注意二维数组的各种表示法,注意二维数组的各种表示法,a为常量a[2][3]a[2][2]a[2][1]a[2][0]a[1][3]a[1][2]a[1][1]a[1][0]a[0][3]a[0][2]a[0][1]a[0][0]200CH2008H2004H2000H2020H2010H2000Haa[2]a[1]a[0]469int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};设数组的首地址为设数组的首地址为1900H,则:,则: a为为_____________ *a为为______________ a+2为为_____________ *a+2为为______________*(a+1)+2为为_____________ **a为为_______________ *(*a+9)为为_____________ (a+1)[1]为为_____________ 1908H1900H1920H1900H1918H1191920Ha[2][3]a[2][2]a[2][1]a[2][0]a[1][3]a[1][2]a[1][1]a[1][0]a[0][3]a[0][2]a[0][1]a[0][0]190CH1908H1904H1900H1920H1910H1900Haa[2]a[1]a[0]470void main(void){ static int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23}; int *p; for(p=a[0]; p
是个常数为第二维的维数是个常数p+2p+4472fun(int *q1, int *q2, int *q3){ *q3=*q2+*q1; }void main ( void){ int i , j, a[3][3]={1,1},*p1,*p2,*p3;p1=a[0], p2=a[0]+1,p3=a[0]+2;for(i=2;i<9;i++) fun(p1++, p2++, p3++);for(i=0;i<3; i++) for(j=0;j<3;j++) { cout<
这样,这样,a与与p等同等同a[2][3] *(*(a+2)+3) p[2][3] *(*(p+2)+3) ap==a两种表示两种表示完全等价完全等价a为常量为常量p为变量为变量475若有以下的定义和语句,则下面各个符号的若有以下的定义和语句,则下面各个符号的正确含义是:正确含义是:int a[3][4] , (*p)[4];p=a;1.p+12.*(p+2) 3.*(p+1)+24.*(*p+2) a[2][3]a[2][2]a[2][1]a[2][0]a[1][3]a[1][2]a[1][1]a[1][0]a[0][3]a[0][2]a[0][1]a[0][0]200CH2008H2004H2000Hpp+1p+2aa数组第一行元素的首地址数组第一行元素的首地址为行指针为行指针a数组第二行元素的首地址数组第二行元素的首地址为列指针为列指针&a[2][0]&a[1][2]为列指针为列指针数据元素数据元素*(*(p+0)+2)=a[0][2]476若若有有以以下下的的定定义义和和语语句句,,则则对对a数数组组元元素素的的非非法引用是:法引用是:int a[2][3], (*pt)[3];pt=a;1)pt[0][0] 2) *(pt+1)[2]2)3) *(pt[1]+2) 3) *(a[0]+2)*(pt+1)[2] 右右结结合合性性==*((pt+1)[2])==*(*(pt+1+2))==*(*(pt+3))=pt[3][0]477多维数组的指针作函数参数多维数组的指针作函数参数主要注意的是函数的主要注意的是函数的实参实参究竟是行指针还是究竟是行指针还是列指针,从而决定函数列指针,从而决定函数形参形参的类型。 的类型要求要求实实参、形参一一对应,类型一致参、形参一一对应,类型一致举例)478求二维数组求二维数组a[3][4]的平均值的平均值void main(void){ float score[3][4] = { {65,67,70 ,60}, {80,87,90,81}, {90,99,100,98} }; float sum=0; for(int i=0;i<3;i++) for(int j=0;j<4;j++) sum=sum+score[i][j]; cout<<“aver=“< 为数组名,代表数组的首地址,是常量数组首地址数组首地址481char string[20];string=“I love China”;strcpy(string, “I love China”);cin.getline(string); //从键盘输入从键盘输入\0anihCevolI string错误!常量不错误!常量不能赋值能赋值正确赋值形式正确赋值形式4822、用字符、用字符指针指针表示字符串表示字符串void main(void){ char *string=“I love China”; cout< void main(void){ char a[ ]=“I am a boy”, b[20]; int i; for(i=0; *(a+i)!=‘\0’; i++) *(b+i)=*(a+i); *(b+i)=‘\0’; cout<
0) changed(s1,s2); if(strcmp(s1,s3)>0) changed(s1,s3); if(strcmp(s2,s3)>0)changed(s2,s3); cout<<"sorted:"<