《C++primer(第五版)》学习之路-第五章:语句

【 声明:版权所有,转载请标明出处,请勿用于商业用途。  联系信箱:[email protected]】

5.1 简单语句

1.绝大多数语句以分号结束。空语句只有一个单独的分号。

2.复合语句是指用花括号括起来的语句和声明的序列,复合语句也被称作块。

一个块就是一个作用域,在块中引入的名字只能在块内部以及嵌套在块中的子块里访问。

5.2 语句作用域

1.可以在if,switch,for和while语句的控制结构内定义变量。定义在控制结构当中的变量只在相应语句的内部可见,一旦语句结束,变量也就超出其作用范围了。

5.3 条件语句

1.C++提供了两种按条件执行的语句。

一种是if语句,它根据条件决定控制流

一种是switch语句,它计算一个整型表达式的值,然后根据这个值从几条执行路径中选择一条。

2.if语句的作用是:判断一个指定的条件是否为真,根据判断结果决定是否执行另外一条语句。

3.switch语句首先对括号里的表达式求值,表达式值转换成整数类型,然后与每个case标签的值比较。

case关键字和它对应的值一起被成为case标签。case标签必须是整型常量表达式。

4.如果没有任何一个case标签能匹配上switch表达式的值,程序将执行紧跟在default标签后面的语句。

5.4 迭代语句

1.迭代语句通常称为循环,它重复执行操作直到满足某个条件才停下来。while和for语句在执行循环之前检查条件,do while先执行循环体,然后再检查条件。

2.范围for语句:C++11新标准引入了一种更简单的for语句,这种语句可以遍历容器或者其他序列的所有元素。

范围for语句的语法形式是:

for(declaration: expression)

statement;

5.5 跳转语句

1.C++提供了4种跳转语句:break,continue,goto和return。

2.break语句负责终止离它最近的while、do while、for或switch语句,并从这些语句之后的第一条语句开始继续执行。

3. continue语句终止最近的循环中的当前迭代并立即开始下一次迭代。

4.goto语句的作用是从goto语句无条件跳转到同一函数的另一条语句。

5.6 try语句块和异常处理

1.在C++语言中,异常处理包括:

throw表达式,异常检测部分使用throw表达式来表示它遇到了无法处理的问题。我们说throw引发了异常。

try语句块,异常处理部分使用try语句块处理异常。try语句块以关键字try开始,并以一个或多个catch子句结束。try语句块中代码抛出的异常通常会被某个catch子句处理。因为catch子句“处理”异常,所以它们也被称作异常处理代码

一套异常类,用于在throw表达式和相关的catch子句之间传递异常的具体信息。

2.程序的异常检测部分使用throw表达式引发一个异常。throw表达式包含关键字throw和紧随其后的一个表达式,其中表达式的类型就是抛出的异常类型。

3.try语句块的通用语法形式是

try{
	program-statements;
}catch(exception-declaration){
	handler-statements;
}catch(exception-declaration){
	handler-statements;
} //...

try语句块一开始是关键字try,随后紧跟着一个块,这个块就像大多数时候那样是花括号括起来的语句序列。

跟在try块之后的是一个或多个catch子句。catch子句包括三部分:关键字catch、括号内一个(可能是未命名的)对象声明(称作异常声明)以及一个块。当选中了某个catch子句处理异常之后,执行与之对应的块。catch一旦完成,程序跳转到try语句块最后一个catch子句之后的那条语句继续执行。

try语句块中的program-statements组成程序的正常逻辑,像其他任何块一样,program-statements可以有包括声明在内的任意C++语句。

4.C++标准库定义了一组类,用于报告标准库函数遇到的问题。这些异常类也可以在用户编写的程序中使用,它们分别定义在四个头文件中:

exception头文件定义了最通常的异常类exception。它只报告异常的发生,不提供额外信息。

stdexcept头文件定义了几中常用的异常类。

new头文件定义了bad_alloc异常类型。

type_info头文件定义了bad_cast异常类型。

5.<stdexcept>定义的异常类

exception             最常见的问题

runtime_error       运行时错误:仅在运行时才能检测到得错误

range_error         运行时错误:生成的结果超出了有意义的值域范围

overflow_error     运行时错误:计算上溢

underflow_error   运行时错误 :计算下溢

logic_error           逻辑错误:可在运行前检测到得问题

domain_error       逻辑错误:参数的结果值不存在

invalid_argument 逻辑错误:不合适的参数

length_error         逻辑错误:试图生成 一个超出改类型最大长度的对象

out_of_range       逻辑错误:使用一个超出有效范围的值

PS:部分练习答案

