C++启蒙之节制布局
副标题#e#
语句是按序次执行的:同一个函数中第一个语句首先执行,接着执行第二个……虽然,少数的措施–包罗我们需要编写的办理书店问题的措施–可以只利用一个序次执行。作为取代,编程语言提供了多种节制布局,答允越发巨大的执行路径。这一部门将简朴地先容C++提供的一些节制布局。
操练7:
编译一个包括错误的嵌套注释的措施。
操练8:
指出下面哪些输出语句是正当的:
std::cout << "/*";
std::cout << "*/";
std::cout << /* "*/" */;
在你作出判定之后,编译这三个语句测试本身的谜底。更正本身碰着的错误。
1、while语句
While语句用于迭代执行。我们可以利用while编写一个措施来计较1到10之间数字的和:
#include <iostream>
int main()
{
int sum = 0, val = 1;
// 一连执行
while
until
val
is greater than 10
while (val <= 10) {
sum += val; // 赋值 sum + val 赋给sum
++val; // 增加 给val加1
}
std::cout << "Sum of 1 to 10 inclusive is "
<< sum << std::endl;
return 0;
}
该措施编译和执行今后打印出:
Sum of 1 to 10 inclusive is 55
像前面的例子一样,我们先包括了iostream头文件并界说了一个main函数。在main函数中我们界说了两个整型变量:sum生存数字的和,val暗示从1到10的值。我们给sum赋了一个初始值0,val的开始值为1。
个中的重要部门是while语句。While的形式如下
while (condition) while_body_statement;
While周期性地测试condition(条件)并执行相关的语句,直到条件为假。
#p#副标题#e#
条件是一个表达式,我们可以计较它的值,这样才气测试其功效。假如功效值非零,那么条件为真;假如值为零那么条件为假。
假如条件是真的(表达式计较出的值非零),那么就执行while_body_statement。在执行while_body_statement之后,再次测试条件。假如条件仍然是真的,那么就再次执行while_body_statement。While一连执行,要么测试条件,要么执行while_body_statement直到条件为假。
在这个措施中,while语句是:
// 一连执行
while
until
val
is greater than 10
while (val <= 10) {
sum += val; // 赋值 sum + val 赋给sum
++val; // 增加 给val加1
}
上面的While中的条件利用小于或便是操纵符(<=操纵符)来较量val的当前值与10的巨细。只要val小于或便是10,我们就执行while的主体。在这种环境下,while的主体是一个包括两个语句的代码块:
{
sum += val; // 赋值 sum + val 赋给sum
++val; // 增加 给va l加1
}
代码块是用海浪括号包括的语句序列。在C++中,代码块可以用于任何可以或许利用语句的位置。代码块中的第一个语句利用了复合赋值操纵符(+=操纵符)。这个操纵符把右边的操纵数加上左边的操纵数。它的结果与下面的赋值语句沟通:
sum = sum + val; // 赋值 sum + val 赋给sum
因此,第一个语句把val的值与sum的当前值相加,并把功效存放到sum中。
下一个语句
++val; // 增加 给val加1
利用了前缀增量操纵符(++操纵符)。增量操纵符给本身的操纵数加1。++val与val = val + 1是沟通的。
在执行while主体之后我们再次执行while中的条件。假如(此刻已经增加了的)val值仍然小于或便是10,那么就再次执行while的主体。轮回继承,测试条件和执行主体,直到val不再小于或便是10。
一旦val大于10,我们就跳出while轮回并执行while后头的语句。在例子中,语句打印输出信息,然后返回,终止main措施。
C++措施的缩排和名目化
C++措施的名目在很洪流平上是自由的,这意味着海浪括号、缩排、注释和新行凡是对措施的寄义是没有影响的。譬喻,暗示main开始的海浪括号可以与main在同一行,而我们把它放在了下一行,或放在任何我们喜欢的位置。独一的要求是它必需是main参数列表反括号后头的第一个非空格、非注释标记。
尽量我们对措施名目化有很大的自由度,可是我们的选择会影响措施的可读性。譬喻,我们可以把main函数写在一个很长的行中。这种界说尽量是正当的,可是却难以阅读。
如何对C或C++措施举办正确的名目化一直存在争论。我们认为并不是只存在一种正确的样式。我们倾向于把界说函数界线的海浪括号放在它们本身的行中。我们倾向于缩排输入或输出表达式,这样操纵符可以分列起来,就像我们编写main函数中的输出语句一样。跟着我们的措施越来越巨大,其它一些缩排习惯会清晰起来的。
#p#分页标题#e#
我们要记着,用其它的方法名目化措施也是可行的。当选择某种名目样式的时候,请思量它对可读性和领略力的影响。一旦你选择了某种样式,就一致性地利用它。
2、for语句
在我们的while轮回中,我们利用变量var来节制轮回中迭代的次数。每次颠末while的时候,都测试val值,然后增加主体中的val值。
利用像val那样的变量来节制轮回是常常用到的,语言也提供了第二种节制布局,叫做for语句,它简化了打点轮回变量的代码。我们将利用for轮回来从头编写一个计较1到10的和的措施:
#include <iostream>
int main()
{
int sum = 0;
// 计较1到10之间所有数字的和
for (int val = 1; val <= 10; ++val)
sum += val; //等同于sum = sum + val
std::cout << "Sum of 1 to 10 inclusive is "
<< sum << std::endl;
return 0;
}
我们在前面的for轮回中界说了sum,并把它配置为零。变量val只在迭代内部利用,而且是作为语句自身的一部门界说的。
For语句
for (int val = 1; val <= 10; ++val)
sum += val; // 等同于 sum = sum + val
有两个部门:for头和for主体。头节制主体执行的次数。头自己包括三个部门:初始化语句、条件和表达式。在这种环境下,初始语句
int val = 1;界说了一个整型的叫做val的工具并把它的初始值配置为1。初始语句只在进入for的时候执行一次。条件val <= 10较量当前值与10的巨细,每次轮回的时候城市测试它的值。只要val小于或便是10,就执行for主体。执行主体之后才执行表达式。在这个for中,表达式利用了前缀增长操纵符,就是给val的值加上1。在执行表达式之后,for继承测试条件。假如val的新值仍然小于或便是10,那么接着执行for轮回主体,val的值继承增长。执行进程一直一连,直到条件失败为止。
在这个轮回中,for主体执行了求和操纵:
sum += val; // 等同于 sum = sum + val
上面的主体利用复合赋值操纵符把当前的val值增加给sum,并把功效存回sum。
扼腹地重述,这个for的全部执行流程是:
1.成立val并把它的初始值设为1。
2.测试val的值是否小于或便是10。
3.假如val小于或便是10就执行for主体,把val加上sum。假如val并非小于或便是10,那么就终止轮回,继承执行轮回后头的第一个语句。
4.增加val的值。
5.反复步调2中的测试,只要条件为真就继承它后头的步调。
请留意:
当我们退出for轮回的时候,就再也不能会见变量val了。在这个轮回终止之后不能利用val。可是,并非所有的编译器都有这个强制条件。
回首编译进程
编译器任务的一部门是查抄措施文本中的错误。编译器不能检测措施的寄义是否正确,可是它可以检测措施形式的错误。下面是编译器大概检测到的一些凡是的错误。
1.语法错误。措施员犯了C++语法错误。下面的措施演示了凡是的语法错误;下面行中的每个注释都描写了错误信息:
// error: missing ')' in parameter list for main
int main ( {
// error: used colon, not a semicolon after endl
std::cout << "Read each file." << std::endl:
// error: missing quotes around string literal
std::cout << Update master. << std::endl;
// ok: no errors on this line
std::cout << "Write new master." <<std::endl;
// error: missing ';' on return statement
return 0
}
2.范例错误。C++中每个数据条目都有相关的范例。譬喻10是个整数。单词"hello"是字符串文本。范例错误的例子有给但愿吸收整型参数的函数通报了字符串文本。
3.声明错误。C++中利用的每个名字都必需在利用之前先界说。没有界说名字凡是导致错误动静。最常见的声明错误是在会见类库中的名字的时候忘了利用std::,可能不留意拼错了提示符的名称:
#include <iostream>
int main()
{
int v1, v2;
std::cin >> v >> v2; // error: uses " v "not" v1"
// 不能界说,应该是 std::cout
cout << v1 + v2 << std::endl;
return 0;
}
错误动静包括一个行号和编译器认为的错误的描写。凭据错误陈诉的序次修改错误是很好的履历。凡是一个错误会有级联效应并引起编译器陈诉比实际环境多的错误。每次修补今后可能至少在修补了少量的明明错误之后,从头编译代码也是很好的履历。这个轮回就是众所周知的编译-编译-调试。
操练9:
下面的for轮回实现什么成果?Sum之后的值是几多?
int sum = 0;
for (int i = -100; i <= 100; ++i)
sum += i;
操练10:
编写一个措施利用for轮回统计50到100之间所有数字的和。然后从头利用while编写一遍。
操练11:
编写一个措施利用while轮回打印从10到0的数字。然后用for从头编写一次。
操练12:
较量你在前面两个操练中编写的轮回。利用每种形式都有些什么优缺点?
操练13:
#p#分页标题#e#
编译器对诊断信息的领略是差异的。编写一些包括了上面接头的普通错误的措施。研究编译器发生的动静,这样就可以熟习本身碰着的动静,以适应更巨大的措施。
3、if语句
作为对1和10之间的数字求和的逻辑扩展,我们可以计较用户提供的两个数字之间所有值的和。我们可以在for轮回中直接利用数字,把第一个数字作为下界线,第二个作为上界线。可是,假如用户提供的第一个数字较大,这个计策就失败了:我们的措施会当即退出for轮回。作为取代,我们应该调解范畴,使较大的数字作为上界线,较小的数字作为下界线。为了实现这个成果,我们需要分辨哪个数字较量大的途径。
与大都语言一样,C++语言也提供了if语句支持条件执行。我们可以利用if语句修悔改的求和措施:
#include <iostream>
int main()
{
std::cout << "Enter two numbers:" << std::endl;
int v1, v2;
std::cin >> v1 >> v2; // 读取输入
// 把较小的数字作为下界线,较大的数字作为上界线
int lower, upper;
if (v1 <= v2) {
lower = v1;
upper = v2;
} else {
lower = v2;
upper = v1;
}
int sum = 0;
// 求下界线与上界线之间的数字的和
for (int val = lower; val <= upper; ++val)
sum += val; // sum = sum + val
std::cout << "Sum of " << lower
<< " to " << upper
<< " inclusive is "
<< sum << std::endl;
return 0;
}
假如我们编译并执行这个措施,并输入数组7和3,这个措施的输出信息是:
Sum of 3 to 7 inclusive is 25
这个措施中的大大都代码与前面例子中的沟通。该措施先提示用户并界说了四个整型变量。接着它从尺度的输入中读取信息到v1和v2。独一的新代码是if语句
// 把较小的数字作为下界线,较大的数字作为上界线
int lower, upper;
if (v1 <= v2) {
lower = v1;
upper = v2;
} else {
lower = v2;
upper = v1;
}
这段代码的结果就是适内地配置upper和lower。个中的if条件测试v1是否小于或便是v2。假如是这样的,我们就当即执行条件后头的代码块。这个代码块包括两个语句,每个语句执行一次赋值操纵。第一个语句把v1赋给lower,把v2赋给upper。
假如该条件为假–也就是说v1大于v2–那么我们就执行else后头的语句。同样,这个语句也是包括两个赋值操纵的代码块。我们把v2赋给lower,把v1赋给upper。
4、读取未知数量的输入信息
我们进一步对这个措施举办修改,答允用户指定一组数字来求和。在这种环境下,我们不知道加上几多个数字。作为取代,我们但愿保持读取数字状态,直到措施到达输入信息的末端。当输入竣事今后,措施给尺度输出写入它们的和:
操练14:
假如输入的数字是相等的,这个措施会怎么办?
操练15:
编译和运行这一部门的措施,输入两个相等的值。把其输出值与你估量的值举办比拟。表明两者之间的纷歧致。
操练16:
编写一个措施打印出用户提供的两个输入信息中较大的一个。
操练17:
编写一个措施让用户输入一系列的数字。打印出一个动静,说明这些数字中有几多个负数。
#include <iostream>
int main()
{
int sum = 0, value;
// 读取直到文件尾,计较读取的值
while (std::cin >> value)
sum += value; // 等同于 sum = sum + value
std::cout << "Sum is: " << sum << std::endl;
return 0;
}
假如我们提供应这个措施的输入信息是:3 4 5 6
那么输入功效将会是:
Sum is: 18
像凡是一样,我们先包括了须要的头文件。Main函数中的第一行界说了两个变量,别离是sum和value。我们将利用value来生存我们读取的每个数字,这是在while条件内部实现的:
while (std::cin >> value)
此处产生的操纵就是对条件的计较,输入操纵
std::cin >> value
#p#分页标题#e#
被执行,它的结果是从尺度的输入中读取下一个数字,把读取的内容生存到value中。这个输入操纵符返回左边的操纵数。条件测试了这个功效,也就是测试了std::cin。
当我们把istream作为条件的时候,其结果是测试流的状态。假如流是有效的–也就是说,仍然可以或许读取别的一个输入–那么测试是乐成的。当我们输入文件末了标识或碰着无效的输入(譬喻读取的值不是整数)的时候,istream就酿成无效的。Istream处于无效状态将导致条件失败。
测试将一直乐成并执行while主体,直到我们简直碰着文件尾标识(或其它的输入错误)。它的主体是一个语句,利用了复合赋值操纵符。这个操纵符把右边的操纵数加到左边的操纵数上。
在键盘上输入文件尾标识
差异的操纵系统利用的文件尾标识值差异。在Windows系统上我们通过按control-z–同时按下"ctrl"和"z"来输入文件尾标识。在Unix系统中(包罗Mac OS-X计较机),凡是是control-d。
一旦测试失败了,while就终止了,我们将跳出轮回并执行while后头的语句。这个语句打印出sum和endl(它打印出新行并刷新与cout关联的缓冲器)。最后,我们执行了return(返回),它凡是返回0表白乐成了。
操练18:
编写一个措施,提示用户输入两个数字,在尺度的输出中写入两个数字之间的所有数字。
操练19:
假如上面的操练中给出的数字是1000和2000会产生什么环境?修改前面的措施,使它不要在每一行输出10个以上的数字。
操练20:
编写一个措施来计较用户给定的范畴之间的数字的和,略过配置上下界线的if测试。估量一下假如输入信息是7和3会产生什么环境。此刻运行措施,并输入7和3,看当作果是否跟你的估量沟通。假如差异,从头研究一个对for和while轮回的接头内容,直到领略产生的环境。