C++程序设计中文版_第1页
C++程序设计中文版_第2页
C++程序设计中文版_第3页
C++程序设计中文版_第4页
C++程序设计中文版_第5页
已阅读5页,还剩560页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第一章绪论

C++程序设计课程介绍课程介绍C++语法基础面向对象程序设计的概念大量的编程实践目标熟练掌握C++语法具有面向对象程序设计的概念与能力能熟练阅读复杂的C++程序源代码能独立的设计与完成面向对象的C++程序1.1Whatisacomputerprogram?(什么是计算机程序?)计算机程序

:计算机完成所有这些工作都是通过执行预定义的指令集来实现的。计算机计算机程序厨师食谱程序设计语言高级语言自然语言机器语言低级语言编译器1.2Developingacomputerprogram(开发计算机程序)开发计算机程序:定义和理解要解决的问题----分析阶段如何去做?-----设计阶段C++程序的编写、编译和测试1.2.1程序发展周期第一步1:设计程序。每个程序必须单独设计,以实现在分析阶段和设计阶段提出的整体解决方案。编写程序之前,检查程序的逻辑。1.2Developingacomputerprogram第二步2:编写程序。使用文本编辑器把

C++程序指令输入到一个文件

源代码

程序代码

源文件

第三步3:编译程序。编译器把C++程序指令转换成机器指令--目标代码,把目标代码存入目标文件中。错误----编译时的错误语法错误:包括遗漏标点和拼写错误…警告信息不象语法错误那样严重,不会妨碍程序的编译可能是一个问题,并应该检查一下程序1.2Developingacomputerprogram第四步

4:链接程序。把程序的目标文件和C++运行时库文件结合起来形成一个可执行文件第五步

5:测试程序。程序在运行时有可能没有像预期的那样执行。一个程序没有编译时候错误并不能保证这个程序就能按要求运行运行时错误——导致程序在完成它的任务之前中止逻辑错误(缺陷)——任务执行完毕,结果却是错误的1.2Developingacomputerprogram第六步6:调试程序。定位和修正程序错误的过程,称为

调试很多编译器都提供了可用于帮助定位缺陷的工具改正一个缺陷后要返回第二步,应该尽可能早地发现错误1.2Developingacomputerprogram程序发展周期设计编写调试编译链接提出整体解决方案测试编写C++指令

源文件编译器把C++程序指令转换成机器指令

目标文件链接器将程序目标文件和C++运行时库文件结合

可执行文件定位和修正程序错误确认程序错误(bug)修正1.3LearningC++(学习C++)一个成功的方法学习C++程序依靠于大量的

练习。每章都设置了一些练习题选择练习的解决方法在本书的网站上.1.4BriefhistoryofC++(C++简史)1972年,C语言诞生于美国新泽西州的贝尔实验室1980年,BjarneStroustrup在贝尔实验室开发了一种语言,被称为

“CwithClasses”

(有类的C)1983年,BjarneStrostrup在AT&T贝尔实验室开发了C++1985年,第一个商业版本的C++上市1997年,C++逐渐发展为最新的ANSI(AmericanNationalStandardsInstitute)标准

1.6ANSI/ISOC++standard(ANSI/ISOC++标准)在本书中使用的示例程序符合ANSI/ISOC++标准.不是所有的编译器符合这个标准,所以一些编译器可能不正确地编译示例程序。很多的示例程序可能要使用其他的编译器来修改。在网站上看到细节。第二章

C++编程入门2.1Constants(常量)C++数据:常量,变量常量:常量的值在程序中不能改变。2.2Variables(变量)变量:变量的值在程序中可以改变。在使用变量前,必须先对变量进行定义。所谓定义变量也就是指定变量的类型和名称。main()指定了C++程序执行的起点,它在程序中只能出现一次。程序语句用一对花括号“{}”括起来每条语句都以分号(;)结尾定义变量的名称和类型对变量进行赋值2.2Variables变量名是C++的一种标识符,可以给变量起任何名字,只要遵守如下的标识符命名规则即可:标识符只能由字母、数字和下划线(_)组成。标识符必须以字母或下划线开头。标识符不能是C++关键字。关键字是指在程序中具有特殊意义的单词(见附录A中C++关键字的列表)。标识符可以包含任意多个字符,但是C++编译器只识别前31个字符。变量就像计算机内存中的一个盒子。2.3Simpleoutputtothescreen

(简单的屏幕输出)cout#include<iostream.h>指令将文件提供给程序。<iostream.h>中包含一些帮助程序轻松实现数据输入/输出的C++语句。cout:

将数据发送到cout流插入运算符<<用于向标准输出流对象cout输出字符串。endl(行结束):

用于实现屏幕上换行的功能。

一串字符:字母和数字包含在

“”中变量名无需用括号括起来2.4Comments(注释)在C++程序中增加注释可使程序更容易阅读编译器完全忽略注释注释以

//开头,到本行末尾结束。2.4Comments(注释)C++注释不能跨越多行。通常,在程序开头加注释,用于描述程序的功能、编程者、编程日期及其他相关信息。C风格的注释,即以/*开头,到*/结束应该养成书写注释的习惯不好的注释会把人弄糊涂2.5Datatypes(数据类型)不同的数据类型占用不同大小的内存,因此,它们所能表示的数据的范围也各不相同。shortinteger:短整型LongIntegerdatatypes:长整型Booleandatatypes:布尔数据类型canstoreonlyoneoftwovalues:true(1)orfalse(0)DoubleFloating-pointdatatypes(双浮点数据类型):增加浮点型数据表示数的范围及精度。2.6Datatypesizes

