# C++和C的差異
---
### NameSpace(命名空間)
是一個識別碼的可見範圍。
>(維基舉例)就像一間公司中,某個員工Kitty的識別碼是217,而在另一間公司中也有一個人(可能是Teresa)的識別碼是217。但是因為他們是不同公司,即使識別碼相同,所代表的意思也不同,並不會導致薪水發錯或是叫錯人的問題。
如以下的code,這裡的`cout`和`cin`的namespace是屬於`standard library`,為了不要造成命名重複的誤會,所以原本的打法應該是
```cpp=
#include <iostream>
int main(){
int a;
std::cin >> a;//standard library中的cin
std::cout << "Hello World!!\n";//standard library中的cout
}
```
而省略的寫法,就是在一開始就在一開始就指定namespace,之後用到此命名空間的東西,就不用再寫出來
```cpp=
#include <iostream>
using namespace std;
int main(){
int a;
cin >> a;
cout << "Hello World!!\n";
}
```
---
### String
>在使用之前,要記得`#include<string>`
和C不同的是,在C++中可以直接用`+`來連接字串
```cpp=
#include <iostream>
#include <string>
using namespace std;
int main(){
string name = "Teresa", str;
str = "Hello, " + name + "!\n";//use string like int in C
cout << str;
}
```
```cpp=
//OUTPUT
Hello, Teresa!
```
---
### Auto Type Inference
C++中,如果在變數前面標示型別的地方標示 `Auto`,則程式會自行判斷這個變數中的值的型別
>結合vector的例子一起示範
---
### Vector
>記得`#include<vector>`
`vector<int>` 的意思就是一個vector裡面每一個元素都是`int`,同理, `vector<string>`就是一個vector 裡面每一個元素都是string。另外,變數後不需要加等號(可加可不加)
下面例子,vector加上Auto Type Inference,示範C++的range-based for loop:
```cpp=
#include<iostream>
#include<vector>
using namespace std;
int main(){
vector<int> v {1, 2, 3, 4, 5};//v = {} is optional
//to take out the int from the vector v
//same as int i; i < len; ++i in C
//auto means it can detemine the type
for(auto i : v){
cout << i << ",";
}
cout << "\n";
}
```
Range-based for loop簡單來說就是不需要像C一樣多設一個index還要設定index範圍去跑整個vector,此種寫法會自動一序取出陣列的值,也不會有超過index範圍的問題。
>但這個功能有些用法還沒搞懂,先放著
---
### Call by Reference
先說說C++中新的變數類型,Reference。
在C當中 `int`變數就是一個整數變數,`int*`就是一個整數的指標變數,`int &`就是一個某個整數變數的別名。
```cpp=
#include<iostream>
using namespace std;
int main(){
int a = 7;
int *b = &a;
int &c = a;
cout << "a = " << a << endl;
cout << "b = " << *b << endl;
cout << "c = " << c << endl;
*b = 8;
cout << "After changing b,\n";
cout << "a = " << a << endl;
cout << "b = " << *b << endl;
cout << "c = " << c << endl;
c = 17;
cout << "After changing c,\n";
cout << "a = " << a << endl;
cout << "b = " << *b << endl;
cout << "c = " << c << endl;
}
```
當同樣都要改變a的值時,b需要先derefence,而c不需要。
c的任何存取,都會影響到a物件的操作。說白了,c就相當於a。
```cpp=
//OUTPUT
a = 7
b = 7
c = 7
After changing b,
a = 8
b = 8
c = 8
After changing c,
a = 17
b = 17
c = 17
```
如果我們寫一個swap的function來比較指標變數和參考的差別,應該會比較清楚:
```cpp=
#include<iostream>
using namespace std;
void swap_by_reference(int & i, int & j){
int tmp = i;
i = j;
j = tmp;
}
void swap_by_pointer(int *i, int*j){
int tmp = *i;
*i = *j;
*j = tmp;
}
int main(){
auto x = 5;
auto y = 7;
swap_by_pointer(&x, &y);
cout << x << ", " << y << endl;
swap_by_reference(x, y);
cout << x << ", " << y << endl;
}
```
```cpp=
//OUTPUT
7, 5
5, 7
```
一樣都能做到swap,但是當使用指標的時候,function裡面就需要dereference,但是當function中使用reference,就可以直接更改到`main`當中`x`和`y`的值。
當function的回傳值為reference時,不可以回傳function中的局部變數。(這個意思就是回傳的reference是function中變數的reference,但是當function結束後,function中的局部變數都不能再被使用,所以傳回來的東西就會是沒有意義的)
```cpp=
#include<iostream>
using namespace std;
//a function which returns a reference
int &max(int &i, int & j){
return (i > j) ? i : j;
}
int main(){
int x = 5;
int y = 9;
max(x, y) = 1;
cout << x << ", " << y << endl;
}
```
以這個function為例,當跑完`max`之後會回傳`y`的reference(因為`y`比較大)到`main`裡面。然後在`main`裡面我們又去更動這個reference的值。
所以最後`cout`的`y`經歷了多出一個reference,又因為reference更動值而`y`的值從9變成1。
```cpp=
//OUTPUT
5, 1
```
---
### Lambda Function
```cpp=
#include<iostream>
#include<iomanip>//setw()
#include<algorithm>//for_each()
#include<vector>//push_back()
using namespace std;
int main(){
vector<int> v;
for (int i = 1; i < 10;++i)
v.push_back(i * 5);
for(auto i:v)
cout << setw(5) << i;
cout << endl;
for_each(v.begin(), v.end(),[](int n){
if (n % 2 == 0){
cout << n << " is even " << endl;
}
});
for(const auto y : v)cout << setw(5) << setfill('#') << y;
cout << endl;
for(auto & y : v) y = y + 1;
for(const auto & y : v)cout << setw(5) << setfill('#') << y;
cout << endl;
}
//question: what is the difference between auto y and const auto & y?
```
寫到這裡有個疑問,`const auto & y`和`auto y`的差別在哪裡?
找到一個不錯的[參考資料](https://zhuanlan.zhihu.com/p/25148592),但我看不懂哈哈哈
把`class`上完再回來看看
```Cpp=
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Rational{
public:
//constructor
Rational();
Rational(int n);
Rational(int n, int d);
void show() const{
cout << numer << "/" << denom << endl;
}
//
private:
int numer;
int denom;
};
Rational::Rational(int n, int d){
numer = n;
denom = d;
}
```
```Cpp=
using namespace std;
class Rational{
public:
//constructor
Rational() : numer{0}, denom{1} {}
Rational(int n) : numer{n}, denom{1} {}
Rational(int n, int d) : numer{n}, denom{d} {}
void show() const{
cout << numer << "/" << denom << endl;
}
//
private:
int numer;
int denom;
};
```