练习5.3

#include <iostream>
int main()
{
	int sum = 0, val = 1;
	while (val <= 10)
		sum += val, ++val;
	std::cout << "Sum of 1 to 10 inclusive is "<< sum << std::endl;

	return 0;
}

练习5.4

(a)迭代器没有指向

#include <iostream>
int main()
{
	int sum = 0, val = 1;
	while (val <= 10)
		sum += val, ++val;
	std::cout << "Sum of 1 to 10 inclusive is "<< sum << std::endl;

	return 0;
}

(b)if不在while循环里面,因此if里的status没有定义

bool status;
while ((status = find(word))) {/* ... */}
if (!status) {/* ... */}

事实上这个if是没有必要的,因为一旦while结束吗,我们可以知道此事status必然为false

练习5.5

#include <iostream>
#include <vector>
#include <string>

using std::vector;
using std::string;
using std::cout;
using std::endl;
using std::cin;

int main()
{
	vector<string> scores = {"F", "D", "C", "B", "A", "A++"};

	int grade {0};
	while (cin >> grade)
	{
		string lettergrade;
		if (grade < 60)
			lettergrade = scores[0];
		else
		{
			lettergrade = scores[(grade - 50) / 10];
			if (grade != 100)
			{
				if (grade % 10 > 7)
					lettergrade += "+";
				else if (grade % 10 < 3)
					lettergrade += "-";
			}
		}

		cout << lettergrade << endl;
	}

	return 0;
}

练习5.6

#include <iostream>
#include <vector>
#include <string>

using std::vector;
using std::string;
using std::cout;
using std::endl;
using std::cin;

int main()
{
	vector<string> scores = {"F", "D", "C", "B", "A", "A++"};

	int grade {0};
	while (cin >> grade)
	{
		string lettergrade = grade < 60 ? scores[0] : scores[(grade - 50) / 10];
		lettergrade +=(grade == 100 || grade < 60)? "": (grade % 10 > 7) ? "+" : (grade % 10 < 3) ? "-" : "";
		cout << lettergrade << endl;
	}

	return 0;
}

练习5.7

(a) if (ival1 != ival2) ival1 = ival2;
    else ival1 = ival2 = 0;
(b) if (ival < minval)
    {
        minval = ival;
        occurs = 1;
    }
(c) int val;
    if (ival = get_value())
        cout << "ival = " << ival << endl;
    if (!ival)
        cout << "ival = 0\n";
(d) if (ival == 0)
    ival = get_value();

练习5.9

#include <iostream>

using std::cout;
using std::endl;
using std::cin;

int main()
{
	unsigned aCnt = 0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt = 0;
	char ch;
	while (cin >> ch)
	{
		if (ch == 'a')
			++aCnt;
		else if (ch == 'e')
			++eCnt;
		else if (ch == 'i')
			++iCnt;
		else if (ch == 'o')
			++oCnt;
		else if (ch == 'u')
			++uCnt;
	}
	cout << "Number of vowel a: \t" << aCnt << "\n"
		 << "Number of vowel e: \t" << eCnt << "\n"
	     << "Number of vowel i: \t" << iCnt << "\n"
	     << "Number of vowel o: \t" << oCnt << "\n"
		 << "Number of vowel u: \t" << uCnt << endl;

	return 0;
}

练习5.10

#include <iostream>
using std::cin;
using std::cout;
using std::endl;

int main()
{
	unsigned aCnt = 0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt = 0;
	char ch;
	while (cin >> ch)
		switch (ch)
		{
			case 'a':
			case 'A':
				++aCnt;
				break;
			case 'e':
			case 'E':
				++eCnt;
				break;
			case 'i':
			case 'I':
				++iCnt;
				break;
			case 'o':
			case 'O':
				++oCnt;
				break;
			case 'u':
			case 'U':
				++uCnt;
				break;
		}

	cout << "Number of vowel a(A): \t" << aCnt << "\n"
	     << "Number of vowel e(E): \t" << eCnt << "\n"
	     << "Number of vowel i(I): \t" << iCnt << "\n"
	     << "Number of vowel o(O): \t" << oCnt << "\n"
	     << "Number of vowel u(U): \t" << uCnt << endl;

	return 0;
}

练习5.11

#include <iostream>

using std::cin;
using std::cout;
using std::endl;