(数据类型的大小)使用sizeof运算符来显示一些常见的数据类型在内存中占用的字节数

运行结果2.7Operators(运算符)2.7.1Theassignmentoperator(赋值运算符)“=”

变量赋值2.7.2Arithmeticoperators(代数运算符)2.7OperatorsProgramExampleP2E运行结果2.7Operators2.7.3Increment

anddecrementoperators(自增和自减运算符)++:可使变量的值增1

--:可使变量的值减1自增运算符(++)有两种形式:前缀形式和后缀形式。2.7OperatorsProgramExampleP2F程序第9行将变量var1和var2定义为整型,并将其分别初始化为1和2。

程序第15行将变量var1的值加1第16行将变量var2的值减1。

第19和20行显示变量var1和var2的最终的值。2.7OperatorsProgramExampleP2G运行结果前缀----如果++放在变量之前,那么变量的值在使用前先增1。后缀----如果++放在变量之后,那么变量先被使用,然后再将其值增1。自减运算符也有前缀和后缀两种形式。2.7Operators2.7.4Combinedassignmentoperators(复合赋值运算符)运算符+=是将左侧变量的值加上右侧的数值后,再重新赋值给左侧的变量。C语言中有5种复合的赋值运算符:+=,-=,*=,/=,%=,分别对应+、-、*、/、%这5种算术运算。2.8Operatorprecedence(运算符的优先级)思考以下句子:2+7*8=72var2+7*8=58var运算符的优先级×√1)*,/

的优先级高于+、-2)当表达式中所含运算符的优先级相同时,应根据运算符的结合性进行计算3)使用()改变运算的先后顺序2.8Operatorprecedence使用括号可以避免在优先计算哪个操作上的混淆。一元减运算符:“-”

出现在一个操作数前面最高优先级二元减运算符:放在两个操作数中2.9Typeconversionsandcasts(类型转换和强转)自动转换-----程序示例P2H运行结果2.9Typeconversionsandcasts在进行混合类型运算时,C++排名的数据类型按下面的顺序:数据类型的“提升”或“扩展”在进行混合类型运算时,C++自动将数据值从类型级别较低的一方向类型级别较高的一方转换。因为相对于级别较低的数据类型,级别较高的数据类型要占用更大的内存空间,因此,类型提升后不会导致数据信息的丢失,从而能够保存更精确的数据。2.9Typeconversionsandcasts数据类型的“降级”和“收缩”数据赋值给较低类型的变量。由于级别较低的数据类型没有足够的存储空间用来存储级别较高的数据,所以,类型的降级会导致数据信息的丢失。2.9TypeconversionsandcastsManualconversionwithastaticcast(强制类型转换运算符进行手工的类型转换)使用强制类型转换运算符相当于将一个表达式赋值给特定类型的变量,然后用该变量替代该表达式。表达式var1/4.0为混合类型的表达式,因此变量var1的类型将自动提升为float类型。

Programmingpitfalls(易犯的错误)1.不要在下面语句的行末添加分号。2.C++中的每条语句都应以分号结束。3.分号并非总是在行末出现。这会导致一个编译错误,因为分号是语句的一部分。Programmingpitfalls4.一个键入错误可能导致一个语句什么都没有做,但它却是有效的。Programmingpitfalls5.在算术表达式中使用变量前,必须将其初始化。6.一定要了解运算符的优先级。如果不能确定运算符的优先级,那么应该使用圆括号。左圆括号和右圆括号的个数一定要相等。7.每个变量都有一个关联的数据类型(int、float等)一定不要让变量的值超出变量所能表示的范围。Programmingpitfalls8.在C++算术运算中,期望的结果不一定总能得到。变量将包含12个,而不是12.5Useastaticcastifthefractionalpartoftheresultisrequired.Programmingpitfalls9.避免不必要的、无意义的程序注释。Quicksyntaxreference(快速语法参考)QuicksyntaxreferenceQ&AThankYou!ThankYou!第三章

键盘输入和屏幕输出

3.1SimpleKeyboardInput

(简单的键盘输入)DataStream(数据流)数据流对象用于在各种不同的设备(如键盘和屏幕)上执行基本的数据输入和输出操作。所谓流,就是与输入输出设备相关联的数据通信对象。cout:标准输出流cout与屏幕相关联<<:流插入运算符<<用于将数据输出到coutcin:标准输入流cin与键盘相关联

>>:流提取运算符>>用于从键盘读取数据3.1SimpleKeyboardInput示例:从键盘读入一个数,并将其保存到变量num中。3.2Manipulators(流操纵符)流操纵符用于对输入和输出数据流进行修改。endl,setw,setfill,fixed,setprecisionendl:将光标移动到一个新行的起始位置setw:设置数据域的宽度(数据项在屏幕上所占的列数)setfill:把占位符从空格改变为其他字符cout<<endl<<endl<<"endlcanbeusedanywhere"<<endl3.2Manipulators(流操纵符)如果域宽设置得太小不足以显示一个数值,那么系统会自动调整域宽使其能够显示数据的所有位的数字。示例:如何使用流操纵符#include<iomanip>使用像setw这样的在圆括号中有一个参数的流操纵符时,第4行是必需的。3.2Manipulators(流操纵符)示例:如何使用setfill和setwsetfill把占位符从空格改变为其他字符setw对输出流中的下一个数据项起作用setfill对送入输出流中的所有后继数据项都起作用3.2Manipulators(流操纵符)

