2.3.1 `for`迴圈
阿新 • • 發佈:2021-02-09
技術標籤:基礎學習 - C++c++
文章目錄
- *`for`迴圈*
- 1 `for`迴圈
- 2 表示式和語句
- 3 非表示式和語句
- 4 使用`for`迴圈訪問字串
- 5 遞增運算子(`++`)和遞減運算子(`--`)
- 6 副作用和順序點
- 7 字首表示式和字尾表示式
- 8 遞增/遞減運算子和指標
- 9 逗號運算子
- 10 基於範圍`for`迴圈(C++11)
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
和括號之間加一個空格,而省略函式名與括號之間的空格
對於其他控制語句(如if
和while
),處理方式與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
就有副作用,因為它將x
加1
- 從表示式到語句的轉變很容易,只要加分號即可
- 表示式:
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++確保副作用(將guests
加1
)在程式進入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;
}