c++ primer(第五版)笔记 第五章 语句

31 篇文章 0 订阅
#include<iostream>
#include<string>
#include<stdexcept>

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

class Test
{
public:
	Test(int tp = 0):ti(tp)
	{
		cout << "new!" << ti << endl;
	}
	// goto 跳到类对象定义前,会销毁对象
	~Test()
	{
		cout <<  "over!" << endl;
	}
	
	int ti;
};

int main()
{
	/* 
	if 语句的条件,可以使一个表达式,也可以是变量,只要该值要能转换为 bool
		if else 结构:
			在c++ 中,else 与同层结构中,最近的,未匹配的 if 匹配
	*/
	int flag1 = 0, flag2 = 0, flag3 = 1, flag4 = 1, flag5 = 0, n = 0;
	if(int f {1})
		cout << f<< endl;
		if(2)
			;
	else	//else 和 if(2) 匹配
		;

	/* 
	switch 结构
		case 标签必须是整形常量表达式,且任何2个标签不可重复
		内部变量定义
			除内部定义的块外,所有case 语句都是同一个作用域
			c++ 不允许跳过变量的初始化语句直接跳往该变量作用域中的另一个位置
			
	*/		
	int si = 1;
	//strTemp,a,b对于所有case都是可见的,c 的作用域仅限语句块内
	switch(si)
	{
		case 1:
			// string strTemp;
			// int a = 0;
			int b;
			{
				// int c = 5;
			}
			break;
		case 2:
			// if(strTemp.empty())	//虽然 strTemp 可见,但跳过了string 类初始化 当一个POD对象有初始化式或者一个类具有显式构造函数时,表明程序员希望初始化这个对象。如果程序的执行有任何可能会导致该初始化被跳过,程序很可能进入程序员意料之外的某个不正确状态。所以,标准明确禁止了这种行为。
				// ;
			// a = 3;	//同样跳过了初始化
			b = 4;	//警告:使用未初始化的变量
			// c = 6;	//c 不可见
		test2 : cout << "i am test2 in switch" << endl;	//从 switch 外跳入
			if(!flag3)	//执行一次
			{
				flag3 = 1;
				goto test4;	//跳出 switch
			}
			break;
	}
	
	/*
	while 循环
		while (condition)
			statement;
		只要 condition 为真,就执行 statement, 记得改变循环控制变量的值,小心死循环
	*/
	/*
	传统 for 循环
		for(init-statement; condition; init-statement)
			statement;
	循环开始执行一次 init-statement,初始化控制变量,可以定义多个对象,但只有一条语句,所以类型要一致
	然后判断 condition,如果 condition 为假,跳出循环,如果为真,执行 statement
	最后执行 expression 改变控制变量
	init-statement, init-statement,可以省略,但分号一定要有
	*/
	for(; n != 10; ++n )		//测试 goto 时,如果此处声明并初始化 n,编译报错,因为goto test5,跳过了n 的初始化,同57行,如果只声明不初始化,可以编译通过但是此时 n 的值是未定义的
	{
		cout <<"for :" << n << endl;
		if(n == 3)
		{
			
			if(flag4)
			{
				flag4 = 0;
				goto test4;	//跳出 for 
			}
			test5 : cout << "i am test5 in for" << endl; //从for 外部跳入后继续正常循环
		}
	}
	/*
	范围 for 循环
		for(declaration : expression)
			statement;
	expression 表示一组序列,如数组,各种标准库容器等,这些类型都拥有返回迭代器的 begin 和 end
	declaration 表示一个变量,容器中的每一个元素都可以转换成该变量的类型,通常使用 auto 类型说明符,如果需要改变其值,必须声明为引用类型
	原理类似
		for (auto beg = string.begin(), en = string.end(); beg != en; ++beg)
			statement;
	*/
	/*
	do while 循环
		do
			statement;
		while(condition);
	先执行一次语句,再判断条件,无论条件如何,至少执行一次
	condition 的控制变量必须定义在循环体外面
	*/
	
	//if while for switch 都可以在循环体作用域内定义变量
	//do while 即不可以在 do 块中定义,也不能再 while 条件中定义,2个不同的作用域
	
	/*
	break 语句 只能用于终止离他最近的循环体(for, while, do while)或switch结构,然后程序从这些结构后的第一条语句继续执行
	*/
	
	/*
	continue 语句 只能用于终止离他最近的循环体中的当前循环(for, while, do while),然后程序立即执行下次循环
	*/
	
	/*
	goto 语句 无条件从 goto 语句跳到同一个函数的另一条语句
	label 是独立于变量和其他标示符的名字,可以和程序里的其他标示符共存
		label : statement;
		...
		goto label;
	goto 可以在同一个函数内跳跃,注意跳跃变量对象定义时的区别
	*/
	/*
	下面的测试 goto 指令 flag 开头的变量是为防止无限循环
	通过 Test 类的构造和析构,加深了解
	实践中,尽量避免使用 goto 
	*/
	test4 : cout << "i am test4 out" << endl;
	Test t(5);
	test1 : cout << "i am test1!"<< endl;
	if(!flag1)	//执行一次
	{
		flag1 = 1;
		flag3 = 0;
		goto test2;
	}
	cout << "---------------------------" << endl;
	if(!flag2)//执行一次
	{
		flag2 = 1;
		goto test1;
	}
	Test t2;
	cout << "---------------------------" << endl;
	if(!flag5)//执行一次
	{
		flag5 = 1;
		flag4 = 0;
		goto test5;
	}
	// goto test3;					//这里会跳过变量定义,不允许
	// int goo  = 1;
	// test3 : cout << "come here!"<<endl;
	
	/*
	try 语句块和异常处理
		throw 表达式(throw expression)表示遇到了无法处理的信息,throw 引发了异常
			throw expression;
			其中 expression 的类型就是异常的类型
			
		try 语句块(try block)处理异常,以 try 关键字开始,并以一个或多个 catch 子句(catch clause)结束
			try
			{
				...
				引发异常
				throw expression;
				...
			}
			catch(expression同类型对象 err)	
			{
				处理异常
				...
			}
			关于 try 嵌套,搜索 catch的顺序,首先抛出异常的函数,找不到的话,上一层调用函数,逐层递回,最终没找到,转到 terminate 标准库函数,其行为和系统有关,一般是非正常退出程序
			
			
		异常类(exception class) 用于 throw 表达式和想关 catch 之间传递异常的具体信息

		异常安全(exception safe)能够在异常中断了正常流程的情况下,正确执行“清理”工作(对象失效或未完成的状态,资源未释放等等)的程序
	*/
	int ei1 = 0, ei2 = 0;
	while(cin >> ei1 >> ei2)
	{
		if(!ei2)
		{
			try
			{
				throw runtime_error("ei2 is 0");
			}
			catch(runtime_error err)
			{
				cout << err.what() << endl;
				cout << "do you want try it again?(y/n)" << endl;
				char ch;
				cin >> ch;
				if(!ch || ch=='n' || ch=='N')
					break;
			}
		}
		else
			cout << ei1 / ei2 << endl;
	}
	
	return 0;
}
/* 程序输出
1
for :0
for :1
for :2
for :3
i am test4 out
new!5
i am test1!
over!
i am test2 in switch
i am test4 out
new!5
i am test1!
---------------------------
i am test1!
---------------------------
new!0
---------------------------
over!
over!
i am test5 in for
for :4
for :5
for :6
for :7
for :8
for :9
i am test4 out
new!5
i am test1!
---------------------------
new!0
---------------------------
over!
over!
*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值