setprecision:用于指定要显示的数据的位数。数据显示的最大位数(包括小数点之前和小数点之后)是6。Inline12setprecisionsetthetotaldigitstoreservebeforeandafterthedecimalpoint.Inline13withfixedprecedingsetprecisionsetthedigitstoreserveafterthedecimalpoint流操纵符fixed和setprecision将一直对输出流中的后继数据项起作用。3.3

Single-characterinputandoutput

(单个字符的输入和输出)字符的输入和输出WhitespaceCharacters(空白字符):在屏幕上产生的显示结果是不可见的空白或空格,诸如Tab、Enter和空格键。输入noskipws:不管从键盘读入什么另一种方法是将函数get()与输入流对象cin联合使用。输出coutandits<<;利用输出流对象cout的成员函数put()来显示一个字符。3.3

Single-characterinputandoutput示例:如何完成单个字符的输入和输出函数是执行特定功能的程序模块。它将在以后的章节进行讨论。从键盘读取单个字符(包括空格)Programmingpitfalls(易犯的错误)1.不要混淆流插入运算符(<<)和流提取运算符(>>)。流插入运算符用于向输出流中插入数据,而流提取运算符用于从输入流中读取数据。2.某些流操纵符只作用于下一个数据域(例如setw);而另外一些流操纵符(例如setprecision)对所有的后继数据域都起用。3.在使用圆括号中有一个参数的流操纵符时,例如setw(4),下面的代码行是必需的。对于其他流操纵符(例如endl),则不需要加入这一行。Quicksyntaxreference(快速语法参考)Q&AThankYou!ThankYou!第四章

选择与循环

4.1Selection(选择)顺序结构自顶向下:顺序执行语句只能解决最简单的问题选择和循环结构语句

1语句

i…语句

n顺序结构语句

i+1…选择结构循环结构4.1Selection(选择)

Theif

statement(if

语句)以关键字if作为开始,后跟一个用圆括号括起来的表达式。关系运算符如果表达式为真,那么执行if后面的语句。如果表达式为假,那么不执行if后面的语句。4.1Selection(选择)Theif

statement(if语句)4.1Selection(选择)4.1.2Theif-elsestatement(if-else语句)使用if-else语句,需要做出的选择是:在两条语句中选择其中的一条来执行。if(expression)statement1elsestatement

2truefalsestatement…4.1Selection(选择)ProgramExampleP4B如果变量account_balance

的值小于0,则执行第14行的语句;否则执行第16行的语句。4.1.3复合语句:用一对花括号括起来的一条或多条语句,称为复合语句。4.1Selection(选择)为了使程序层次清晰,通常将复合语句中的语句向右缩进。4.1Selection(选择)4.1.4Logicaloperators(逻辑运算符)逻辑运算符&&和||

用于在if语句中实现组合测试。&&用于将两个简单的条件组合,得到的复合条件是,当且仅当两个简单条件均为真时才为真。而||将两个简单的条件组合得到的复合条件是,只要两者之一或两者均为真时就为真。逻辑非运算符

!用于将一个结果取反。如果结果为真,那么就将其变为假;如果结果为假,那么就将其变为真。4.1Selection(选择)逻辑运算符4.1Selection(选择)4.1.5Nestedifstatements(嵌套if语句)一个if语句出现在另一个if语句中间switch

语句等价于一个if-else语句序列关键字:

switchcase4.1Selection(选择)“op”必须是char类型

或int类型.1“op”的值依次与每个case后的值相比较2如果发现与某个case后的值相匹配,就执行其后的语句。3break语句终止switch语句。switch语句4.1Selection(选择)如果找不到与“op”相匹配的情况,就执行default后面的语句。4.1Selection(选择)Theconditionaloperator?:(条件操作符)if-else的简写格式。找到num1和num2的最大值。4.2Iteration(循环)3iterativecontrolstatements(循环控制语句)while语句do-while语句for语句

while

语句while(expression){statement1;…statementn;}otherstatements;

如果表达式的值为真otherwise4.2Iteration(循环)ProgramExampleP4F当控制表达式n!=0为真时,花括号内({和}以内)的语句将被重复执行。重复执行一条或者多条语句,称为程序循环。while循环的执行过程如下:1.计算控制表达式的值。2.如果控制表达式的值为真,那么就执行循环体中的语句,然后返回步骤1。3.如果控制表达式的值为假,就退出循环,执行循环体后面的语句。4.2Iteration(循环)do-while

循环do-while循环的执行过程如下:1.执行循环体中的语句。2.计算控制表达式的值。3.如果控制表达式的值为真,那么返回步骤1。4.如果控制表达式的值为假,则退出循环,执行循环体后面的语句。do{statement1;…statementn;}otherstatements;如果表达式的值为真否则while(expression)4.2Iteration(循环)ProgramExampleP4G4.2Iteration(循环)for

语句初始化表达式;在循环开始之前执行一次继续条件;循环继续条件表达式为真;循环继续条件表达式变为假;增值表达式每次循环体执行完以后,都要执行一次增值表达式。for(“initial”;”continue”;”increment”){statement1;…statementn;}otherstatements;如果“continue”的值为真否则4.2Iteration(循环)ProgramExampleP4H{}内的语句将被执行5次。使用{}有助于清晰地表示循环体。程序示例P4H中的变量变量

i可以在for语句之前定义i最初为10,每一轮过后减1多个表达式在for语句中用逗号隔开。4.2Iteration(循环)4.2Iteration(循环)for语句中的任何一个或者所有这三个表达式都可以省略

