码迷,mamicode.com
首页 > 编程语言 > 详细

C++第5章-循环和关系表达式

时间:2021-01-27 13:11:48      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:算术运算   std   string   tab   本质   就会   ali   下一步   字符串翻转   

第5章-循环和关系表达式

主要知识点:递增/递减运算符。

5.1 for循环

cout.setf(ios_base::boolalpha):通常,cout在显示bool值之前都会转换成int,此函数设置了一个标记,命令cout显示true或false,而非1或0。

递增/递减运算符

分为前缀(prefix)++i,后缀(postfix)i++

  • 前缀函数:先加后用。将值i加1,然后把i+1赋给i
  • 后缀函数:先用再加。把i复制一个副本,将副本的值加1,然后把副本的值i+1赋给i

从上面也可以看出,前缀的速度要比后缀高。后缀是比较难理解的,我们结合例子去解释:

int a = 20;
int b = 20;
cout << a << " " << b << endl;	// 20 20
cout << a++ << " " << ++b << endl;	// 20 21
cout << a << " " << b << endl;	//21 21

第4行其实可以先int c = a++;,便可以写成cout << c ...,也就是输出的是c的值,那么为什么c是20而不是21呢?
首先从运算的优先级上讲,递增运算高于赋值操作,所以a先复制一个副本并+1,但是什么时候把这个副本值赋给a呢?执行完顺序点!接下来引入副作用顺序点

  • 副作用(side effect):计算表达式时对某些东西,比如存在变量中的值进行了修改;
  • 顺序点(sequence point):程序执行过程中的一个点,在进入下一步之前要确保对所有的副作用进行了评估。C++中,分号就是一个顺序点,意味着程序处理下一条语句前,赋值运算符和递增/递减运算符的所有修改必须完成

所以对于int c = a++;来说,后缀操作只能执行到副本+1这一步,之后就要执行把值a赋给c这步,而此时a的值仍是20,所以c的值也是20。

程序在执行完第4行后,要对所有的副作用进行评估,便会把副本+1的结果赋给a,执行完第4行后,a的值更新为了21。也就是说:顺序点执行完成后,后缀运算才会把副本+1的值赋给本身

++b就没有上面那么麻烦了,执行完后就会直接更新b的值。

对于for循环的自增操作,比如for(int i=0; i<10; i++),我们可以看到括号里是用的分号隔开,这意味着每个表达式的末尾是个顺序点,所以执行完i++后,就完成了把副本+1的值赋给i的这个过程。

递增/递减和while循环

int guests = 0;
while(guests++ < 10)
	cout << guests << endl;

// output: 1,2,3...9,10

首先guests++ < 10的末尾是个顺序点,当guests=0是,执行完这个顺序点guests=1,传给下面的cout打印;直到guests=9,执行完顺序点后guests=10,此时便不符合guests++ < 10这个条件了,程序结束。

递增/递减和指针

这里主要涉及优先级问题,

  • 前缀递增/递减和*运算符的优先级相同,故整体上从右向左结合;
  • 后缀递增/递减优先级高于前缀,自然也高于*

pt->arr[0],可以总结如下:

常见类型 解释
*++pt; 先运算++pt,则pt->arr[1],然后取arr[1]的值
++*pt; 先取*ptarr[0]的值,然后++arr[0]
(*pt)++; 括号优先级最高,所以先取*ptarr[0]的值,然后arr[0]++
*pt++; 先执行pt++,结合上文此时pt->arr[0],然后取arr[0]的值,这句执行完后(顺序点)才有pt->arr[1]

语句块和变量

如果在一个语句块内声明一个变量,而外部语句块中也有一个这种变量,如下面所示:

int x = 10;
{
	cout << x << endl;	// 10
	int x = 100;
	cout << x << endl;	// 100
}
cout << x << endl;		// 10

从第4行声明新变量开始,到这个语句块结束,新变量将隐藏旧变量。结束后该变量再次可见。

逗号运算符和字符串翻转

#include <iostream>
int main() {
	using namespace std;
	cout << "Enter a word: " << endl;
	string word;
	cin >> word;

	char temp;
	int i, j;
	for (j=0, i=word.size()-1; j<i; --i, ++j) {
		temp = word[i];
		word[i] = word[j];
		word[j] = temp;
	}
	cout << word << "\nDone!";
	return 0;
}

执行效果:输入stressed,输出desserts。这个代码在string类有更好的实现方式,但现阶段可以先参考这个使用。

第10行中使用逗号同时操作ij,这是逗号运算符。允许把两条或更多语句放在C++语法只允许放一个表达式的地方。第10行的本质是把这两个合成为1个。

也可以这样写int j=0, i=word.size()-1;也能取得同样的效果,但这里的,就是列表分隔符,而不是逗号运算符。同样的还有第9行中,int i, j同时初始化ij,也是分隔列表中的变量。

逗号运算符有如下三个特点:

  • 逗号运算符是个顺序点。先确保第一个表达式,然后计算第二个表达式。i=20, j=2*i则有i=20, j=40
  • 逗号表达式的值是第二部分。比如上面的表达式的值就是40,转换成bool类型为true;
  • 逗号运算符的优先级是最低的。(cat=70), 240执行括号中的表达式,240没什么作用。

cat=(70, 240):这个表达式结合上面的第二点,cat=240

关系运算符

x+3 < y-2等价于(x+3) < (y-2)。这是因为关系运算符的优先级低于算术运算符

字符串的比较

C++第5章-循环和关系表达式

标签:算术运算   std   string   tab   本质   就会   ali   下一步   字符串翻转   

原文地址:https://www.cnblogs.com/rongyupan/p/14327988.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!