[APG4b]C++の基礎文法をAtCoderで学ぶ。

## 参考
以下のサイトを参考にしている。

https://atcoder.jp/contests/APG4b

## 目的
- C++の基本文法を整理
- プログラミング言語の主流の文法を整理

## 予備知識

3つの制御構造
| 制御構造(3) |
|:-:|
|  順次 |
|  分岐 |
|  反復 |

## 第1章 基本文法(1.00~1.15)

### ファイルの主な構造
```c++
#include <bits/stdc++.h> // incloudeディレクティブで機能を読み込み
using namespace std; // プログラムを短く書くための機能

int main() {
// 処理
}
```

### 入力と出力
**複数の入力**の場合は、スペースか改行で区切られていれば**自動的に分解**して入力してくれる。
```c++
// 入力
cin >> 変数; // 入口をイメージ
cin >> 変数1 >> 変数2; // 複数を入力

// 出力
cout << 値; // 出口をイメージ
cout << 値 << endl; // 改行を含む
cout << 値1 << 値2 << 値3 << endl; // 複数を出力
```

### 2通りのコメント方法
```c++
// コメント

/*
コメント
*/
```

### プログラムの主な3つのエラー

| エラー(3) | 説明 |  |
|:-:|:-:|:-:|
|  コンパイルエラー |  書いたプログラムの文法にミスがあるときに発生するエラー |  Compile-Error |
|  実行時エラー |  実行時エラーとは、プログラムの文法に間違いはなかったが、内容に致命的な間違いがあったときに発生するエラー（例、3÷0のゼロ除算） |  Runtime-Error |
|  論理エラー |  プログラムは一見正しく動作しているが、その動作が実は正しくないときに発生するエラー |  Wrong-Answer |

| 1 | 2 | 3 |
|:-:|:-:|:-:|
|  実行時間制限超過 |   |  Time-Limit-Exceeded |

### 変数を宣言
「データ型」と「変数」を指定
```c++
データ型 変数;
データ型 変数 = 値; // 変数の宣言と代入（初期化）
データ型 変数 = 値1, 変数 = 値2; // 同時に複数を宣言
```
### 5つのデータ型

| データ型(5) | 説明 |
|:-:|:-:|
|  int型 |  整数 |
|  double型 |  小数 |
|  string型 |  文字列 |
|  char型 |  文字（1字） |
|  bool型 |  真偽値 |

```c++
int 変数 = 整数;
double 変数 = 小数;
string 変数 = "文字列"; // ダブルクオーテーション
char 変数 = '文字'; // シングルクオーテーション
bool 変数 = 真偽値;
```

### if文で条件分岐（分岐）
```c++
if (条件式1) {
  //処理1
}
else if (条件式2) {
  //処理2
}
else {
  //処理3
}
```

### 6つの比較演算子（うち2つ）
| 1 | 2 |
|:-:|:-:|
|  `==` |  等しい |
|  `!=` |  等しくない |

```c++
// 等しい場合
if (変数 == 値) {
cout << "等しい" << endl;
}

// 等しくない
if (変数 != 値) {
cout << "等しくない" << endl;
}
```

### 3つの論理演算子

| 1 | 2 |
|:-:|:-:|
|  !(条件式) |  条件式の結果の反転 |
|  条件式1 && 条件式2 |  条件式1が真 かつ 条件式2が真 |
|  条件式1 || 条件式2 |  条件式1が真 または 条件式2が真 |

```c++
if (!(変数1 == 変数2)) {
cout << "変数1と変数2は等しくない" << endl;
}

if (変数1 == 値 && 変数2 == 値) {
cout << "変数1と変数2は値" << endl;
}

if (変数1 == 値 || 変数2 == 値) {
cout << "変数1か変数2は値" << endl;
}
```

### 5つの複合代入演算子（うち1つ）
| 1 | 2 |
|:-:|:-:|
|  `+=` |  足して再代入 |

```c++
// 以下は同じ
変数 = 変数 + 値;
変数 += 値;
```

### インクリメントとデクリメント
| 1 | 2 |
|:-:|:-:|
|  `++` |  値を1ずつ増やす。 |
|  `--` |  値を1ずつ減らす。 |

このように、プログラムを短く書くための記法のことをシンタックスシュガーと言う。
```c++
// 以下は同じ
変数 = 変数 + 1;
変数 += 1;
変数++;
```

### while文で繰り返し処理（反復）
```c++
while (条件式) {
  // 処理
}
```

### for文で繰り返し処理（反復）
```c++
for (初期化; 条件式; 更新) {
  //処理
}

//N回処理する
for (int i = 0; i < N; i++) {
  //処理
}
```

### break;でループを抜ける
breakはループを途中で抜けるための命令です。
```c++
// breakがなければこのループはN回まで繰り返す
for (int i = 0; i < N; i++) {

if (条件式) {
  cout << "ぬける" << endl;
  break; // 条件を満たすと、ループから抜ける
}

// 処理 
}
```

### continueでその後の処理をとばして次のループへ行く
continueはその後の処理をとばして次のループへ行くための命令です。
```c++
for (int i = 0; i < N; i++) {

if (条件式) {
  cout << "とばす" << endl;
  continue; // 条件を満たすとき、これより後の処理をとばす
  // 処理
}

// 処理
}
```

### 「メンバ関数」
### 文字列の長さ
- 文字列変数.size()
```c++
string str = "Hello";
cout << str.size() << endl;
```

### i番目の文字
- 文字列.at(i)
```c++
string str = "Hello";
char c = str.at(0); // 0番目のchar型の値が得られる
```

