令和のC++基礎文法最速マスター

19日目です。

# C++とは
Cの拡張版のコンパイル言語。最新バージョンは`C++20`
学習は[wandbox](https://wandbox.org/)や[paiza](https://paiza.io/ja)などのオンライン実行環境がおすすめ

# コメント
C++のコメントは2種類ある。
1: `//` 行コメント
2: `/* */` 範囲コメント

``` c++
//コメント

/*

ここもコメント

*/
コメントじゃない！
範囲コメントの入れ子はできない
*/
```
# Hello World
```C++:HelloWorld.cpp
#include <iostream>

int main(){
    std::cout << "Hello　World!" << std::endl;
    return 0;
}
```
```:result
Hello World!
```
c++では原則`main`関数から実行されます。

```c++
int main(){
    //この中になんか書く
}
```

## include
C#でいう`using`、pythonでいう`import`に近い。
`std::cout`や`std::endl`などが`iostream`に定義されており、`#include`を使って読み込んでいる。
`#include`については、また後程詳しく説明する。

## std::cout　std::endl
頭の`std`は名前空間を示している。`iostream`のような標準ライブラリの名前空間は`std`であり、標準ライブラリの関数を呼び出す際は頭に`std::`を付ける。

`cout`は標準出力であり、`<<`からの内容を標準出力に出力する。他言語における`print`のようなものである。
`endl`は改行を意味する。

# 型
c++は、一部言語とは違い、変数宣言などの際型を明示する必要があります。
## 数値型
数値型にはいくつか種類がある。
### 整数型
整数型は符号付(マイナスの数を含む)と符号なし(マイナスの数を含まない)の二つに分かれ、サイズの異なる4種類が存在する。予約語ではないので、`#include <cstdint>`をファイルの頭に書いてください。

<details><summary>[コラム] C++における型</summary>
予約語の型(`short` `int` `long`とか)はサイズが環境により異なる。そのためここでは`cstdint`で定義された整数型について記載する。特にこだわりがなければサイズが厳密なこちらを使用されたし

| 型 | サイズ [byte]| 範囲 |
|:-:|:-:|:-:|
|  int8_t |  1 | -128 ~ 127  |
| uint8_t  | 1  | 0 ~ 255  |
| int16_t  | 2  | -32768 ~ 32767  |
| uint16_t  | 2  | 0 ~ 65535  |
|  int32_t | 4  | -2147483648 ~ 2147483637  |
|  uint32_t | 4  | 0 ~ 4294967295  |
| int64_t  | 8  | -9223372036854775808 ~ 9223372036854775807  |
| uint64_t  | 8  | 0 ~ 18446744073709551615  |

### 浮動小数点数型
浮動小数点数を表す型は2種類ある。

| 型 | サイズ[byte] | 範囲 |
|:-:|:-:|:-:|
| float  | 4  | 3.4E +/- 38 (7 桁)  |
| double  | 8  | 1.7E +/- 308 (15 桁)  |

### 文字型
文字型は1つである。`int8_t`と同じと考えてよい。なお、文字列型というのはない。(後述)

| 1 | 2 | 3 |
|:-:|:-:|:-:|
| char  | 1  | -128 ~ 127  |
| unsigned char  | 1  | 0 ~ 255  |

# 変数
C++における変数宣言は以下のとおりである。

``` c++:source.cpp
#include <cstdint>

//変数の宣言、初期化
//型 変数名 ( = 初期価値);
int32_t a;//宣言
uint32_t b = 249u;//末尾に'u', 'U'を付けると、符号なしの数となる
char c = 'n'; //文字は '' で囲う
double d = 3.141592;//初期化
constexpr float e = 2.71;//constexprを前につけると定数となる。


//変数への代入
//変数名 = 値
a = 128;
d = a;//暗黙にキャストされる
b = (uint32_t)a;//(型名)を変数の前につけると、明示的にキャストする
//e = 3.14; エラー　定数に代入などにより変更できない
```
## 配列
配列は次のように宣言、使用する。

```c++:Array.cpp
#include <array>
#include <iostream>

std::array<int32_t, 6> ary;//int32_t型、要素数6の配列
std;;array<int32_t, 6> ary2{0,1,2,3,4,5};//それぞれの値で各要素を初期化

for(int32_t i = 0; i < 6; i++){
    ary[i] = i;//[ ]で各要素にアクセスする
}

for(auto ar : ary2){//c++におけるforeachのようなもの 後述する
    //arは各要素 ary2[i]と同じ感じ
    std::cout << ar << ','; //0,1,2,3,4,5,
}

```

<details><summary>[コラム] 生配列</summary><div>
C++にはC言語からの配列があり、よく生配列といわれたりする。`Array`は標準ライブラリによる機能であるが、生配列はクラスではなく言語仕様。そのため何かをincludeする必要はない。ただ、C言語用ライブラリやCとの互換性が必要な場面、組み込みのためにメモリを節約するなどの場面以外では使うことはないほうが多い気がする。上記のコードを生配列を用いて書いてみる

```c++
#include <iostream>

int32_t ary[6];
int32_t ary2[6] = {0,1,2,3,4,5};

for(int32_t i = 0; i < 6; i++){
    ary[i] = i;
}

for(int32_t i = 0; i < 6; i++){
    std::cout << ary2[i] << ',';
}
```
</div>
</details>

##文字列
<details><summary>[コラム] 文字列は文字の配列</summary><div>
C++に文字列型というのはなく、文字型の配列によってあらわされる。つまり次のような感じになる

```c++
std::array<char, 64> str{'H', 'e', 'l', 'l', 'o'};

char[64] str2 = "Hello";
```

また、後述の`string`も配列になるため`[i]`を用いてi番目の文字(char型)を得ることができる
</div>
</details>

文字列は`string`を使う。頭で`#include <string>`をしてください。
コードは次のようになります。

```c++
#include <string>
std::string str = "Hello";
```

##コンテナ
C++には可変長動的配列として`vector`がある。他言語でいう`List`、`ArryList`に近い。
`#include <vector>`を頭に書いてください。

```c++:Vector.cpp
#include <vector>

std::vector<int32_t> vec;

for(int32_t i = 0; i < 10; i++){
    int32_t n;
    std::cin >> n;
    vec.push_back(n);//末尾に要素を追加
}
```
# 演算子
```c++
int32_t a = 0;
a = 3 + 2; //a is 5
a = 3 - 2; //a is 1
a = 3 * 2; //a is 6
a = 3 / 2; //a is 1  整数のため小数は切り捨てられる
a = 3 % 2; //a is 1　3を2で割った余り
```
```c++
a = 0;

a += 10; // a is 10     a = a + 10と同じ
a -= 2;  // a is 8      a = a - 2
a *= 2;  // a is 16     a = a * 2
a /= 2;  // a is 8      a = a / 2
a %= 3;  // a is 2      a = a % 3
```
```c++
int32_t a = 0, b = 3, c = 3;
bool r;

r = a == b; // false
r = a == c; // true

r = a != b; // true;
r = a != c; // false;

r = a > b; // false
r = a > c; // false

r = a < b; // true
r = a < c; // false

r = a >= b; // false
r = a >= c; // true

r = a <= b; // true
r = a <= c; // true

r = true && false; // false and演算
r = true || false; // true  or演算
```

# 関数
関数の宣言・定義は次の通りです

```c++:calc.hpp
//宣言
//戻り値の型 関数名(引数)
int32_t add(int32_t a, int32_t b);
```
```c++:add.cpp
//定義
int32_t add(int32_t, int32_t b){
    return a + b; //戻り値は return で返す
}
```
```c++:source.cpp
#include "add.hpp"
//他ファイルで関数を定義した場合、その関数の宣言が書かれたファイル(*.h/*.hpp)をインクルード

int32_t r = add(2, 3); // r is 5
```
関数の途中に`return`があると、それ以降は実行されません。

```c++
int32_t mul(int32_t a, int32_t b){
     if(b == 0){
         return 0;
         b = 1;//これ以降実行されない
     }
     return a / b;//b==0でなければ実行される
     a += 2;//実行されない
}
```
戻り値がない場合は、戻り値の型を`void`としてください。また、その場合は関数ブロックの終わり(`}`)または`return;`で関数を終了します。

# 制御
## if/else
条件分岐は`if`です。

```c++
int32_t abs(int32_t a){
    if(a > 0){//aが0よりおっきい
        return a;
    }
    else if(a == 0){//そうじゃなくてaが0のとき
        return 0;
    }
    else{//そうじゃない
        return -a;
    }
}
```

## ループ
繰り返し処理には`for`と`while`があります。
### for

```c++
//for(初期化式; 条件式; 変化式)

int32_t i;
for(i = 0; i < 10; i++){//iを0で初期化し、i < 10を満たすとき、i++をする
    //ループ内
    if(i == 2) break; //iが2のとき、forループから抜け出す
}

//初期化式内で変数宣言をすると、forループ内でのみその変数が有効になる
for(int32_t j = 0; j < 10; j++){//jを0で初期化し、j < 10を満たすとき、j++をする
    //ループ内
}
i = 0;  //これは有効
// j = 0; これは無効

for(;;){
    //条件式に何も書かないと、無限ループ
}
```

### while
```c++
bool Update(){
    return system.Update(); //終了するときはfalseが返る
}

int main(){
    while(Update()){
        //終了操作がされるまで実行される
    }

    return 0;
}
```

# 終わり
追加要望があれば追記します。