;不能省略for(;;)没有可以使循环结束的条件,所以它将使循环成为一个无限循环(即死循环)。4.2Iteration(循环)嵌套的循环:一个循环包含在另一个循环中ProgramExampleP4I第14行到第17行的循环显示数字1到12。第21行到第24行的循环在这些数字的下面显示连字符“-”。当内层循环执行完毕以后,又转向外层循环控制,i的值增加到2。接下来,执行内层循环(第29行到第32行),内层循环从j等于1开始,到j大于12结束。每执行一次内层循环,就显示乘法表中的一个数。外层循环(第26行到第33行)从i等于1开始第28行在屏幕的左端显示一个1和一个竖线|4.2Iteration(循环)嵌套的循环:一个循环包含在另一个循环中ProgramExampleP4IProgrammingpitfalls(易犯的错误)1.紧随if语句之后不应有分号。2.紧随switch语句之后不应有分号。3.测试是否相等时,应使用==,而不要使用=。4.每个else都是与其前面最邻近的那个if语句配对。5.对于每个左花括号{,必定有个与其配对的右花括号}。Theifonlycontrolstheemptystatementmistakenlymadebythemisplacedsemicolon.Programmingpitfalls6.为了在if语句中控制一个语句序列的执行,必须使用花括号。7.在计算含有逻辑运算符(&&和||)的表达式时,尽量使其能够根据最少的操作数就可以确定整个表达式的值,这意味着表达式中的某些操作数的值就无需再进行计算了。如果a和b相等,语句a=1成立。然而,语句b=2总是成立,无论a和b的值是多少。Programmingpitfalls8.紧随while或for语句之后不应有分号。9.在for循环中,要小心指定循环终止条件。asemicolonimmediatelyafterawhileorforstatementmakesthebodyoftheloopemptyThisloopdoesnothing,becausei==10isfalseatthestartoftheloop(iisinfact0)andtheloopterminatesimmediately.Programmingpitfalls10.紧随while循环的while之后不应有分号,但是紧随do-while循环的while之后有分号。11.浮点数所表示的精度是有限的。在if语句或者for语句中测试浮点数是否相等时,了解这一点是非常重要的。在大多数计算机上,这将导致一个无限循环。这样做的原因是,f可能永远不会等于1.1。Quicksyntaxreference(快速语法参考)QuicksyntaxreferenceQ&AThankYou!ThankYou!第五章

数组与结构体

5.1Arrays(数组)Array(数组):数组由一组相同类型的变量组成。定义存储数组的维数:数组中的元素个数数组索引

(或下标):元素在数组中的位置

数组的索引初始值为05.1Arrays(数组)数组如何引用数组中的某个特定的元素?用数组名和写在方括号中的下标值。如何获取最后的元素?or?52×√5.1Arrays(数组)ProgramExampleP5A

定义年龄为10个整数的数组

格式:for循环用于读取数组中的每个元素的值,并将其累加到变量total_age中。5.1Arrays(数组)ProgramExampleP5B:在编程中查找数组中的最小值和最大值定义一个整型常量SIZE和一个有SIZE个数的数组“ages”。symbolicconstant(符号常量)关键字const用于定义SIZE,指定它的值不能被修改。

标识符通常要大写。使用符号常量使得程序更易于修改。5.1Arrays(数组)ProgramExampleP5B:在编程中查找数组中的最小值和最大值Theforlreadsinvaluesintothearrayagesandtotalsthemoopfor循环将数组中的每个元素与变量youngest和oldest的值进行比较。当发现某个元素值大于oldest时,就将该元素值赋值给oldest。当发现某个元素值小于youngest时,就将该元素值赋值给youngest。循环完成时,存储在youngest中的元素就是数组中最小的元素,而存储在oldest中的元素就是数组中值最大的元素。5.1Arrays(数组)Initialisinganarray(数组初始化)ProgramExample

P5C

定义并初始化一组天数。

数组的初始化数值写在{}

内并用,

分隔开。5.1Arrays(数组)数组初始化当初值个数少于数组元素个数时,其余的数组元素将被初始化为0值。如果定义一个数组时对数组元素进行了初始化,但是没有指定数组元素个数,那么编译器将根据花括号内提供的初值个数来确定数组元素的个数。||5.1Arrays(数组)Two-dimensionalarrays(二维数组)一个二维数组可以具有多于一行的元素。5.1Arrays(数组)二维数组定义:指定数组每一维的长度,并且用方括号将它们括起来。访问一个元素:指定该元素的行和列。

行数的范围是0到6。列数的范围是0到4。5.1Arrays(数组)程序示例P5D:读入7天内使用5个实验室的学生人数

符号常量NO_OF_DAYS

和NO_OF_LABS。

定义一个有NO_OF_DAYS行和NO_OF_LABS列的二维数组usage。5.1Arrays(数组)ProgramExampleP5D这个for循环用来累加数组usage的每一列元素并求其平均数。这个for循环用来读入数组usage的数值。5.1Arrays(数组)二维数组的初始化二维数组是通过放置在花括号内的初值来对其进行初始化的。将每一行的初值放在单独的行上,或者在每行添加括号来提高可读性。

5.1Arrays(数组)二维数组的初始化省略第一个维度编译器将自动计算出数组的行数0未提供初值的数组元素将被初始化为0值

5.1Arrays(数组)多维数组数组定义为多维数组访问该数组元素需要使用三个下标5.2Structures(结构体)5.2.1绪论

数组适合于存储同种类型的数据集例如,一个学生的考试成绩逻辑相关但数据不同的信息项学生的学号和考试成绩结构体可以表示逻辑相关但数据类型不同的数据项。5.2Structures(结构体)5.2.2

声明一个结构体第一步:声明一个结构体模板:一个结构体模板是由关键字struct及其后的结构体名字组成的。

