# C++ 基礎
###### tags: `C++` `基礎語法`
###### 最後修訂:2023/09/06
### 前言
-----------------------------------------------------------------
#### C++ 基礎
- **程式框架**
- C++程式是函數的集合,其中 main() 函數是程式的起始函數
- C++的框架
```cpp=
//引入C++所有宣告
#include <bits/stdc++.h>
//使用標準函數庫
using namespace std;
/* 多行註解範例
* main() 是 CPP 程式的起始函數
* int 表示函數執行完畢會回傳一個整數
*/
int main()
{
//你的主程式碼在這裡
//一般而言,傳回0,表示程式正常執行完畢
return 0;
}
```
- **C++資料的型別**
- C++ 是強型別語言,所以,宣告變數都要標註型別。
- 基礎型別
- bool 布林
- char 字元
- int 整數
- float 單精確度浮點數 (浮點數等同於數學中的實數)
- double 雙精確度浮點數
- 物件型別
- string 字串
- 修飾詞
- unsigned 無正負符號,這個會增加表示最大數字的範圍
- long long 長,這個會增加配置給變數的記憶體
- int:整數,4 bytes,可以表示 $-2^{31}$ ~ $2^{31}-1$
- unsigned int:無負數整數,4 bytes,可以 $0$ ~ $2^{32}-1$
- long long int:長整數,8 bytes,可以表示 $-2^{63}$ ~ $2^{63}-1$
- **常數與變數**
- 字元常數
- \b 倒退字元
- \t Tab字元
- \n 換行字元
- \r 歸位字元(歸位就是到每列的列首)
- 變數
- C/C++ 中所有變數都要宣告後才能使用。
- 對於基礎型別而言,宣告未初始化,其值為未知。
```cpp=
int n; //宣告一個整數變數,但未初始化,其值為未知。
int n = 0; ////宣告一個整數變數,並初始化為0。
```
- **C/C++ Input/Output**
- C 的 I/O 函數
- 輸出 printf
格式化字串可以用的符號
- %c 字元
- %d 10進位數字
- %o 8進位數字
- %x 16進位數字
- %f 浮點數
- %p 指標位址
- %s C的字串
- %e 科學記號
- 輸入 scanf
```cpp=
#include <bits/stdc++>
using namespace std;
int main()
{
int year = 2023;
double pi = 3.1415926;
printf("今年是 %d 年\n", year); //2023
printf("今年是 %10d 年\n", year); // 2023
printf("Pi是 %.2f\n", pi); //3.14
printf("Pi是 %10.4f\n", pi); // 3.1416
int n = 0;
scanf("%d", &n);
printf("%d \n", n);
return 0;
}
```
- **基礎語法**
- **判斷敘述(if)**
==範例:按照分數轉換成優、甲、乙、丙、丁== (範例中未檢核分數範圍)
```cpp=
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n = 0;
cin >> n;
if (n >= 90)
cout << "優" << endl;
else if (n >= 80)
cout << "甲" << endl;
else if (n >= 70)
cout << "乙" << endl;
else if (n >= 60)
cout << "丙" << endl;
else
cout << "丁" << endl;
return 0;
}
```
- **重覆敘述(for)**
==範例:列出字串中每個字元的ASCII碼==
```cpp=
//C++ 是強型別語言,所有變數均須指定其資料型別
#include <bits/stdc++.h>
using namespace std;
int main()
{
string s = "Today is a good day.";
for (int i=0; i<s.length(); i++)
{
cout << s[i] << " = " << (int)s[i] << endl;
}
return 0;
}
```
- **重覆敘述(while)**
==範例:利用輾轉相除法,求給定兩正整數之最大公因數==
```cpp=
#include <bits/stdc++.h>
using namespace std;
int main()
{
int a = 28, b= 30;
int r = a % b;
while (r != 0)
{
a = b;
b = r;
r = a % b;
}
cout << "gcd=" << b << endl;
return 0;
}
```
- **重覆敘述(do...while)**
do..while 敘述類似於 while 敘述,差別在 do...while 敘述,迭代部分至少執行1次,while 則可能為0次。
==範例:猜猜看下面的範例是 1+2+...+9 或 1+2+...+10 ?==
```cpp=
#include <bits/stdc++.h>
using namespace std;
int main()
{
int s=0, i=1;
do
{
s += i;
i++;
} while (i < 10)
cout << "s=" << s << endl;
return 0;
}
- **陣列與重覆敘述**
==範例:計算整數陣列元素的總和及平均數==
```cpp=
#include <bits/stdc++.h>
#include <cstdlib>
using namespace std;
int main()
{
int len = 10;
int n[len] = {15, 20, 85, 42, 87, 14, 8, 6, 17, 22};
int sum = 0;
for (int i=0; i<len; i++)
{
sum = sum + n[i];
}
cout << sum << endl;
cout << sum*1.0/len << endl;
//用 C 的 printf 顯示小數點以下2位
printf("%.2f", sum*1.0/len);
return 0;
}
```
- **資料型態轉換**
- **字串與數值資料互轉** C++11 開始支援
```cpp=
#include <bits/stdc++.h>
using namespace std;
int main(int argc, char **argv)
{
//字串轉整數
string s1 = "456";
int num1 = stoi(s1);
cout << num1 << endl;
//字串轉浮點數
string s2 = "3.14159";
double num2 = stod(s2);
cout << num2 << endl;
//轉換函數還有
// stol 轉換為 long int
// stoul 轉換為 unsinged long int
// stoll 轉換為 long long int
// stoull 轉換為 unsinged long long int
// stof 轉換為 float
// stold 轉換為 long float
//整數轉字串
int num3 = 789;
string s3 = to_string(num3);
cout << s3 << endl;
//浮點數轉字串
double num4 = 1.618;
string s4 = to_string(num4);
cout << s4 << endl;
return 0;
}
```
- **字串與數值資料互轉** C的字串
```cpp=
#include <bits/stdc++.h>
using namespace std;
int main() {
//C 的字串,是字元的集合,最後一個字元是 '\0'
char str1[80] = "123"; //實際上是 4 個字元,最後一個是 '\0'
// 用 strlen() 取得字串長度
cout << strlen(str1) << endl; //3
//字串相加
char str3[80] = "abc";
strcat(str3, "def");
cout << str3 << endl; //abcdef
// 字串轉整數
int n = atoi(str);
cout << n << endl; //123
// 字串轉浮點數
char str1[80] = "1.68";
double d = atof(str1);
cout << d << endl;
// 整數轉字串
int n1 = 123;
char str2[80]; //字串長度要夠,否則就會溢位
sprintf(str2, "%d", n1);
cout << str2 << endl;
// 浮點數轉字串
double n2 = 3.14;
sprintf(str2, "%f", n2);
cout << str2 << endl;
return 0;
}
```
- **C 與 C++ 字串互轉**
```cpp=
#include <bits/stdc++.h>
using namespace std;
int main()
{
// C 的字串,是字元的集合,最後一個字元是 '\0'
char str1[80] = "That is a good game.";
// C++ 的字串,封裝成物件,也是字元的集合。
string str2 = "Let's play the game.";
// C 字串轉換為 C++ 字串
string str3 = string(str1);
// C++ 字串轉換為 C 字串
// 轉換為「指向常數字元」的指標,也就是指向的字元是不能改變的
const char *str4 = str2.c_str();
// C 和 C++ 字串相加
char str5[80] = "Today ";
char str6[80] = "is ";
string ss = "a good day.";
// C 字串無法直接相加,因此下面的寫法是錯的
// string str8 = str5 + str6 + ss;
string str8 = str5 + ss + str6; //這樣可以
string str9 = string(str5) + str6 + ss; //這樣也可以
string str10 = ss + str5 + str6; //這樣當然也可以
//這樣行不行呢? 你先猜猜看,然後再試試看,印證你的想法
string str11 = str5 + string(str6) + ss;
return 0;
}
```
### 進階閱讀資料
- C++與演算法
- https://al.orangeapple.co/index.html
- C++ STL (標準函式庫)
- https://hackmd.io/@johnaxer/cpp_stl
- 演算法 Algorithm
- https://hackmd.io/@johnaxer/algorithm