C++第5章-循環和關係表達式

第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)。這是因爲關係運算符的優先級低於算術運算符

字符串的比較

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章