结构体标记

:结构体的名字

结构体成员:结构体中的信息项5.2Structures(结构体)5.2.2声明一个结构体第二步:用这个模式来定义变量5.2Structures(结构体)5.2.2声明一个结构体通过结构体变量的成员选择运算符“.”来访问。程序示例P5E:输入了一个结构体变量的每一个结构体成员的数值并将它们显示在屏幕上。5.2Structures(结构体)ProgramExampleP5E5.2Structures(结构体)ProgramExampleP5E5.2Structures(结构体)另一个声明的结构体形式5.2Structures(结构体)5.2.3结构体变量的初始化用放置在花括号内的初值对结构体变量的成员进行初始化5.3typedef语句typedef

允许程序员为系统内置的或者程序员自定义的数据类型名定义一个同义词。使用typedef定义一个同义词DATEforstructdate:5.2Structures(结构体)5.2.4嵌套的结构体一个结构体内包含了另一个结构体作为其成员。5.4Arraysofstructures(结构体数组)例如:定了一个有5个元素的数组persons数组的每个元素都是拥有三个成员number、dob和joined的structpersonnel的结构体类型。成员dob和joined本身又是拥有日、月和年三个成员的结构体。哪个成员将会被访问

?persons[0].number?persons[4].joined.year?5.5Enumerateddatatypes(枚举数据类型)枚举数据类型主要用于描述一组整型值上述语句声明了一个名为response的枚举数据类型,它的可能取值为:yes,no,none。answer定义为response枚举类型的变量。枚举数据类型名称的定义response

被称为枚举标记花括号“{”和“}”内的名字都是整型常量no的值为

0,yes

的值为1,none的值为2......5.5Enumerateddatatypes(枚举数据类型)另一种定义形式当枚举类型和枚举变量放在一起定义时,枚举标记是可选的。枚举数据类型的数组Valuesotherthan0,1,and2canalsobeusedProgrammingpitfalls(易犯的错误)应将数组的维数放在方括号之内,而非圆括号之内。数组下标的取值范围是从0开始到数组的元素个数减1。即使结构体的模板是相同的,也不能在if语句中对两个结构体变量进行比较。Programmingpitfalls即使结构体的模板是相同的,也不能在if语句中对两个结构体变量进行比较。若要比较两个结构体变量相等与否,那么必须对两个变量的每个成员都单独进行比较。×√Quicksyntaxreference(快速语法参考)Q&AThankYou!ThankYou!第六章

字符串

6.1C-strings(C风格字符串)C风格字符串:字符数组是元素为字符型的数组,字符串是以空字符'\0'作为数组最后一个元素的字符数组。字符串字双引号引起来的字符序列不必指定数组中字符的个数在字符串字的末尾,编译器会自动地添加'\0'。字符串字“Hello”实际上包含6,而不是5字符。6.1C-strings如果指定了数组的大小,而字符串的长度又小于数组大小,那么这个数组其余的元素都将被初始化为'\0'。为了在一个字符串中包含一个双引号,必须在这个双引号的前面加上一个反斜杠(\)。6.1C-stringsThenewline('\n')escapesequencecanbeusedinplaceofendltoadvancetoanewline.如果一个字符串太长,不能写在一行中,那么可以把它拆分成几个小的片段写在不同的行中。6.2C-stringinputandoutput

(C风格字符串的输入和输出)请记住,字符数组的大小必须比字符串中的字符数多1。程序示例P6A:一个简单的C风格字符串的输入与输出的演示。?流提取运算符>>读字符直到遇到John后的空格符为止(但是空格符没有被读取)。6.2C-stringinputandoutput如果用户键入的字符多于10个,将会发生什么?数组first_name就会溢出,多出的那些字符就会改写内存的其他区域,程序很可能就会出错。getline()函数考虑到这种可能性及为了允许输入空格,可以使用函数getline()。6.2C-stringinputandoutputProgramExampleP6Bgetline()换行符'\n'称为定界符,表示从输入流cin读取字符到数组first_name的结束。'\n'被称为定界符,若定界符被省略,则将其假定为'\n'。自动在其末尾添加'\0'。6.2C-stringinputandoutputProgramExampleP6C第16行好像被跳过去了,并没有读取名字。为什么?当按下回车符时,第一个非数值数据在“12345”之后,所以它被留在输入流中。第17行,键入在student_name被读到。6.2C-stringinputandoutputProgramExampleP6D解决方案:丢弃或者忽略输入流中包括'\n'在内的所有多余的字符。6.3AccessingindividualcharactersofaC-string(访问C风格字符串中的单个字符)程序示例P6E:

在不同行显示字符串"Hello"的每一个字符解决方案:可以通过下标来访问C风格字符串的每个字符6.4C-stringfunctions(C风格字符串函数)C++继承了C风格字符串函数库。如何使用这些函数库?找到c字符串的长度strlen():返回一个C风格字符串中字符的个数,不包含'\0'。6.4C-stringfunctionsCopyingaC-string(复制C风格字符串)strcpy(destination,source)source字符串中的内容被复制到destination字符串中。Remark:source字符串必须以'\0'结束destination字符串有足够的空间来存储要复制的字符串内容。6.4C-stringfunctionsC-stringconcatenationstrcat(str1,str2)把字符串str2拼接到字符串str1的后面。Bothstr1andstr2mustbenull-terminatedstr1要有足够的空间来存储拼接后的字符串。6.4C-stringfunctionsComparingC-strings(比较C风格字符串)strcmp(str1,str2)比较两个以'\0'为结束的字符串str1和str2的大小。函数返回:anegativevalue,ifstr1<str2,0,ifstr1==str2,apositivevalue,ifstr1>str2.6.4C-stringfunctionsstrncat(str1,str2,n)将C风格字符串str2的前n个字符添加到C风格字符串str1的末尾。strncmp(str1,str2,n)与函数strcmp(str1,str2)类似,区别仅在于,strncmp(str1,str2,n)最多比较n个字符。strncpy(str1,str2,n)将字符串str2的前n个字符复制到字符串str1中。6.4C-stringfunctionsProgramExampleP6F6.4C-stringfunctionsConvertingnumericC-stringstonumbers(数值C风格字符串向数值的转换)数字C风格字符串的存储:ASCII