int main()
{
	unsigned aCnt = 0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt = 0, spaceCnt = 0,tabCnt = 0, newLineCnt = 0;
	char ch;
	while (cin >> std::noskipws >> ch)
		switch (ch)
		{
			case 'a':
			case 'A':
				++aCnt;
				break;
			case 'e':
			case 'E':
				++eCnt;
				break;
			case 'i':
			case 'I':
				++iCnt;
				break;
			case 'o':
			case 'O':
				++oCnt;
				break;
			case 'u':
			case 'U':
				++uCnt;
				break;
			case ' ':
				++spaceCnt;
				break;
			case '\t':
				++tabCnt;
				break;
			case '\n':
				++newLineCnt;
				break;
		}

	cout << "Number of vowel a(A): \t" << aCnt << "\n"
	     << "Number of vowel e(E): \t" << eCnt << "\n"
	     << "Number of vowel i(I): \t" << iCnt << "\n"
	     << "Number of vowel o(O): \t" << oCnt << "\n"
	     << "Number of vowel u(U): \t" << uCnt << "\n"
	     << "Number of space: \t"  << spaceCnt << "\n"
	     << "Number of tab char: \t" << tabCnt << "\n"
	     << "Number of new line: \t" << newLineCnt << endl;

	return 0;
}

练习5.12

#include <iostream>

using std::cin;
using std::cout;
using std::endl;

int main()
{
    unsigned aCnt = 0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt = 0, spaceCnt = 0,tabCnt = 0, newLineCnt = 0, ffCnt = 0, flCnt = 0, fiCnt = 0;
    char ch, prech = '\0';
    while (cin >> std::noskipws >> ch) {
        switch (ch) {
        case 'a':
        case 'A':
            ++aCnt;
            break;
        case 'e':
        case 'E':
            ++eCnt;
            break;
        case 'i':
            if (prech == 'f') ++fiCnt;
        case 'I':
            ++iCnt;
            break;
        case 'o':
        case 'O':
            ++oCnt;
            break;
        case 'u':
        case 'U':
            ++uCnt;
            break;
        case ' ':
            ++spaceCnt;
            break;
        case '\t':
            ++tabCnt;
            break;
        case '\n':
            ++newLineCnt;
            break;
        case 'f':
            if (prech == 'f') ++ffCnt;
            break;
        case 'l':
            if (prech == 'f') ++flCnt;
            break;
        }
        prech = ch;
    }

    cout << "Number of vowel a(A): \t" << aCnt << "\n"
         << "Number of vowel e(E): \t" << eCnt << "\n"
         << "Number of vowel i(I): \t" << iCnt << "\n"
         << "Number of vowel o(O): \t" << oCnt << "\n"
         << "Number of vowel u(U): \t" << uCnt << "\n"
		 << "Number of space: \t" << spaceCnt << "\n"
		 << "Number of tab char: \t" << tabCnt << "\n"
         << "Number of new line: \t" << newLineCnt << "\n"
		 << "Number of ff: \t" << ffCnt << "\n"
		 << "Number of fl: \t" << flCnt << "\n"
         << "Number of fi: \t" << fiCnt << endl;

    return 0;
}

练习5.13

(a) //缺少break
    unsigned aCnt = 0, eCnt = 0, iouCnt = 0;
    char ch = next_text();
    switch (ch) {
        case 'a': aCnt++; break;
        case 'e': eCnt++; break;
        default : iouCnt++; break;
    }
(b) //ix应该定义在外部
    unsigned index = some_value();
    int ix;
    switch (index) {
        case 1:
            ix = get_value();
            ivec[ ix ] = index;
            break;
        default:
            ix = static_cast<int>(ivec.size())-1;
            ivec[ ix ] = index;
    }
(c) //case语法错误
    unsigned evenCnt = 0, oddCnt = 0;
    int digit = get_num() % 10;
    switch (digit) {
        case 1: case 3: case 5: case 7: case 9:
            oddcnt++;
            break;
        case 2: case 4: case 6: case 8: case 0:
            evencnt++;
            break;
    }
(d) //case标签必须是常数
    const unsigned ival=512, jval=1024, kval=4096;
    unsigned bufsize;
    unsigned swt = get_bufCnt();
    switch(swt) {
        case ival:
            bufsize = ival * sizeof(int);
            break;
        case jval:
            bufsize = jval * sizeof(int);
            break;
        case kval:
            bufsize = kval * sizeof(int);
            break;
    }

练习5.14

#include <iostream>
#include <string>

using std::cout;
using std::cin;
using std::endl;
using std::string;

int main()
{
	string str,max_str,pre_str;
	int max_cnt = 0;
	int count = 0;
	max_str = pre_str = "";
	while(cin>>str)
	{
		if(str==pre_str)
			++count;
		else
			count = 1;
		if(count>max_cnt)
		{
			max_str = str;
			max_cnt = count;
		}
		pre_str = str;
	}

	if (max_str == "")
		cout << "There's no duplicated string." << endl;
	else
		cout << "the word " << max_str << " occurred " << max_cnt << " times. " << endl;

	return 0;
}

