# C++の勉強 この後のライブコーディングで使用されることを中心に、現在主流のプログラミング言語にほぼ共通することについて説明する # コメント`// /* */` 説明などを書ける `//`改行までがコメント `/* */`挟まれた部分がコメント このあとめちゃくちゃコメントで説明しているので、読むべし ```cpp= // コメント コメントではない // コメント /* これも コメント */ ``` # 謎のセミコロン`;` C言語では、なにかと`;`が処理の最後についているが、そんなに深い意味はない (`for`文では重要) # 変数と型 値の入れ物 ## 変数宣言 コンピューターのメモリー(データを入れておく場所)のどこかに名前を付ける **`型 変数名;`**`// で宣言する` **`型 変数名 = 値;`**`// とすると、宣言と同時に値が入る(初期化)` - 整数型 `int`など 値: 整数 `int suuzi = -123;` - 文字列クラス `string` 値: 文字列(`""`で囲む) `string moziretu = "mogi";` ※型ではなく「クラス」 - 文字型 `char` 値: 半角英数字・記号・制御文字など(`''`で囲む) `char mozi = 'Q';` - 論理型 `bool` 値: 真`1` と 偽`0` `bool isHokudaisei = true;` <!-- - 浮動小数点型 `float`など 値: 実数 `float zissuu = 1.23;` --> # 関数 C言語では、処理は関数の中に書く ## `main`関数 C言語は(ふつう)`main`関数から開始される 下のように書くと、何もしないプログラムができる ```cpp= main() { } ``` :::spoiler 実行結果(なにも起きない) ``` ``` ::: (`int main(int argc, char const *argv[])`などの書き方をする場合も) ## 関数の作り方 `戻り値の型 関数名 (引数の宣言) {関数の処理;}` `int function_A (int input) {return 123;}` ```cpp= main() { int c; c = funcfunc(123); } int funcfunc(int a) { int b; // 変数宣言(funcfunc関数内だけで有効) b = a + 1; // a+1 を b に代入する return b; // int型を返す } ``` ## 標準入出力 ### 標準出力 Pythonの`print()`、C/C++の`puts(),printf()`などもあるが、 今回は「演算子のオーバーロード」による方法で文字列を出力 ※`endl`は改行のため ```cpp= #include <iostream> // シフト演算子のオーバーロードを使うため using namespace std; // cout,cinを使うため main() { cout << "aaa" << endl; // aaa と表示される cout << "bbb" << endl; // bbb と表示される } ``` :::spoiler 実行結果 ``` aaa bbb ``` ::: ### 標準入力 Pythonの`input()`、C/C++の`scanf()`などもあるが、 今回は「演算子のオーバーロード」による方法で文字列を出力 ```cpp= #include <iostream> // シフト演算子のオーバーロードを使うため using namespace std; // cout,cinを使うため main() { int num; cin >> num; // 入力した文字列を数値に変換して変数numに代入 cout << num + 10000 << endl; // 入力された数よりに10000足して表示 } ``` :::spoiler 実行結果 1 を入力し、Enterを押した場合 ``` 1 10001 ``` 2345 を入力し、Enterを押した場合 ``` 2345 12345 ``` ::: # 演算子 (これ以降の部分は、省略のため、`main`関数の中身だけを書いている) ## 代入演算子`=` 等号の意味ではない! 左に、右から代入される (当然、左は変数でなければいけない) ```cpp= // 変数宣言(初期化) int num = 0; cout << num << endl; // 0 が表示される num = 1; // 代入 cout << num << endl; // 1 が表示される ``` ## 四則演算 `+ - * /` ```cpp= // 変数宣言 int a = 3; int b = 2; int c = 1; c = a + b; //足し算 cout << c << endl; // 5 が表示される c = a - b; // 引き算 cout << c << endl; // 1 が表示される c = a * b; // 掛け算 cout << c << endl; // 6 が表示される c = a / b; // 割り算 cout << c << endl; // 1 が表示される(整数) ``` ## 複合代入演算子 `+= -=`などなど ```cpp= // 変数宣言 int a = 0; a += 10;  // a = a + 10; と同じ cout << a << endl; // 10 が表示される a -= 10; // a = a - 10; と同じ cout << a << endl; // 0 が表示される ``` ## 増分・減分演算子`++ --` インクリメント(カウントアップ)、デクリメント(カウントダウン) ```cpp= // 変数宣言 int a = 0; a++; // a += 1; や a = a + 1; と同じ cout << a << endl; // 1 が表示される a--; // a -= 1; や a = a - 1; と同じ cout << a << endl; // 0 が表示される ``` ※前置と後置があるが、今回は触れない ## 比較演算子 `< <= > >= == !=` 大小比較4つ、等しい、等しくない 主に分岐やループの条件式に使う 成立で1、不成立で0を返す `!= <= >=`は、フォントによっては`≠ ≤ ≥`と表示される ```cpp= bool b; b = 1 < 1; cout << b << endl; // 0 が表示される b = 1 <= 1; cout << b << endl; // 1 が表示される ``` :::spoiler 実行結果 ``` 7 10 ``` ::: ## 論理演算子 `and or && ||` ```cpp= and //(&&も同じ) or //(||も同じ) ``` ## シフト演算子 `<< >>` 今回は`cout cin`の標準入出力を利用する際、演算子のオーバーロードで使用するが、ややこしいので省略 ## 演算子の優先順位 数学と同じように、計算の順番(演算子の優先順位)がある(詳しくは下記URL参照)。 http://www.bohyoh.com/Candcpp=/C/operator.html ```cpp= // 変数宣言 int a = 3; int b = 2; int c = 1; c = a + b * b; // 掛け算が先 cout << c << endl; // 7 が表示される c = (a + b) * b; // ()内が先 cout << c << endl; // 10 が表示される ``` :::spoiler 実行結果 ``` 7 10 ``` ::: # 分岐 `if`、`else` `if(条件式)`のように書く 条件式が`0`以外なら`if(条件式)`の後の`{}`で囲まれた処理を実行する 条件式が`0`なら`else`の後の`{}`で囲まれた処理を実行する ```cpp= if(1 < 2){ cout << "YES" << endl; // YES が表示される }else{ cout << "NO" << endl; // NO が・・・表示されない } ``` :::spoiler 実行結果 ``` YES ``` ::: `if`だけでもよい(条件式が`0`の時、なにもしない) ```cpp= if(1 < 2){ cout << "YES"; // YES が表示される } ``` `{}`は省略できるが、そのあと1つ目の処理だけが`{}`の中にあるのと同じになる ```cpp= if(0 == 1) cout << "YES" << endl; // YES が・・・表示されない cout << "YES" << endl; // YES が表示される(インデントに意味はない) ``` 上と同じ ```cpp= if(0 == 1){ cout << "YES" << endl; // YES が・・・表示されない } cout << "YES" << endl; // YES が表示される ``` `else if`を使い、3つ以上に分岐することもできる ```cpp= int x = 5; cout << "x is " << x << "." endl; if(x < 1) cout << "x is less than 1." << endl; else if(x < 4) cout << "x is 1 or more and less than 4." << endl; else if(x < 7) cout << "x is 4 or more and less than 7." << endl; else cout << "x is 7 or more." << endl; ``` :::spoiler 実行結果 ``` x is 5. x is 4 or more and less than 7. ``` ::: # ループ `while for break continue` ## `while` `while(継続条件式)`は、`継続条件式`が`true`の間ずっと繰り返すような処理によく使われる 無限ループ ```cpp= while (true){ cout << 'a'; // a が無限に表示される } ``` :::spoiler 実行結果 ``` aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ``` ::: 決まった回数のループ(`for`で書くことが多い) ```cpp= int i = 0; while (i < 8){// 8回繰り返す cout << i; // 0 1 2 3 4 5 6 7 が順番に表示される i++ } ``` :::spoiler 実行結果 ``` 0 1 2 3 4 5 6 7 ``` ::: ## `for` `for(初期化式;継続の条件式;変化式)`は、`while`よりも決まった回数のループによく使われる 下の書き方が定型文的に使われる(上の`while`と同じ動作なので、見比べて理解してほしい) ```cpp= for (int i = 0; i < 8; i++){// 8回繰り返す cout << i << " "; // 0 1 2 3 4 5 6 7 が順番に表示される } `````` :::spoiler 実行結果 ``` 0 1 2 3 4 5 6 7 ``` ::: ## `break` ループを終了させ、外に出たいときに使う 通常、`if`と組み合わせて使う ```cpp= for (int i = 0; i < 8; i++){// 8回繰り返す cout << i << " "; // 0 1 2 3 4 5 6 7 が順番に表示される if(i == 4) break; } // <- breakでここに飛ぶ ``` :::spoiler 実行結果 ``` 0 1 2 3 4 ``` ::: ## `continue` ループの最後まで処理を飛ばしたいときに使う 通常、`if`と組み合わせて使う ```cpp= for (int i = 0; i < 8; i++){// 8回繰り返す cout << i << " "; // 0 1 2 3 4 5 6 7 が順番に表示される if(i < 4) continue; cout << endl; // 改行する // <- continueでここに飛ぶ } ``` :::spoiler 実行結果 ``` 0 1 2 3 4 5 6 7 ``` 0~3の後は改行しないのでこうなる ::: # クラス ## string 前述の通り文字列クラス 変数として扱えるほか、`.length`で文字列の長さを取得したりできる ```cpp= #include <iostream> // シフト演算子のオーバーロードを使うため #include <vector> // vectorを使うため using namespace std; // cout,cinを使うため // メイン関数 int main(void) { string s = "This is very long long string."; cout << s.length; } ``` ## vector(配列のようなもの) 同じ型の変数をまとめて扱える vectorを`vec`で宣言したとすると、**最初の変数は`vec[0]`**、次の変数は`vec[1]`のように扱える ```cpp= #include <iostream> // シフト演算子のオーバーロードを使うため #include <vector> // vectorを使うため using namespace std; // cout,cinを使うため // メイン関数 int main(void) { // 全て a が代入された、長さ8のchar型のvectorを宣言 vector<char> aaa(8,'a'); aaa[3] = 'A'; aaa[4] = 'A'; for (int i = 0; i < 8; i++) // 8回繰り返す { cout << aaa[i] << " "; // . . . O X . . . が表示される } } ``` 2次元にもできる ```cpp= #include <iostream> // シフト演算子のオーバーロードを使うため #include <vector> // vectorを使うため using namespace std; // cout,cinを使うため // メイン関数 int main(void) { // 全て'.'(ピリオド)が代入された、長さ8の(長さ8のchar型のvector)のvectorを宣言 vector<vector<char>> reversi(8, vector<char>(8,'.')); reversi[3][3] = '@'; reversi[4][4] = '@'; reversi[3][4] = 'O'; reversi[4][3] = 'O'; for (int i = 0; i < 8; i++) // 8回繰り返す { for (int j = 0; j < 8; j++) // 8回繰り返す { cout << reversi[i][j] << " "; // 何が表示される??? } cout << endl; // 改行する } } ``` :::spoiler 実行結果 ``` . . . . . . . . . . . . . . . . . . . . . . . . . . . @ O . . . . . . O @ . . . . . . . . . . . . . . . . . . . . . . . . . . . ``` ::: フィボナッチ数列の例 ```cpp= #include <iostream> // シフト演算子のオーバーロードを使うため #include <vector> // vectorを使うため using namespace std; // cout,cinを使うため // メイン関数 int main(void) { int length = 10; vector<int> suuretu(length,0); // 全て0が代入された、長さlengthのint型のvectorを宣言 for (int i = 0; i < length; i++) // length回繰り返す { cout << suuretu[i] << " "; // 0 0 0 0 0 0 0 0 0 0 が表示される } suuretu[0] = 0; // 最初の2項は0,1 suuretu[1] = 1; for (int i = 2; i < length; i++) // iが2から(length-2)まで繰り返す { suuretu[i] = suuretu[i - 1] + suuretu[i - 2]; // フィボナッチ数列を作る } cout << endl; // 改行 for (int i = 0; i < length; i++) // length回繰り返す { cout << suuretu[i] << " "; // 0 1 1 2 3 5 8 13 21 34 が順番に表示される } } ``` :::spoiler 実行結果 ``` 0 0 0 0 0 0 0 0 0 0 0 1 1 2 3 5 8 13 21 34 ``` ::: ## pair make_pair くわしくはMonkukuiさんに聞きましょう! # スコープ `{}`で囲まれた部分で宣言した変数は、`{}`の内でのみ使用可能 関数の引数も、関数内でのみ使用可能 ```cpp= #include <iostream> // シフト演算子のオーバーロードを使うため using namespace std; // cout,cinを使うため int numA; // スコープは全体(グローバル変数) main() { int numC; // スコープはmain関数内 cout << numA + numB + numC; } void functionA() { int numB; // スコープはfunctionA関数内 } ``` コンパイルすると以下のようなエラーが出る ``` test2.cpp:9:18: error: 'numB' was not declared in this scope cout << numA + numB + numC; ^~~~ ``` `'numB' was not declared in this scope`は、「このスコープではnumBは宣言されていません」 <!-- # 今日は扱わないが、重要なこと - クラス - ラムダ式 - `auto` - `const` - `switch-case`の分岐 - `++x;`と`x++;`の違い --> <!-- - `bool`の変数を数値として扱う --> <!-- - ポインタ --> <!-- - `vector`は使う --> <!-- - グローバル変数(に書き込みまくる)とかポインタとか構造体よりは簡単だし、pair<>は使ってもよさそう -->