---
tags: books
---
# 基本程式架構
```cpp=
#include <iostream>
using namespace std;
int main(){
cout<<"hello, world"<<endl;
return 0;
}
```
### 標頭檔
```cpp=
#include <iostream>
```
標頭檔,又稱標準函式庫,裡面包含著許多函式以使用
舉例而言,若想用cin, cout指令輸入輸出的話需要先引入iostream函式庫
而想用abs(),sqrt()或ceil()等數學函式則需要#include <cmath>
想使用rand()函式需要#include <cstdlib>
### 標準命名空間 std
```cpp=
using namespace std;
```
在使用cin, cout, endl等指令的時候,常常前面都需要加std::很麻煩
這時就可以在主函式前面先加這行,也就是「使用標準命名空間std」 (std是standard的縮寫)
這樣底下就不需要再加一堆std了
至於為什麼要先定義命名空間,原因是若是在大型程式可能會出現有好幾個不同檔案且同一個函式的用法不一定相同,這時候就需要用定義類別的方式去做區分
**(未來學到類別的時候可能會比較能理解)**
### 主函式
```cpp=
int main(){
return 0; //在C++裡面可加可不加
}
```
程式主要執行的部分,return 0表示函式執行結束且回傳一個值為0,用以表示程式正常結束,在C++中不需要加return 0 (在編譯時會在我們看不到的地方自動加上去)
### 輸入輸出,前後置遞增運算子及換行
```cpp=
cin>>n; //假設鍵盤輸入為5
cout<<n; //5
cout<<++n; //6
cout<<n++; //6
//輸出完後此時n為7
cout<<"hello, world"<<endl;
```
cin表示輸入(鍵盤),cout表示輸出(控制台(console))
上課時講的前置遞增及後置遞增,表示處理變數以及做其他事的先後順序
第3行可看到n在遞增完後進行輸出,顯示結果為6
第4行則是先輸出n,再進行遞增的動作,先輸出6,之後n變成7
endl 跟 '\n' 跟"\n"都同樣可表示換行
不過在競賽時,若輸出結果非常多,使用'\n'比起endl可以節省不少時間
### 資料型態
```cpp=
int n=5; //-2147483648~2147483647
double m=9.5;
float a=9.5;
char c='a';
```
常見的資料型態有int(整數), double(雙精度浮點數), float(單精度浮點數), char(字元)
int的整數範圍只能在-2147483648~2147483647,若超出範圍則會有溢位問題
double跟float皆為浮點數,但有幾種差別
1. 位元組和範圍不同,double為8 byte, float為4 byte
2. 精度不同,double可到小數點後第15位,float只能到8位,再往後出現的數字都會整個亂掉
用科學記號表示應該更明顯的能看出悲劇
3. 在上課時應該會有人好奇為什麼宣告float的變數時常數後面會加一個後綴f
在C++中,浮點數的常數基本上是以double的方式存取,所以如果不加後綴f時,實際上常數會以double的形式轉為float的形式,而又因為double轉成float會有些許誤差,因此才要加f
不過,誤差極小,所以幾乎所有情況下不加也沒差
char字元,ASCII碼中常見的a對應的是10進位數字為97,A對應的是65
# rand()
### RAND_MAX
```cpp=
cout<<RAND_MAX<<endl; //我的電腦是32767
```
C++裡面內建的東西,若輸出會顯示rand()可出現的最大值
**以下是我上網查詢的結果,如果有錯再更正,每台電腦的RAND_MAX會不一樣,最小會是32767,最大則是2147483647**
### srand()
```cpp=
srand((unsigned int) time(NULL)); //寫NULL或0都可以
```
首先要說,實際上電腦所提供的亂數並不是真正的隨機數,以下為亂數生成原理
每個rand()所生成的亂數實際上是由**隨機亂數種子**所形成,其被包含在srand()中
**每個不同的隨機亂數種子會生成不同的序列**
例如當使用srand(8)時,rand()就會根據隨機種子8所生成的序列而進行輸出,因此會發現,**不管是在第1次編譯還是第n次編譯,所形成的亂數序列都會是一樣的**
(至於不同電腦會不會出現同樣的結果之後有機會再測試)
那如何改善這個狀況,這時就需要用到time()函式,當函式參數為0時,所得到的值會是從西元1970年1月1日0時0分0秒至今的秒數
因此,**每一秒srand()都會生成不同的亂數種子,因而形成不同的隨機亂數序列,從而達到某種意義上的亂數**
至於為何要在time(NULL)前加上unsigned int,原因是time(NULL)的值為signed型態,而srand()接受的是unsigned型態,因此為了預防出現問題,所以就要加個unsigned int進行轉換
### 用rand()生成[a,b]的數
```cpp=
#include <bits/stdc++.h>
using namespace std;
int main(){
int a=20, b=170; //假設要生成[20,170]的亂數
srand((unsigned int) time(NULL));
int m=rand()*(b-a)/32767+a; /* 上課教的方法,不太能理解的話可以帶數字進去看看
the range of rand() in [0,32767]*/
int n=rand()%(b-a+1)+a; //另一種方法,比較好理解
cout<<m<<endl<<n<<endl;
}
```
%為取餘運算子(取相除後餘數),例如21%6=3
所以rand()取於b-a+1後的數字只會在[0, b-a],再加上a之後區間為[a,b]
# 額外補充
### 上課用到以及常見的math函式
sqrt(n) square root的縮寫,取根號
pow(n,m) 指數,n的m次方
ceil(n),無條件進位n
floor(n),無條件捨去n
abs(n),取絕對值n
### 小數點後第n位與科學記號
#### 使用函式庫iomanip
```cpp=
#include <iostream>
#include <iomanip>
using namespace std;
int main(){
double n=321.65494176;
cout<<setprecision(4)<<fixed<<n<<endl; //321.6549
cout<<setprecision(4)<<scientific<<n<<endl; //3.2165e+002
}
```
### 萬用標頭檔
**(但似乎上課用的軟體用不了,也許要調一下編譯環境之類的,我再找找)**
```cpp=
#include <bits/stdc++.h>
```
這個函式庫包含所有的函式庫
例如 iostream, cmath, ctime, iomanip, vector, string, deque...
雖然看起來有點難記,不過這樣就不用再多記一堆函式庫了(但我還是會背一下啦,可能有極少部分軟體或競賽不給用)