练习5.15

(a) int ix;
    for (ix = 0; ix != sz; ++ix)  { /* ... */ }
    if (ix != sz)
    // . . .
(b) int ix;
    for (; ix != sz; ++ix) { /* ... */ }
(c) for (int ix = 0; ix != sz; ++ix) { /*...*/ }

练习5.17

#include <iostream>
#include <vector>

using std::cout;
using std::endl;
using std::vector;

int main()
{
	vector<int> vec1 {0, 1, 1, 2};
	vector<int> vec2 {0, 1, 1, 2, 3, 5, 8};

	auto size = vec1.size() < vec2.size() ? vec1.size() : vec2.size();
	for (decltype(vec1.size()) i = 0; i != size; ++i)
	{
		if (vec1[i] != vec2[i])
		{
			cout << "false" << endl;
			break;
		}
		if (i == size - 1)
			cout << "true" << endl;
	}

	return 0;
}

练习5.18

(a) do {
        int v1, v2;
        cout << "Please enter two numbers to sum:" ;
        if (cin >> v1 >> v2)
            cout << "Sum is: " << v1 + v2 << endl;
    }while (cin);
(b) int ival;
    do {
        // . . .
    } while (ival = get_response());
(c) int ival = get_response();
    do {
        ival = get_response();
    } while (ival); 

练习5.19

#include <iostream>
#include <string>

using std::cout;
using std::cin;
using std::endl;
using std::string;

int main()
{
	string rsp;
	do
	{
		cout << "Input two strings: ";
		string str1, str2;
		cin >> str1 >> str2;
		cout << (str1 <= str2 ? str1 : str2) << " is less than the other. "<< "\n\n"<< "More? Enter yes or no: ";
		cin >> rsp;
	}
	while (!rsp.empty() && rsp[0] == 'y');
	return 0;
}

练习5.20

#include <iostream>
#include <string>

using std::cout;
using std::cin;
using std::endl;
using std::string;

int main()
{
	string str, pre;
	while (cin >> str)
		if (str == pre)
			break;
		else
			pre = str;

	if (cin.eof())
		cout << "no word was repeated." << endl;
	else
		cout << read << " occurs twice in succession." << endl;
	return 0;
}

练习5.21

#include <iostream>
using std::cin;
using std::cout;
using std::endl;

#include <string>
using std::string;

int main()
{
	string curr, prev;
	bool no_twice = false;

	while (cin >> curr)
	{
		if (!isupper(curr[0]))
			continue;
		else if (prev == curr)
		{
			cout << curr << " occurs twice in succession." << endl;
			no_twice = true;
			break;
		}
		else
			prev = curr;
	}

	if (!no_twice) cout << "no word was repeated." << endl;
}

练习5.22

for (int sz = get_size(); sz <=0; sz = get_size())
    ; 

练习5.23

#include <iostream>

int main(void)
{
	int a, b;
	std::cin >> a >> b;
	std::cout << static_cast<double>(a) / b << std::endl;

	return 0;
}

练习5.24

#include <iostream>
#include <stdexcept>

int main(void)
{
    int a, b;
    std::cin >> a >> b;

    if (b == 0) throw std::runtime_error("divisor is 0");

    std::cout << static_cast<double>(a) / b << std::endl;

    return 0;
}

练习5.25

#include <iostream>
#include <stdexcept>
using std::cin;
using std::cout;
using std::endl;
using std::runtime_error;

int main(void)
{
	int a, b;
	cout << "Input two integers: ";
	while (cin >> a >> b)
	{
		try
		{
			if (b == 0) throw runtime_error("divisor is 0");
			cout << static_cast<double>(a) / b << endl;
			cout << "Input two integers: ";
		}
		catch (runtime_error err)
		{
			cout << err.what() << "\n" << "Try again.\nInput two integers: ";
		}
	}

	return 0;
}

版权声明:本文为博主原创文章,如果转载,请注明出处

时间: 2024-10-05 05:02:04

《C++primer(第五版)》学习之路-第五章:语句的相关文章

C++ Primer 第五版学习笔记

<C++ Primer>第五版中文版学习笔记 ? C++ Primer 第五版学习笔记

C++ Primer(第五版)学习笔记_9_标准模板库_multimap多重映照容器

