1. 程式人生 > 其它 >2.3.1 `for`迴圈

2.3.1 `for`迴圈

技術標籤:基礎學習 - C++c++

大綱目錄

文章目錄


for迴圈

1 for迴圈

#include <iostream>

int main()
{
	using namespace std;

	int i;

	for (i = 0; i < 5; i++) 
	{
		cout <<
"i = " << i << endl; } return 0; }

在這裡插入圖片描述


#include <iostream>

int main()
{
	using namespace std;

	cout << "請輸入開始元素:";
	int limit;
	cin >> limit;

	int i;

	for (i = limit; i; i--)  // 值為0的表示式被轉換為bool值的false,導致迴圈結束
	{
		cout << "i = " <<
i << endl; } cout << "i 現在是:" << i << endl; return 0; }

在這裡插入圖片描述
for語句看上去有些像函式呼叫,因為它使用一個後面跟一對括號的名稱

c++常用分辨for的方式是:for和括號之間加一個空格,而省略函式名與括號之間的空格

對於其他控制語句(如ifwhile),處理方式與for相似


#include <iostream>

const int ArSize = 16;

int main()
{
	long long factorials[ArSize]
; factorials[0] = factorials[1] = 1LL; // 0的階乘和1的階乘都是1 for (int i = 2; i < ArSize; i++) { factorials[i] = i * factorials[i - 1]; } for (int i = 0; i < ArSize; i++) { std::cout << i << "! = " << factorials[i] << std::endl; } return 0; }

在這裡插入圖片描述


for (;;)
{

}

可以省略表示式,以上是個死迴圈

2 表示式和語句

#include <iostream>

int main()
{
	using namespace std;

	int x;

	cout << "表示式(x = 100)的意思是:" << (x = 100) << endl;
	cout << "現在 x = " << x << endl;
	cout << "表示式(x < 3)的意思是:" << (x < 3) << endl;
	cout << "表示式(x > 3)的意思是:" << (x > 3) << endl;
	
	// 通常,cout在顯示bool之前將它們轉換成int
	// 當用cout輸出流的時候,將bool型別的值以true或flase表示,而不是1或0
	cout.setf(ios_base::boolalpha);

	cout << "表示式(x < 3)的意思是:" << (x < 3) << endl;
	cout << "表示式(x > 3)的意思是:" << (x > 3) << endl;

	return 0;
}

在這裡插入圖片描述

  • 為判定表示式x = 100,c++必須將100賦給x。當判定表示式的值這種操作改變了記憶體中資料的值時,我們說表示式有副作用(side effect)。
  • 因此,判定賦值表示式會帶來副作用,即修改被賦值者的值
  • 有可能把賦值看做預期的效果,但從c++的構造方式這個角度來看,判定表示式才是主要作用
  • 並不是所有的表示式都有副作用
  • 例如:判定x + 15將計算出一個新的值,但不會修改x的值。
  • 然而,判定++x + 15就有副作用,因為它將x1

  • 從表示式到語句的轉變很容易,只要加分號即可
  • 表示式:age = 100
  • 語句:age = 100; 這是一條表示式語句
  • 只要加上分號,所有的表示式都可以成為語句,但不一定有程式設計意義。
#include <iostream>

int main()
{
	using namespace std;

	int x = 0;

	x + 6;	// 有效的語句,但是沒有用

	cout << "x = " << x << endl;

	return 0;
}

在這裡插入圖片描述
編譯器允許這樣的語句,但它沒有完成任何有用的工作。

程式僅僅是計算和,而沒有使用得到的結果,然後便進入下一條語句(智慧編譯器甚至可能跳過這條語句)

3 非表示式和語句

  • int toad並不是一個表示式,因為它沒有值

下面的程式碼是非法的

eggs = int toad * 1000;	// 非法的,不是一個表示式
cin >> int toda;	// 不能將宣告與cin結合起來

// 不能把for迴圈賦給變數,for迴圈不是表示式,因為沒有值
int fx = for (i = 0; i < 4; i++)
	cout >> i;	// 不可以

4 使用for迴圈訪問字串

#include <iostream>
#include <string>

int main()
{
	using namespace std;

	cout << "輸入一個字串:";
	string word;
	getline(cin, word);

	// string 類的size() 獲得字串的字元數
	for (int i = word.size() - 1; i >= 0; i--)
	{
		cout << word[i];
	}

	return 0;
}

在這裡插入圖片描述

5 遞增運算子(++)和遞減運算子(--

#include <iostream>
#include <string>

int main()
{
	using namespace std;

	int a = 20;
	int b = 20;

	cout << "a   = " << a << endl;
	cout << "a++ = " << a++ << endl;
	cout << "a   = " << a << endl << endl;

	cout << "a   = " << a << endl;
	cout << "a-- = " << a-- << endl;
	cout << "a   = " << a << endl << endl;

	cout << "b   = " << b << endl;
	cout << "++b = " << ++b << endl;
	cout << "b   = " << b << endl << endl;

	cout << "b   = " << b << endl;
	cout << "--b = " << --b << endl;
	cout << "b   = " << b << endl << endl;

	return 0;
}

在這裡插入圖片描述

6 副作用和順序點

  • 副作用:計算表示式時對某些東西(如儲存在變數中的值)進行的修改
  • 順序點:程式執行過程中的一個點,在這裡,進入下一步之前將全確保對所有的副作用都進行了評估
  • c++中,語句中的分號就是一個順序點,這意味著程式處理下一條語句之前,賦值運算子、遞增運算子和遞減運算子執行的所有修改都必須完成
#include <iostream>

int main()
{
	using namespace std;

	int guests = 0;

	while (guests++ < 10)
	{
		cout << guests << endl;
	}
	
	return 0;
}

在這裡插入圖片描述

  • 表示式guests++ < 10是一個完整的表示式,因為它是一個while迴圈的測試條件,因此該表示式的末尾是一個順序點。所以c++確保副作用(將guests1)在程式進入cout之前完成。然而。通過使用字尾格式,可確保將guests同10進行比較後將其值加1
y = (4 + x++) + (6 + x++);
  • 表示式4 + x++不是一個完整表示式,因此,c++不保證x的值在計運算元表示式4 + x++後立刻增加1
  • 在這個例子中,整個賦值語句是一個完整表示式,而分號標識了順序點,因此c++只保證程式執行到下一條語句之前,x的值將被遞增兩次。
  • c++沒有規定是在計算每個子表示式之後將x的值遞增,還是在整個表示式計算完畢之後才將x的值遞增

7 字首表示式和字尾表示式

字首表示式的效率要高於字尾表示式

8 遞增/遞減運算子和指標

  • 字首遞增、字首遞減和解除引用運算子的優先順序相同,以右到左的方式進行結合
  • 字尾遞增和字尾遞減的優先順序相同,但比字首運算子的優先順序高,這個運算子以從左到右的方式進行結合
  • 字首表示式*++pt的含義:先將++應用於pt,然後將*應用於被遞增後的pt
#include <iostream>

int main()
{
	using namespace std;

	double arr[5] = { 1.1, 2.2, 3.3, 4.4, 5.5 };

	double* pt = arr;

	cout << "*arr: " << *arr << endl;		// arr[0]
	cout << "*(++pt): " << *(++pt) << endl;	// arr[1]

	double x = *++pt;	// arr[2]

	cout << "x: " << x << endl;
	cout << "++*pt: " << ++ * pt << endl;	// arr[2] + 1
	cout << "(*pt)++: " << (*pt)++ << endl;	// arr[2] + 1
	x = *pt++;	// x 是 arr[2] pt 變成 arr[3]
	// 字尾運算子++的優先順序更高,這意味著將運算子用於pt
	// 而不是*pt,因此對指標遞增
	// 然而後綴運算子意味著將對其原來的地址(&arr[2])
	// 而不是新的地址解除引用,因此*pt++的值為arr[2]
	// 但該語句執行完畢之後,pt的值將為arr[3]的地址
	cout << "x = *pt++: " << x << endl;
	cout << "*pt: " << *pt << endl;

	return 0;
}

在這裡插入圖片描述

9 逗號運算子

#include <iostream>
#include <string>

int main()
{
	using namespace std;

	cout << "請輸入單詞:";
	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 << endl;

	return 0;
}

在這裡插入圖片描述

  • int j = 0, i = word.size() - 1,在這種情況下,逗號只是一個列表分隔符,而不是逗號運算子
  • i =20, j = 2* i i的值是20,j的值是40
  • 逗號運算子的優先順序是最低的
  • cata = 17, 240;被解釋為:(cata = 17), 240;也就是說cata被設定為17 ,240不起作用
  • cata = (17, 240); cata被設定為240

10 基於範圍for迴圈(C++11)

#include <iostream>

int main()
{
	using namespace std;

	double prices[5] = { 4.99, 10.9, 43.3, 2.6, 77.1 };

	for (double x : prices)
	{
		cout << x << endl;
	}

	cout << endl;

	for (auto& x : prices)
	{
		cout << x << endl;
	}

	cout << endl;

	for (double& x : prices)
	{
		x *= 0.80;
		cout << x << endl;
	}

	return 0;
}

在這裡插入圖片描述


#include <iostream>

int main()
{

	for (int x : { 3, 5, 2, 8, 6})
	{

		std::cout << x << std::endl;
	}

	return 0;
}

在這裡插入圖片描述