說明
看《C++ Primer Plus》時整理的學習筆記,部分內容完全摘抄自《C++ Primer Plus》(第6版)中文版,Stephen Prata 著,張海龍 袁國忠譯,人民郵電出版社,只做學習記錄用途,
目錄- 說明
- 5.1 for 回圈
- 5.1.1 for 回圈格式
- 5.1.2 遞增運算子(++)和遞減運算子(--)
- 5.1.3 遞增/遞減運算子和解除參考運算子
- 5.1.4 組合賦值運算子
- 5.1.5 逗號運算子
- 5.1.6 關系運算式
- 5.1.7 字串的比較
- 5.2 while 回圈
- 5.2.1 while 回圈格式
- 5.2.2 撰寫延時回圈
- 5.2.3 型別別名
- 5.3 do while 回圈
- 5.4 基于范圍的 for 回圈(C++11)
- 5.5 嵌套回圈和二維陣列
- 5.5.1 初始化二維陣列
- 5.5.2 使用 new 創建動態二維陣列
- 5.5.3 嵌套回圈
本章介紹回圈和關系運算式,
5.1 for 回圈
for回圈是入口條件回圈,也就是在每輪回圈之前,都將計算測驗運算式的值,
5.1.1 for 回圈格式
for回圈的基本格式如下:
for (initialization; test-expression; update-expression)
{
statements;
}
initialization在回圈開始時被執行,且整個回圈程序中只被執行一次,它可以使用任意運算式,通常在這一部分中宣告并初始化變數,但這種變數只存在于for陳述句中,當程式離開回圈后,這種變數將消失,(對于部分老式實作,initialization部分內宣告的變數將被視為在回圈之前宣告的,因此在回圈結束后仍可使用,)
test-expression(測驗運算式)決定回圈體是否被執行,它也可以使用任意運算式,C++ 將把結果強制轉換為 bool 型別,若值為false,將導致回圈結束,若值為true,回圈將繼續進行,這一部分通常使用關系運算式,當省略測驗運算式時,測驗條件默認為true,
update-expression(更新運算式)在每輪回圈結束時執行,它也可以使用任意運算式,但通常被用來對跟蹤回圈輪次的變數的值進行增減,
//以下回圈將一直運行,除非在statements里跳出
for (;;)
{
statements;
}
5.1.2 遞增運算子(++)和遞減運算子(--)
遞增運算子(++)和遞減運算子(--)執行兩種極其常見的回圈操作:將回圈計數加 1 或減 1,這兩個運算子都有兩種變體:前綴版本位于運算元前面,如++x;后綴版本位于運算元后面,如x++;兩個版本對運算元的影響是一樣的,但是影響的時間不同,后綴版本表示先使用運算元的值,然后再將運算元的值加 1;前綴版本表示先將運算元的值加 1,然后再使用運算元的值,
//前綴版本,全部執行完畢后x=6, y=6.
int x = 5;
int y = ++x;
//后綴版本,全部執行完畢后x=6, y=5.
int x = 5;
int y = x++;
此外,前綴格式與后綴格式的執行速度會有細微的差別:后綴版本首先會復制一個副本,將其加 1,然后將復制的副本回傳,而前綴版本不會進行額外的復制操作,對于內置型別而言,這種差異微乎其微,但對于用戶定義的型別,前綴版本的效率比后綴版本高,
5.1.3 遞增/遞減運算子和解除參考運算子
將遞增(++)/遞減(--)運算子和解除參考運算子(*)同時用于指標時,將依據運算子的位置以及優先級來進行運算,前綴遞增、前綴遞減、解除參考運算子的優先級相同,都以從右到左的方式進行結合;后綴遞增、后綴遞減的優先級相同,但比前綴運算子的優先級高,且都以從左到右的方式進行結合,
//執行完畢后x=32.8, pt指向arr[1], arr元素無變化
double arr[3] = {21.1, 32.8, 23.4};
double *pt = arr;
double x = *++pt;
//執行完畢后x=22.1, pt指向arr[0], arr元素無變化
double arr[3] = {21.1, 32.8, 23.4};
double *pt = arr;
double x = ++*pt;
//執行完畢后x=21.1, pt指向arr[1], arr元素無變化
double arr[3] = {21.1, 32.8, 23.4};
double *pt = arr;
double x = *pt++;
//執行完畢后x=21.1, pt指向arr[0], arr[0]=22.1
double arr[3] = {21.1, 32.8, 23.4};
double *pt = arr;
double x = (*pt)++;
5.1.4 組合賦值運算子
每個算術運算子都有其對應的組合賦值運算子:
| 運算元 | 作用(L為左運算元,R為右運算元) |
|---|---|
+= |
將L+R賦給L |
-= |
將L-R賦給L |
*= |
將L*R賦給L |
/= |
將L/R賦給L |
%= |
將L%R賦給L |
5.1.5 逗號運算子
用兩個花括號可以構造一條復合陳述句(代碼塊),代碼塊被視為一條陳述句,這種做法允許把兩潭訓更多陳述句放到按 C++ 語法只能放一條陳述句的地方,逗號運算子對運算式完成同樣的任務,可以將兩個或多個運算式合并為一個,但在宣告陳述句中,逗號只做為分隔符,而不是運算子,逗號運算子是一個順序點,它確保先計算第一個運算式,再計算第二個運算式,C++ 規定,逗號運算式的值是第二部分的值,在所有運算子中,逗號運算子的優先級是最低的,
//宣告陳述句中,逗號用做分隔符
int i = 0, j = 0;
//逗號用做運算子
i = 0, j = 0;
//逗號運算子的優先級最低,此時i=1
i = 1,2,3,4,5,6;
//逗號運算式的值,此時i=6
i = (1,2,3,4,5,6);
5.1.6 關系運算式
C++ 提供了 6 種關系運算子來對數字進行比較,由于字符用其 ASCII 碼表示,因此也可將這些運算子用于字符,不能將它們用于 C-風格字串,但可用于 string類物件,對所有關系運算式,若比較結果為真,則其值為true,否則為false,關系運算子的優先級比算術運算子低,
| 運算子 | 含義 |
|---|---|
< |
小于 |
<= |
小于或等于 |
== |
等于 |
> |
大于 |
>= |
大于或等于 |
!= |
不等于 |
5.1.7 字串的比較
C-風格字串應使用strcmp()函式來比較,該函式接受兩個字串地址作為引數,引數可以是指標、字串常量或字符陣列名,如果兩個字串相同,該函式將回傳零;如果第一個字串按字母順序排在第二個字串之前,該函式將回傳一個負值;如果第一個字串按字母順序排在第二個字串之后,該函式將回傳一個正值,
//比較C-風格字串是否相等
strcmp(str1,str2) == 0
//比較C-風格字串是否不等
strcmp(str1,str2) != 0
strcmp(str1,str2)
//比較C-風格字串str1是否在str2前面
strcmp(str1,str2) < 0
//比較C-風格字串str1是否在str2后面
strcmp(str1,str2) > 0
string類函式多載了關系運算子,因此其物件可直接使用關系運算子進行比較,
5.2 while 回圈
while回圈也是入口條件回圈,也就是在每輪回圈之前,都將計算測驗運算式的值,
5.2.1 while 回圈格式
while回圈的基本格式如下:
while (test-expression)
{
statements;
}
它可以轉換為for回圈:
for (;test-expression;)
{
statements;
}
同樣地,for回圈基本格式也可以轉換為while回圈:
initialization;
while (test-expression)
{
statements;
update-expression;
}
通常,使用for回圈來為回圈計數,在無法事先知道回圈將執行的次數時,一般使用while回圈,設計回圈時,有以下幾條指導原則:
- 指定回圈終止條件,
- 在首次測驗之前初始化條件,
- 在條件被再次測驗之前更新條件,
5.2.2 撰寫延時回圈
頭檔案ctime定義了一個符號常量CLOCKS_PER_SEC,該常量等于每秒鐘包含的系統時間單位數,將系統時間除以這個值,可以得到秒數,或者將秒數乘以CLOCKS_PER_SEC,可以得到以系統時間單位為單位的時間,以下程式使用了頭檔案ctime來創建延時 5 秒的回圈:
#include <ctime>
int main()
{
//接下來的4行總耗時約5秒
float secs = 5;
clock_t delay = secs * CLOCKS_PER_SEC;
clock_t start = clock();
while (clock() - start < delay);
return 0;
}
5.2.3 型別別名
C++ 為型別建立別名的方式有兩種,一種是使用前處理器:
//使用前處理器創建別名(通用格式)
#define aliasName typeName
//使用前處理器創建別名(例子)
#define BYTE char
#define FLOAT_POINTER float *
第二種方法是使用關鍵字typedef來創建別名:
//使用關鍵字typedef來創建別名(通用格式)
typedef typeName aliasName;
//使用關鍵字typedef來創建別名(例子)
typedef char BYTE;
typedef float * FLOAT_POINTER;
typedef不會創建新型別,只是為已有型別建立一個新名稱,相比于使用#define,它能處理更復雜的型別別名,因此,使用typedef是一種更佳的選擇,
5.3 do while 回圈
do while回圈是出口條件回圈,這意味著這種回圈將首先執行回圈體,然后再判定測驗運算式,決定是否應繼續執行回圈,這樣的回圈通常至少執行一次,do while回圈的基本格式如下:
do
{
statements;
} while (test-expression)
5.4 基于范圍的 for 回圈(C++11)
C++11 新增了一種回圈:基于范圍的for回圈,這簡化了一種常見的回圈任務:對陣列或容器類的每個元素執行相同的操作:
//回圈遍歷陣列的值
double prices[5] = {4.99, 10.99, 6.87, 7.99, 8.49};
for (double x : prices)
{
std::cout << x << std::endl;
}
//回圈遍歷并修改陣列的值(參考變數)
double prices[5] = {4.99, 10.99, 6.87, 7.99, 8.49};
for (double &x : prices)
{
x = x * 0.80;
}
//基于范圍的for回圈和初始化串列
for (double x : {3, 5, 2, 8, 6})
{
std::cout << x << std::endl;
}
這種回圈多用于模板容器類,
5.5 嵌套回圈和二維陣列
5.5.1 初始化二維陣列
C++ 沒有提供二維陣列的型別,但用戶可以創建每個元素本身都是陣列的陣列,二維陣列在概念上是二維的,但在記憶體中是連續存放的,在 C++ 中,二維陣列是按行存盤的,也就是先存放a[0]行,再存放a[1]行,接著存放a[2]行,以此類推直到元素放完,每行中元素也是依次存放,二維陣列的初始化與一維陣列類似:
//初始化方式一:全元素初始化
int a[4][5] =
{
{96, 100, 87, 101, 105},
{96, 98, 91, 107, 104},
{96, 101, 93, 108, 107},
{96, 103, 95, 109, 108}
};
//初始化方式二:全元素初始化時,可省略內部括號
int a[4][5] =
{
96, 100, 87, 101, 105,
96, 98, 91, 107, 104,
96, 101, 93, 108, 107,
96, 103, 95, 109, 108
};
//初始化方式三:全元素初始化時,第一維大小可省略
int a[][5] =
{
96, 100, 87, 101, 105,
96, 98, 91, 107, 104,
96, 101, 93, 108, 107,
96, 103, 95, 109, 108
};
//初始化方式四:全元素初始化為0
int a[4][5] = {0};
//初始化方式五:初始化部分元素,剩余元素默認為0
int a[4][5] =
{
{96},
{96, 98, 91},
{96, 101},
{96, 103, 95, 109}
};
//初始化方式六:省略第一維大小且只初始化部分元素
int a[][5] =
{
{},
{96, 98, 91},
{96, 101},
{96, 103, 95, 109}
};
5.5.2 使用 new 創建動態二維陣列
動態二維陣列的創建以及釋放如下所示:
//分配動態二維陣列記憶體的通用格式
typeName ** pointer_name = new typeName *[rowSize];
for (int i = 0; i < rowSize; i++)
{
pointer_name[i] = new typeName[columnSize];
}
//釋放動態二維陣列記憶體
for (int i = 0; i < rowSize; i++)
delete[] pointer_name[i];
delete[] pointer_name;
在 C++11 中,使用 new 創建動態二維陣列的同時還可對其進行初始化,采用動態一維陣列的初始化方法,在for回圈中對動態二維陣列的每行進行初始化即可,
5.5.3 嵌套回圈
嵌套回圈是回圈中的回圈,外層回圈以及內層回圈可以是for、while、do while中的任意一種,由于 CPU 使用了分支預測技術,將大回圈做為內層回圈,小回圈做為外層回圈可以提升嵌套回圈的運行效率,因此嵌套回圈一般將回圈次數最多回圈的放在最內層,由于二維陣列是按行存盤的,使用嵌套回圈遍歷二維陣列時,按行遍歷可提升運行效率,因此當嵌套回圈僅用于遍歷二維陣列時,一般將列回圈放在內層[測驗例],
本文作者:木三百川
本文鏈接:https://www.cnblogs.com/young520/p/16633560.html
著作權宣告:本文系博主原創文章,著作權歸作者所有,商業轉載請聯系作者獲得授權,非商業轉載請附上出處鏈接,遵循署名-非商業性使用-相同方式共享 4.0 國際版 (CC BY-NC-SA 4.0)著作權協議,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/502958.html
標籤:C++
