【C++ primer 5e】第一章开始
知识点整理
endl
操纵符之一,结束当前行,并将设备关联的缓冲区中的内容刷到设备中。
缓冲刷新操作保证到目前为止的程序所产生的所有输出都真正写入到输出流中,而不是仅停留在内存等待写入流。程序员常常在调试时添加打印语句。这类语句应该保证一直刷新流。 否则,如果程序崩溃,输出可能还留在缓冲区中,从而导致关于程序崩溃位置的错误推断。
输出运算符
<<
接受两个对象,左侧的对象必须是一个ostream
对象,右侧的对象是要打印的值,并返回左侧对象。输入运算符
>>
接受两个对象,左侧对象接受一个istream
对象,从给定的istream
读入数据,存入给定的右侧对象中,并返回左侧对象。单行注释,
//
开始,以换行符结束。多行注释,用两个注释界定符
/*
,*/
,这种注释以/*
开始,以*/
结束,可以包含出*/
外的任意内容,包括换行符。当注释符跨越多行时,最好能显示指出其内部程序行都属于多行注释的一部分。 我们所采用的风格是,注释内的每行都以一个
*
开头,从而指出整个范围都是多行注释的一部分。注释界定符不能嵌套。
while语句反复执行一段代码,直至给定的条件为假为止。
while (condition) { statement }
for语句包含循环头,循环体,循环头控制循环体的执行次数。
for (init-statement; condition; expression) { // 循环头 // 循环体 }
初始化语句只在for循环入口处执行一次。 循环体每次执行前都会先检查循环条件。 表达式在for循环体之后执行。
当从键盘向程序输入数据时,对于如何指出文件结束,不同操作系统有不用的约定,在windows系统中,输入文件结束符的方法是敲
Ctrl+Z
, 然后按Enter或Return键。 在Unix系统中,包括Mac OS X 系统中,文件结束符输入是用Ctrl + D
。// 读取数量不定的输入数据 int main(int argc, char const *argv[]) { int sum = 0, value = 0; while (cin >> value) { sum += value; } cout << "sum is: " << sum << endl; return 0; }
表达式
cin >> value
从标准输入读取下一个数,保存在value中。 输入运算符返回左侧运算对象,因此,循环条件实际上检测的是cin
, 当我们使用一个istream对象作为条件时,其效果是检测流的状态。如果流是有效的,即流未遇到错误,那么检测成功。 当遇到文件结束符,或遇到一个无效的输入时(假设读入的值不是一个整数),istream对象的状态就会变为无效。 处于无效状态的istream 对象会使条件为假。
输入两个整数,返回两个整数的和
#include<iostream> using namespace std; int main(int argc, char const *argv[]) { float a = 0, b = 0; cout << "please input two number: " << endl; cin >> a >> b; cout << a << " and " << b << " sum: " << a + b << endl; return 0; }
练习1.3: 编写程序,在标准输出上打印hello world
#include<iostream> int main(int argc, char const *argv[]) { std::cout << "hello world" << std::endl; return 0; }
练习1.4: 我们的程序使用加法运算符+来将两个数相加。 编写程序使用乘法运算符*,来打印两个数的积
#include<iostream> using namespace std; int main(int argc, char const *argv[]) { float a = 0, b = 0; cout << "please input two number: " << endl; cin >> a >> b; cout << a << " * " << b << " = " << a * b << endl; return 0; }
练习1.5: 我们将所有输出操作放在一条很长的语句中。 重写程序,将每个运算对象的打印操作放在一条独立的语句中。
#include<iostream> using namespace std; int main(int argc, char const *argv[]) { // 长语句 cout << "hello" << " world" << " haha" << endl; // 独立短语句 cout << "hello"; cout << " world"; cout << " haha"; cout << endl; return 0; }
练习1.6: 解释下面程序片段是否合法。
std::cout << "The sum of " << v1; << " and " << v2; << " is " << v1 + v2 << std::endl;
如果程序是合法的,它输出什么? 如果程序不合法,原因何在? 应该如何修正?
答: 不合法,每一行的后面都添加了;
,表示该行结束,第一行增加了分号,第二行的<<
的左侧就没有了一个ostream
对象,导致语法错误,可以在2,3行左侧加std::cout
, 也可以把分号去掉。
// 加 cout std::cout << "The sum of " << v1; std::cout << " and " << v2; std::cout << " is " << v1 + v2 << std::endl;
// 去掉分号 std::cout << "The sum of " << v1 << " and " << v2 << " is " << v1 + v2 << std::endl;
练习1.7: 编译一个包含不正确嵌套注释的程序,观察编译器返回的错误信息。
int main(int argc, char const *argv[]) { /* * * 注释对 /* */ 不能嵌套 */ return 0; }
编译器返回: 在注释外找到“*/”
练习1.8: 指出下列语句哪些是合法的(如果有的话)
std::cout << "/*"; std::cout << "*/"; std::cout << /* "*/" */; std::cout << /* "*/" /* "/*" */;
预编译这些语句会产生什么样的结果,实际编译这些语句来验证你的答案(编写一个小程序,每次将上述语句作为其主体),改正每个编译错误。
std::cout << "/*";
正确的std::cout << "*/";
正确的std::cout << /* "*/" */;
不正确,嵌套界定符了,改为std::cout << "*/" /* */;
std::cout << /* "*/" /* "/*" */;
正确的,前后都有匹配的界定符,并且保证了cout
右边是一个对象。
练习1.9: 编写程序,使用while 循环将50-100的整数相加
int main(int argc, char const *argv[]) { int i = 50, sum = 0; while (i <= 100) { sum += i; ++i; } cout << sum << endl; return 0; }
练习1.10: 除了++运算符将运算对象的值增加1之外,还有一个递减运算符--实现将值减1。 编写程序,使用递减运算符在循环中按递减顺序打印出10到0之间的整数。
int main(int argc, char const *argv[]) { int i = 10; while (i >= 0) { cout << i-- << endl; } return 0; }
练习1.11: 编写程序,提示用户输入两个整数,打印出这两个整数所指定的范围内的所有整数。
int main(int argc, char const *argv[]) { cout << "please input two number: " << endl; int start = 0, end = 0; cin >> start >> end; cout << start << "-" << end << " all int number: " << endl; while (start <= end) { cout << start++ << " "; } cout << endl; return 0; }
练习1.12: 下面for循环完成了什么功能? sum 的终值是多少?
int sum = 0; for (int i = -100; i <= 100; ++i) { sum += i; }
从 -100 加到 100,sum的终值是0
练习1.13: 使用for循环重做1.4.1节中所有的练习。
int sum = 0; for (int i=50; i <= 100; ++i) { sum += i; }
for (int i = 10; i >= 0; --i) { cout << i << " "; }
cout << "please input two number: " << endl; int start = 0, end = 0; cin >> start >> end; cout << start << "-" << end << " all int number: " << endl; for (int i = start; i <= end; ++i) { cout << i << " "; } cout << endl;
练习1.14: 对比for循环和while循环,两种形式的优缺点各是什么?
while 循环中,在循环条件中检查变量,在循环体中递增变量的模式非常频繁,所以有了for语句,来简化这种模式的语句。
练习1.15: 编写程序,包含第14页”再探编译“中讨论的常见的错误。 熟悉编译器生成的错误信息。
练习1.16: 编写程序,从cin读取一组数,输出其和。
int sum = 0, value = 0; while (cin >> value) { sum += value; } cout << "sum is: " << sum << endl;
练习1.17: 如果输入的所有值都是相等的,本节的代码会输出什么? 如果没有重复值,输出又会是怎样呢?
// 练习1.17,1.18 所指的代码 int main(int argc, char const *argv[]) { int curValue = 0, val = 0; if (cin >> curValue) { int count = 1; while (cin >> val) { if (curValue == val) { ++count; } else { cout << curValue << " occurs " << count << " times" << endl; curValue = val; count = 1; } } cout << curValue << " occurs " << count << " times" << endl; } return 0; }
练习1.18: 编译并运行本节程序,给它输入全部相等的值。 再次运行程序,输入没有重复的值。
练习1.19: 修改你为1.11编写的程序,使其能够处理用户输入的第一个数比第二个数小的情况。
int main(int argc, char const *argv[]) { cout << "please input two number: " << endl; int start = 0, end = 0; cin >> start >> end; cout << start << "-" << end << " all int number: " << endl; if (start > end) { swap(start, end); } while (start <= end) { cout << start++ << " "; } cout << endl; return 0; }