C++ Primer(第五版)学习笔记_9_标准模板库_multimap多重映照容器 多重映照容器multimap与map结构基本相同,但由于重复键值存在,所以multimap的元素插入.删除.查找都与map的方法不相同. 1.multimap对象创建.元素插入 插入元素时,需要使用insert()方法和类似pair<string,double>("Jack", 300.5)的元素结构.可以看到,重复的元素是按照插入的先后顺序排序的. #include <iostre

C++ Primer(第五版)学习笔记_5_标准模板库string(2)

C++ Primer(第五版)学习笔记_5_标准模板库string(2) 10.搜索string对象的元素或子串 采用find()方法可查找字符串中的第一个字符元素(char, 用单引号界定)或者子串(用双引号界定):如果查到,则返回下标值(从0开始计数),如果查不到,则返回一个很大的数string:npos(即:4294967295). #include <iostream> #include <stdio.h> #include <string> using nam

C++ Primer(第五版)学习笔记_3_标准模板库vector(2)

C++ Primer(第五版)学习笔记_3_标准模板库vector(2) 欢迎大家阅读参考,如有错误或疑问请留言纠正,谢谢 6.元素的插入 insert()方法可以在vector对象的任意位置前插入一个新的元素,同时,vector自动扩张一个元素空间,插入位置后的所有元素依次向后挪动一个位置. 要注意的是,insert()方法要求插入的位置,是元素的迭代器位置,而不是元素的下标. #include <iostream> #include <vector> using namespa

C++ Primer(第五版)学习笔记_1_标准模板库--快速入门

C++ Primer(第五版)学习笔记_1_标准模板库--快速入门 欢迎大家阅读参考,如有错误或疑问请留言纠正,谢谢 标准模板库(STL)提供三种类型的组件:容器.迭代器和算法,他们都支持泛型程序设计标准. 容器主要有两类:顺序容器和关联容器.顺序容器(vector.list.deque和string等)是一系列元素的有序集合.关联容器(set.multiset.map和multimap)包含查找元素的键值. 迭代器的作用是遍历容器. STL算法库包含四类算法:排序算法.不可变序算法.变序性算法

C++ Primer(第五版)学习笔记_2_标准模板库vector(1)

C++ Primer(第五版)学习笔记_2_标准模板库vector(1) 欢迎大家阅读参考,如有错误或疑问请留言纠正,谢谢 向量容器vector不但能像数组一样进行随机访问,还能在尾部插入元素,完全可以替代数组. 值得注意的是,vector具有内存自动管理的功能,对于元素的插入和删除,可以动态调整所占的内存空间. 容器vector的下标是从0开始的,如果vector容器的大小是n,则元素下标为0~n-1,这和数组的一样的.不一样的是,vector可以随时调整其大小. vector重要的方法有三个

C++ Primer(第五版)学习笔记_4_标准模板库string(1)

C++ Primer(第五版)学习笔记_4_标准模板库string(1) 1.创建string对象 创建一个空字符串,其长度为0 #include <iostream> #include <string> using namespace std; int main(int argc, char* argv[]) { string s; cout << s.length() << endl; return 0; } 运行结果: 0 2.给string对象赋值

C++ Primer(第五版)学习笔记_6_标准模板库_set集合容器

C++ Primer(第五版)学习笔记_6_标准模板库_set集合容器 Set集合容器实现了红黑树(Red-BlackTree)的平衡二叉检索树的数据结构,在插入元素时,它会自动调整二叉树的排序,把该元素放到适当的位置. (1)确保每个子树根节点的键值大于左子树所有节点的键值,而小于右子树所有节点的键值: (2)另外,还得确保根节点左子树的高度与右子树的高度相等.这样,二叉树的高度最小,从而检索速度最快. 平衡二叉检索树的检索使用中序遍历算法,检索效率高.默认情况下,将键值由小到大遍历. 对于s

C++ Primer(第五版)学习笔记_8_标准模板库_map映照容器

C++ Primer(第五版)学习笔记_8_标准模板库_map映照容器 map映照容器的元素数据是由一个键值和一个映照数据组成的,键值与映照数据之间具有一一映照的关系. map映照容器的数据结构也是采用红黑树来实现的. 1.map创建.元素插入和遍历访问 #include <iostream> #include <stdio.h> #include <vector> #include <map> #include <string> using n

C++ Primer(第五版)学习笔记_7_标准模板库_multiset多重集合容器

C++ Primer(第五版)学习笔记_7_标准模板库_multiset多重集合容器 多重集合容器multiset与set一样,也是使用红黑树来组织元素数据的,唯一不用的是,multiset允许重复的元素键值插入.其结构示意图如下: 1.multiset元素插入 #include <iostream> #include <stdio.h> #include <vector> #include <set> #include <string> usi