### エスケープシーケンス（\n）
「改行」などの特殊な文字をプログラム中で表現する場合、エスケープシーケンスを利用します。
```c++
cout << "こんにちは\nAtCoder";
```

### 行単位での入力（getline関数）
cinを使うと空白や改行区切りの入力を簡単に扱えますが、空白で区切らずに行単位で入力を受け取りたいこともあります。
その場合はgetlineを使います。
- getline(cin, 文字列変数);
```c++
string s, t;
getline(cin, s); // 変数sで入力を一行受け取る
getline(cin, t); // 変数tで入力を一行受け取る

cout << "一行目 " << s << endl;
cout << "二行目 " << t << endl;
```
```c++
//入力
I have a pen.
I have an apple.

//実行結果
一行目 I have a pen.
二行目 I have an apple.
```

### 配列の宣言と、その操作
配列を宣言

```c++
//配列の宣言します。
vector<型> 配列名;

//配列の初期化
vector<型> 配列名(要素数);

// 初期値の指定
vector<型> 配列名(要素数, 初期値);
```
配列を操作します。
配列は文字列のように `+=` で要素を追加することはできません。
代わりに配列変数 `.push_back()` を使えば、配列の末尾に要素を追加することができます。
```c++
//i番目の要素
配列変数.at(i)

//配列の要素数
配列変数.size()

// 要素の追加
配列変数.push_back()

// 要素の削除
配列変数.pop_back()
```
for文を使った入力
```c++
// 100要素の配列で初期化
vector<int> vec(100);

// 100個の入力を受け取る
for (int i = 0; i < 100; i++) {
cin >> vec.at(i);
}
```

### STL (Standard Template Library)
C++で用意されている、関数等がまとまっているもののことをSTL (Standard Template Library)といいます。
min関数では2つの引数がありましたが、引数の数は関数によって異なります。
関数の計算結果の値のことを返り値（かえりち）または戻り値（もどりち）と言います。

### 5つの関数
```c++
// aとbのうち小さい方の値を返す
min(a, b);

// aとbのうち大きい方の値を返す
max(a, b);

// 変数aと変数bの値を交換する
swap(a, b);

// 配列変数をソートする（要素を小さい順に並び替える）
sort(配列変数.begin(), 配列変数.end());

// 配列変数vecの要素の並びを逆にする
reverse(配列変数.begin(), 配列変数.end())l;
```

### 配列を渡す形式
```c++
関数名(配列変数.begin(), 配列変数.end())
```
### 関数を定義
```c++
返り値の型 関数名(引数1の型 引数1の名前, 引数2の型 引数2の名前, ...) {
  // 処理
  return 返り値;
}

// 返り値がない関数
void 関数名(引数1の型 引数1の名前, 引数2の型 引数2の名前, ...) {
  // 処理
  return;
}

// 引数がない関数
返り値の型 関数名() {  
  cin >> 変数; // cinで入力
  // 処理
  return 返り値;
}
```
## 第2章 複雑な計算処理の書き方(2.00~2.03)
### 範囲for文
全ての要素を取り出し終わるとループを抜けます。
```c++
for (配列の要素の型 変数名 : 配列変数) {
  // 各要素に対する処理
}

```
### ループ構文の使い分け
- 範囲for文：配列の全ての要素に対する処理
- for文：一定回数、繰り返す処理
- while文：条件に合う限り繰り返す処理

### 多重ループのbreak/continue
```c++
  bool finished = false;  // 外側のループを抜ける条件を満たしているかどうか(フラグ変数)

  for (int i = 0; i < ... ; i++) {
    for (int j = 0; j < ... ; j++) {

      /* 処理 */

      if (/* 2重ループを抜ける条件 */) {
        finished = true;
        break;  // (＊)
        // finishをtrueにしてからbreakすることで、
        //   内側のループを抜けたすぐ後に外側のループも抜けることができる
      }
    }
    // (＊)のbreakでここに来る

    if (finished) {
      break;  // (＊＊)
    }
  }
  // (＊＊)のbreakでここに来る
```

### 多次元配列と表形式
配列を宣言します。
```c++
vector<vector<要素の型>> 変数名(要素数1, vector<要素の型>(要素数2, 初期値));
vector<vector<要素の型>> 変数名(要素数1, vector<要素の型>(要素数2));  // 初期値を省略

// 表の場合
vector<vector<要素の型>> 変数名(縦の要素数, vector<要素の型>(横の要素数));
```
### 2次元配列の要素にアクセス
```c++
変数名.at(添字1).at(添字2);

// 表の場合
変数名.at(上から何番目か).at(左から何番目か);
```
配列の要素数の取得
```c++
// 縦の要素数を取得
変数.size();

// 横の要素数を取得する
変数.at(0).size();
```
### N×0の二次元配列
後から配列に要素を追加して使う場合などに、N×0の配列を宣言することがあります。
```c++
vector<vector<型>> 変数名(N);  // 「要素数0の配列」の配列
```
### 長方形にならない二次元配列(ジャグ配列)
N×0の二次元配列に後から要素を追加していく場合などに「行毎に要素数の違う二次元配列」ができることがあります。

### 多次元配列
```c++
// 3次元配列の宣言
vector<vector<vector<要素の型>>> 変数名(要素数1, vector<vector<要素の型>>(要素数2, vector<要素の型>(要素数3, 初期値)));
vector<vector<vector<要素の型>>> 変数名(要素数1, vector<vector<要素の型>>(要素数2, vector<要素の型>(要素数3)));  // 初期値を省略