表示"123“整数值的存储:二进制1236.4C-stringfunctionsatoi():C风格字符串到整数atol():

C风格字符串到长整数atof():C风格字符串到双精度浮点Remark:忽略字符间的空格在遇到第一个不能作为一个数值部分的字符时,停止转换。函数atoi()遇到小数点时就会停止转换

函数atof()则能接受小数点,因为它可以作为小数的一部分。6.4C-stringfunctionsFunctionRemarkstrlen(str)FindingthelengthofaC-stringstrstrcpy(str1,str2)copiesthecontentsofaC-stringstr2tostr1strcat(str1,str2)concatenatesaC-stringstr2totheendoftheC-stringstr1strcmp(str1,str2)comparestwonull-terminatedC-stringsstr1andstr2.strncat(str1,str2,n)AppendsthefirstncharactersoftheC-stringstr2tostr1.strncmp(str1,str2,n)Identicaltostrcmp(str1,str2),exceptthatatmost,ncharactersarecompared.strncpy(str1,str2,n)Copiesthefirstncharactersofstr2intostr1.6.5C++strings(C++字符串)C风格字符串常见错误:试图去访问数组范围以外的元素没有使用函数strcpy()来实现字符串之间的复制没有使用函数strcmp()来比较两个字符串…C++字符串数据类型不是C++语言固有的一种数据类型在C++中,string数据类型是由类来定义的6.5C++stringsProgramExample

P6GRemark:在比较C++字符串时,不必像比较C风格字符串那样使用==,<,>,等去代替函数strcmp()。C++字符串有很多有用的函数。6.5C++strings6.5.1字符串初始化和赋值第11行演示了如何用一些相同的字符分配一个C++字符串。可以用两行或多行来为C++字符串赋值。str5被称为空白字符串。6.5C++strings6.5.1字符串初始化和赋值第33行演示了assign()把str1字符串的一部分赋值给str5。str1

是被赋值的源字符串1

是赋值的起始位置3

是赋值的字符个数6.5C++strings6.5.1字符串初始化和赋值6.5C++strings6.5.2stringconcatenation(字符串连接)ProgramExampleP6I6.5C++strings6.5.3字符串长度,字符串索引和子串ProgramExampleP6J改变第一个和最后一个字符

检查索引值,以确保它不是在at()的范围。6.5C++stringsProgramExample

P6Jsubstr()可以提取C++字符串的一部分。第一个参数是起点。第二个参数是提取的字符数。6.5C++strings6.5.4字符串替换,删除,插入和空字符串RemarkReplace3charactersfromstr1startingatthe2ndcharacterpositionwith4charactersfromstr2,startingatthe3rdharacterposition.Characteratposition0isthefirstcharacter.Erasefromthe10thcharacterpositiontotheendofstr1.6.5C++stringsProgramExampleP6KErase2charactersstartingatthe5thcharacterposition.Erasetheentirestring.Judgewhetherstr1isempty?Startingatthe2ndcharacterofstr2,insert6charactersatthe5thcharacterpositionofstr1.6.5C++strings6.5.5字符串检索Holdthepositionofthefirstoccurrenceof"CDE"instr1.If"CDE"isnotinstr1,p=-1.Reversefind-thelastoccurrenceof"CDE"Findthefirstoccurrenceofanyoneofanumberofcharacters.Findthelastoccurrenceofanyoneofanumberofcharacters.Findthefirstoccurrenceofanycharacterthatisnotoneofanumberofcharacters.Findthelastoccurrenceofanycharacterthatisnotoneofanumberofcharacters.6.5C++strings6.5.6字符串比较ProgramExample

P6LC++字符串可以与标准比较符进行比较:==,=,<=,>=<和>Compare()resultis<0ifthefirstdifferingcharacterinstr1islessthanthecharacterinthesamepositioninstr2.如果str1和str2所有的字符是相等的,并且两个字符串长度相同,那么结果是0。否则结果是>0.6.5C++stringsProgramExample

P6L6.6Arraysofstrings(string类型的数组)像其他数据类型一样,也可以定义C风格字符串数组和C++字符串数组。C++字符串数组使用起来更简单一些。6.7Characterclassification(字符分类)有很多C++函数可以用来测试单个字符的值。根据这个字符是否属于一个特定的字符集,这些函数返回值为真(非0整数),或者为假(整数0)。6.7Characterclassification(字符分类)C++还有两个用于转换字符大小写状态的函数:tolower和toupper。6.7Characterclassification(字符分类)6.7Characterclassification(字符分类)Programmingpitfalls(易犯的错误)1.双引号(")用于字符串,单引号(')用于字符。例如,"abcd"和'e'。2.定义C风格字符串时,一定要给'\0'留出空间。例如,要存储包含20个字符的一个C风格字符串,必须定义有21个元素的数组。3.函数strcpy(str1,str2)是把字符串str2复制到str1中,不要弄反了。Programmingpitfalls4.比较两个C风格字符串必须使用函数strcmp()。Forexample,ifstr1andstr2areC-strings,thenthestatementif(str1==str2)//OKforC++strings,butnotforC-strings.isincorrect.Thecorrectstatementisif(strcmp(str1,str2)==0)Programmingpitfalls5.以数组下标方式访问超出C或C++字符串大小范围的字符将导致一个运行时错误。使用C++类成员函数at()可以检测该错误。Forexample,charcs[5]="abcd";//a4characterC-stringstringcpps="abcd";//a4characterC++stringcs[5],cs[6],cs[7]etcareinvalid,asarecpps[5],cpps[6],cpps[7]etc.WithaC++stringthiserrorcanbedetectedusingthestringmemberfunctionat().QuickSyntaxReference(快速语法参考)Q&AThankYou!ThankYou!第七章

函数

7.1Introduction(引言)函数是用函数名来调用执行的具有特定功能的语句块。为了降低编写如此大规模代码的复杂度,必须将其分解为较小、较简单的模块。函数和类是构造C++程序的基本模块。在C++的标准库中有很多固有的、预先定义的库函数。第11行调用sqrt()函数来计算变量中的值n的平方根7.1IntroductionC++允许程序员自己编写函数加入到手头已存在的标准库中。和变量一样,函数在使用之前也必须进行声明。第7行将stars声明为函数。前面的void是对函数stars()类型的声明。第二个void告诉编译器stars函数将不会接收来自于调用程序的任何数据。第二个void是可选择的。-----stars()函数的函数原型。----7.1IntroductionProgramExampleP7B第22~26行是函数定义第22行:函数头部第24~25行:函数体7.2Functionarguments(函数实参)函数star()可以显示11个星号,那么如何显示可变数量的星号?Newfunctionstars():takeavaluepassedtoitanddisplaythenumberofasterisksspecifiedinthatvalue.7.2FunctionargumentsProgramExampleP7CRemark这个数值称为实际参数(简称实参)从第23行声明为整型的形式参数(简称形参)中接收数据。Remark函数的形参仅在函数内部有效在函数stars()的第25行语句中,使用变量num来确定要输出多少个星号。7.2FunctionargumentsAnewprogramspecifies:thenumbercharactertodisplaydisp_chars()有两个形参:num(要显示的字符的个数)ch(要显示的字符)7.2Functionarguments函数原型中使用的变量名通常都与函数首部中定义的形参的名字相同。在函数原型的后面写上一段注释来描述函数及其形参,是一个非常好的习惯。函数原型及其随后的注释称为函数接口。7.3Defaultparametervalues(默认的形参值)没有向其传递实参值的函数形参可以被赋值一个默认的值。第二个参数被省略。这两个是等价的。如果一个函数形参被指定了默认值,那么位于它右侧的所有形参都必须指定默认值。√×7.4Returningavaluefromafunction

(从函数返回一个值)ProgramExampleP7E要定义和调用返回值的函数,你应该注意:函数原型函数头部7.4Returningavaluefromafunction返回语句的一般形式是:例如:这两块是等价的:7.4Returningavaluefromafunction在程序中可以引用变量的任何地方都可以进行函数调用7.5Inlinefunctions(内联函数)内联函数可以减少函数执行时间开销在函数原型前面加上关键字inline,即可把函数变成内联函数当程序使用内联函数时,编译器将每个函数调用都用函数内的语句代替。在一般情况下,当函数内仅有1~3行代码时应考虑函数内联。7.6Passingargumentsbyvalue

(按值传递实参)按值传递实参将实参值的一个副本传递给函数的形参。实参的值在被调函数中是不能修改的。a值的副本被传递至p值p

值的改变对a值不会有任何影响

7.6Passingargumentsbyvalue将形参声明为常量,可以防止形参值在函数内被修改.只要将关键const字放在函数原型和功能头前即可。引用是变量的同义词或者别名。变量的引用是通过在变量数据类型后面加上&来定义的。定义引用变量时,必须对其进行初始化7.7Passingargumentsbyreference

(按引用传递参数)

r引用到

n

n和r指的是同一个值

r不是n的副本,只是n的另一个名字对n的修改也会导致r值的改变7.7PassingargumentsbyreferenceProgramExample

P7Ga

p

指的都是同一个存储单元对p的修改也会导致a值的修改7.7PassingargumentsbyreferenceProgramExampleP7HArgumentspassedbyreference局部变量变量temp是局部变量的函数swap_vals()。局部变量仅在定义它的函数内部才能使用。7.8Passingaone-dimensionalarraytoafunction(向函数传递一维数组)可以使用按引用传参的方法将数组传递给函数为了避免按值传参引起的复制数组所有元素所需的开销程序示例P7I:

containsafunctionsum_array()thatsumstheelementsofanintegerarraypassedtoitfrommain().7.8Passingaone-dimensionalarraytoafunction第16行调用函数sum_array()来计算数组中的值的总和。参数是数组中元素的名称和数目。方括号[和]是必需的,它表示形参是一个数组的引用。对于一维数组,不必在方括号内指出元素的个数,从而使得同一个函数可以用于处理不同大小的数组。

Const通知编译器,在函数sum_array()内部,数组array是只读的,不能被修改。在第20行中数组是引用值。因为数组只能以引用的方式传递,&不是必需的.ProgramExampleP7J7.8Passingaone-dimensionalarraytoafunction除了列出形参和返回值这种函数注释方式以外,还可以使用前置和后置条件的函数注释方式。在前置条件注释中,列出成功调用函数所必需的前提条件。在后置条件注释中,列出调用函数后产生的结果。ProgramExampleP7J…continued7.8Passingaone-dimensionalarraytoafunction7.8Passingaone-dimensionalarraytoafunction7.8Passingaone-dimensionalarraytoafunction7.9Passingamulti-dimensionalarraytoafunction

(向函数传递多维数组)当向函数传递多维数组时,在函数的形参列表中必须声明数组的每一维(除第一维之外)的大小。7.9Passingamulti-dimensionalarraytoafunction7.9Passingamulti-dimensionalarraytoafunction二维数组元素按行存储在一块连续的存储单元中。程序P7J中的数组元素array[i][j]相对于数组起始地址的偏移量为i*2+j。为了计算这个偏移量,必须已知数组的列数(=2),因此编译器要求必须指明数组的第二维的长度。7.10Passingastructurevariabletoafunction(向函数传递结构体变量)向函数传递结构体变量实际传递给函数的是该结构体变量成员值的副本。这就意味着结构体变量的成员值不能在函数中修改。当变量是按引用传递给函数时,结构体变量的成员值才可以在函数中修改。程序示例P7L:

演示了通过值和引用向两个不同的函数传递结构体变量。7.10PassingastructurevariabletoafunctionProgramExampleP7L在main()函数之外定义结构体模板时,结构体模板是全局的global.这样,该结构体模板就在所有的函数,包括main(),display_student_data(),andget_student_data()中都是可用的。7.10PassingastructurevariabletoafunctionProgramExampleP7L…continued当一个结构体变量被按值传递给函数时,整个结构体的成员数据必须复制给函数的形参。对于一个较大的结构体,这种数据复制带来的时间开销是很大的,因此,更好的方法是采用按引用传递方式。如果不希望实参在函数中被修改,就使用const关键字。7.10PassingastructurevariabletoafunctionProgramExampleP7L…continued7.11Passingastringtofunction

(向函数传递字符串)切记使用字符串作为函数实参和使用结构体变量作为函数实参需要考虑的问题是一样的。也就是说,按值传递字符串意味着将字符串中的所有字符都复制给函数形参。为了避免这一时间开销,更好的方式是按引用传递字符串。7.11.1向函数传递C++字符串程序示例P7MdemonstratespassingaC++stringbyconstreferencetoafunctionthatcountsthenumberofvowelsinthestring.7.11Passingastringtofunction7.11Passingastringtofunction7.11.2向函数传递C风格字符串在程序P7M中,使用C风格字符串而不是C++字符串,程序必须做出以下修改:7.12Recursion(递归)Recursion(递归)是一种根据问题本身来定义问题的编程技术,它通过将问题分解为与其自身相同的、只是规模小一些的子问题来解决问题。例如,一个正整数的阶乘就是从1一直到该正整数的所有整数的乘积。(a)0!=1,这被称为基线情况。(b)正整数n的阶乘是n乘以n-1的阶乘。这称为一般情况,显然阶乘是根据其自身来定义的问题。7.12Recursion(递归)使用定义,3的阶乘计算如下:Thevalueofnis3so,using(b)above,3!=3*2!Nextfind2!Heren=2so,using(b)again,2!=2*1!Nextfind1!Heren=1so,using(b)again,1!=1*0!Nextfind0!Inthiscaseusing(a),0!isdefinedas1.Substitutingfor0!gives1!=1*1=1.Substitutingfor1!gives2!=2*1!=2*1=2.Finally,substitutingfor2!gives3!=3*2!=3*2=6.7.12Recursion(递归)ProgramExampleP7N7.12Recursion(递归)ProgramExampleP7N注意:●每一个递归数必须至少有一个基线情况,它是用来结束递归过程的。●一般情况必须最终能简化为基线情况。7.12Recursion(递归)阶乘函数可以使用迭代方法来写递归方法编写的程序执行效率低于迭代方法编写的程序,这是因为增加了函数调用的开销。由于递归程序遵循了阶乘的实际数学定义,因此用递归方法编写的程序具有更清晰的优点。7.13Functionoverloading(函数重载)函数重载

通常用在两个或多个函数需要执行相同功能、而每个函数需要不同数量的实参或者实参数据类型不同的时候。在一个程序中,使用具有相同函数名的不同函数,称为函数重载,这样的函数称为重载函数。函数重载要求每个重载函数具有不同的形参列表,即形参个数不同,或者至少有一个形参类型不同。7.13FunctionoverloadingProgramExampleP7O编译器根据实参与形参匹配的结果来确定调用两个sum_array()函数中的哪一个。7.13FunctionoverloadingProgramExampleP7O…continued7.14Storageclassesautoandstatic

(auto和static存储类型)7.14.1auto在函数内部定义的变量是auto(自动)存储类型。每次进入函数(包括main())时,都为每个auto存储类型的变量重新分配内存空间。函数结束时,将分配的内存空间释放,存储在auto变量中的任何数值都将丢失。这样的变量称为局部变量,只能在定义它的函数内部访问。变量var1和var2的存储类型定义为auto。关键字auto可以省略。7.14Storageclassesautoandstatic7.14.2static和auto变量一样,static变量对定义它们的函数而言,也是局部的。static变量只分配一次存储空间,因此即使函数结束后仍然保持其值不变。ProgramExampleP7P7.14StorageclassesautoandstaticProgramExampleP7P…continued变量static_var只进行了一次初始化,并且在每次函数调用时都能保留其原有的值,即每次调用函数any_func()之后,变量static_var的值都会被加1。自动变量auto_var在每次进入函数时都被重新创建并初始化为0,然后增加到1。7.15Thescopeofavariable(变

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论