このページは引っ越しました。
IT Tech Learning
learn.ee3.jp
以下の内容は今後メンテナンスされません。
チートシートのアイデアと全体構成は こちらの引用元 から頂きました。以下に添付されているソースコードはオリジナル、または、著作権を伴わないと判断した一般的な内容です。
テンプレート
参考例
ファイルの冒頭に「ヘッダー」を書くことでコーディングの効率化の効果がある。下記は一例であり、自分なりのものを作ることが望ましい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
#include <bits/stdc++.h> using namespace std; #include <atcoder/all> using namespace atcoder; using ll = long long; const int INF = 0x7FFFFFFF; const long long LINF = 0x7FFFFFFFFFFFFFFF; #define rep(i, n) for (int i = 0; i < (int)(n); i++) #define range(i, s, e) for (int i = (s); i <= (int)(e); i++) #define all(a) begin(a), end(a) #define rall(a) rbegin(a), rend(a) #define coutf cout << fixed << setprecision(8) #define pydiv(a,b) ((0<(a)&&0<(b)||(a)<0&&(b)<0) ? (a)/(b) : (0<(b)) ? ((a)-(b)+1)/(b) : ((a)-(b)-1)/(b)) #define pymod(a,b) ((0<(a)&&0<(b)||(a)<0&&(b)<0) ? (a)%(b) : ((a)%(b)+(b))%(b)) // 要素数3以上のmin/max(C++20から)例.min({1,2,3}) //#define min std::ranges::min //#define max std::ranges::max // 座標をsetで扱えるようにする。pairのメンバー名first,secondが嫌なので。 struct Point { int x, y; }; bool operator<(const Point &p1, const Point &p2){ if (p1.x != p2.x) return p1.x < p2.x; else return p1.y < p2.y; } #define cin_from(fname) ifstream ifs(fname); cin.rdbuf(ifs.rdbuf()); #define cout_to(fname) ofstream ofs(fname); cout.rdbuf(ofs.rdbuf()); int main() { int N; cin >> N; vector<int> A(N); rep(i, N) cin >> A[i]; vector<int> B(N , 0); vector<vector<int>> C(N, vector<int>(N, 0)); int ans = 0; cout << ans << endl; return 0; } |
Hello World!
1 2 3 4 5 6 7 8 |
#include <bits/stdc++.h> using namespace std; int main() { cout << "Hello, C++" << endl; return 0; } |
汎用版Hello World!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
/********************* これはGCC(g++)とclang++の両方で動くサンプル。 $ g++ hello_clang.cpp $ clang++ hello_clang.cpp Macでは特別な設定をしなくてもg++コマンドが動きます。 ただし多くの場合、そのg++コマンドはXcodeと一緒に インストールされるclang++のエイリアスです。 競プロで使われる本物のg++は brew install gcc で インストールする必要があります。 競プロでよく使う #include <bits/stdc++.h> はMac版のg++には存在しません。 Mac版のコンパイラかどうかは #ifdef __clang_version__ で判定できます。 *********************/ #ifdef __clang_version__ // Mac版g++(clang++)の場合 #include <iostream> #else // その他、競プロ環境の場合 #include <bits/stdc++.h> #endif using namespace std; // 基本、これは常に書く int main() { #ifdef __clang_version__ cout << __clang_version__ << endl; #endif cout << "Hello, C++" << endl; // "\n"の代わりにendlでも良い return 0; } |
文法
基本的な文法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
// GCCのg++を競プロで使う場合、次の2行は常に書くのが定石 #include <bits/stdc++.h> using namespace std; // コメントの書き方(1) // "//"から行末はコメントと見なされる。行の途中からでもOK。 /* コメントの書き方(2) /* から */ までの範囲はコメント(実際は"/"は半角文字である) 行の途中からでもOK。途中に含まれる改行もコメントと見なされる。 広い範囲をまとめてコメント化できる。ただし「入れ子」にはできない。 */ // main()の外側で定義された変数はグローバル変数。 // プログラムの実行中常に存在し、関数の中など、どこからでも参照できる。 int global_var_1; // グローバル変数の宣言(グローバル変数は0で初期化される) int global_var_2 = 999; // 初期値を設定したグローバル変数の宣言 // main() や関数の中で定義された変数はローカル変数。 // ローカル変数は明示的に初期化しないかぎり、初期値は不定である。 // ローカル変数はその関数内、またはブロック内でのみ存在し、有効である。 // これを変数の「スコープ」という。 /* * C/C++のプログラムにはmain()関数が必ず存在する。 * ・main() 関数は int型 で、そのリターン値はシステム側で利用される。 * 通常、処理が正常に終われば 0、エラーならそれ以外を返すが、 * その値を利用するかどうかはシステム依存。(競プロでは無視されることが多い) * ・main() の内容は { } で囲む。 */ int main() { // 文の末尾は ; で終わる。改行やインデント(字下げ)は関係ない。 int i = 10; int // 行頭がズレたり、途中で改行しても影響ない。 j; /* インデント(字下げ)は文法上は意味を持たないが、上の例のようにコードの 可読性のためには重要。常に正しく統一性のあるインデントを行うこと。*/ // 複数の文を { } で囲うと、ひとまとまりのブロックになる。 // ブロックの最後には ; は付けない。 // ブロックの中で宣言された変数のスコープは、そのブロック内に限られる。 { int i; // このiと数行上(ブロック外)で宣言されたiは別の変数(スコープが異なる) i = 20; cout << "ブロック内では i=" << i << endl; } cout << "ブロック外では i=" << i << endl; // グローバル変数はどこからでも参照できる。 cout << "グローバル変数 global_var_1=" << global_var_1 << " は0で初期化されている。" << endl; cout << "グローバル変数 global_var_2=" << global_var_2 << " は999で初期化されている。" << endl; /* main()関数はint型なので整数値を返す。 */ return 0; } |
プリプロセッサ
C言語・C++言語にはプリプロセッサが存在する。プリプロセッサはソースコードの前処理を行い、その結果はコンパイラへの入力となる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
#include <bits/stdc++.h> using namespace std; // #defineはコンパイラではなくプリプロセッサに対する命令である。 // 定数を記述したり、コード内の文字列を置換したりできる。 // 定義名は大文字を使うのが慣例。 #define VALUE1 123 #define number_type int // #defineで定義した名前で、どの部分をコンパイルするか制御できる。 #define CONTROL_1 // この行が存在するか・しないか(コメント化されているか)で動作が異なる #define CONTROL_2 0 // 値を使って複数の動作を制御することもできる // #defineで定義する名前には引数のように値を渡すこともできる。 // これによりコード記述の簡略化が可能になる。 #define rep(i, n) for (int i = 0; i < (int)(n); i++) int main() { cout << "VALUE1の値は" << VALUE1 << endl; // "VALUE1"は変数ではないので変更はできない。次の文を有効にするとエラーが発生する。 //VALUE1 = 10; // "number_type"というデータ型は存在しないが、#define文により"int"に置き換えられる。 number_type i = 10; cout << "i=" << i << endl; // #if の後には論理式を書く。0はfalse、1はtrueを意味する。 // 次の行の0を1に変更すると、有効なコードの範囲が逆になる。 #if 0 // #if 0 〜 #endif で囲まれば部分はプリプロセッサによって無視される。 // これをコメント機能として使い、プログラムの一部の動作を無効化できる。 cout << "ここは #if 0 の内部" << endl; #else // #if には #else も使える。#else は無くても良い。 cout << "ここは #if 0 の、#else の中" << endl; #endif // #ifdef の後には定義名を書く。その名前が定義されているかで、有効なコードの範囲を制御する。 // 冒頭の #define CONTROL_1 を削除またはコメント化すると動きが変わる。 // #ifdef の逆論理は #ifndef である。 #ifdef CONTROL_1 cout << "CONTROL_1が定義されていればここが動作する。" << endl; #else cout << "CONTROL_1が定義されていなければここが動作する。" << endl; #endif // #if の後には定義名を使った論理式を書ける。 // 冒頭の #define CONTROL_2 の値を変更すると動きが変わる。 #if CONTROL_2 == 0 cout << "CONTROL_2が0または未定義ならばここが動作する。" << endl; #elif CONTROL_2 == 1 // #elif は "else if" を意味する cout << "CONTROL_2が1ならばここが動作する。" << endl; #elif CONTROL_2 == 2 cout << "CONTROL_2が2ならばここが動作する。" << endl; #else // #else はなくても良い cout << "CONTROL_2がその他の場合はここが動作する。" << endl; #endif // 普通にfor文を書くとこうなるが面倒である。 for (int i=0; i<3; i++) cout << "i=" << i << ' '; cout << endl; // 競プロでは次のような簡略した書き方をすることがある。 // rep() は冒頭の #define で定義されており、実際はfor文である。 rep(j, 3) cout << "j=" << j << ' '; cout << endl; return 0; } |
入出力
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
#include <bits/stdc++.h> using namespace std; int main() { // 標準出力デバイス(通常はターミナルコンソール)に // cout でデータ(変数や定数)を出力する。 // ・endl を出力すると改行する。 // ・ << を繋げて幾つでも連続して出力できる。 cout << "数値を入力してください。" << endl; // ・文字列最後に \n を付けても改行できる。 cout << "(文字を入れると0と認識されます)\n"; // 標準入力デバイス(通常はターミナルコンソールに接続されたキーボード) // から cin でデータ入力できる。 int N; // int型(数値)の変数を宣言 cin >> N; // 読み込んだ数値を変数にセットする cout << "読み込んだデータは " << N << " です。" << endl; // 文字列も読める cout << "何か文字列を入力してください。" << endl; string S; // string型(文字列)の変数を宣言 cin >> S; // 読み込んだ数値を変数にセットする cout << "読み込んだデータは " << S << " です。" << endl; // 複数のデータ入力も可能。データの区切りはスペース、改行、タブが使える。 cout << "数値を3つ入力してください。" << endl; int N1, N2, N3; // int型(数値)の変数を宣言 cin >> N1 >> N2 >> N3; // 読み込んだ数値を変数にセットする cout << "読み込んだデータは " << N1 << " " << N2 << " " << N3 << " です。" << endl; // 配列へのデータ入力も可能。 cout << "データの個数を入力してください。" << endl; int N4; // int型(数値)の変数を宣言 cin >> N4; int N4_array[N4]; // int型(数値)の配列変数を宣言。C++では変数でサイズ指定できる。 cout << "数値を " << N4 << " 個入力してください。" << endl; for (int i=0; i<N4; i++) cin >> N4_array[i]; // 読み込んだ数値を配列にセット cout << "読み込んだデータは "; for (int i=0; i<N4; i++) cout << '(' << i << ')' << N4_array[i] << ' '; cout << "です。" << endl; return 0; } |
出力の書式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
#include <bits/stdc++.h> using namespace std; int main() { cout << "-- 書式は保存される" << endl; int i = 14; cout << i << endl; // 標準(現在の設定値=初期値は10進) cout << hex << i << endl; // 16進に変更 cout << i << endl; // 明示的に変更しないと状態は変わらない cout << dec << i << endl; // 10進に戻す cout << "--- 10/16/8/2進" << endl; cout << dec << i << endl; // 標準(10進) cout << hex << i << endl; // 16進 cout << oct << i << endl; // 8進 cout << bitset<8>(i) << endl; // 2進 <ビット幅> cout << "--- 出力スペースの指定" << endl; cout << setw(10) << dec << i << endl; // 標準(10進) cout << setw(10) << hex << i << endl; // 16進 cout << setw(10) << oct << i << endl; // 8進 cout << setw(10) << bitset<8>(i) << endl; // 2進 <ビット幅> cout << "--- 0で埋める" << endl; cout << setfill('0') << setw(10) << dec << i << endl; // 標準(10進) cout << setfill('0') << setw(10) << hex << i << endl; // 16進 cout << setfill('0') << setw(10) << oct << i << endl; // 8進 cout << setfill('0') << setw(10) << bitset<8>(i) << endl; // 2進 <ビット幅> cout << "--- showbaseの効果(2進・10進には効果なし)" << endl; cout << showbase; cout << hex << i << endl; // 16進 cout << oct << i << endl; // 8進 cout << noshowbase; cout << "--- 16進を大文字で" << endl; cout << uppercase << hex << i << endl; // 大文字 cout << "0x" << uppercase << hex << i << endl; // 0xに続いて大文字 cout << nouppercase << hex << i << endl; // 元に戻す cout << "--- 浮動小数点" << endl; double f = 10.0 / 3; cout << f << endl; // 標準 cout << fixed << f << endl; cout << fixed << setprecision(2) << f << endl; // 少数点以下の長さを指定 cout << scientific << f << endl; cout << scientific << setprecision(2) << f << endl; cout << "--- bool値を文字列で出力" << endl; bool a = true; cout << boolalpha << a << endl; // boolalphaが無いと1と出力 a = false; cout << boolalpha << a << endl; // boolalphaが無いと0と出力 cout << (a ? "Yes" : "No") << endl; // 競プロではこちらの方が使いそう return 0; } |
データ型、キャスト、定数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
#include <bits/stdc++.h> using namespace std; int main() { //////////////////////////////// // int型 //////////////////////////////// cout << "-- int型 --" << endl; // int は4バイトの(処理系によって違う場合もある)数値を表すデータ型 cout << "int型のサイズは " << sizeof(int) << " バイトです。" << endl; int i; // 変数の宣言(ローカル変数の初期値は不定。0のこともあるがそれは偶然。) int i2 = 999; // 初期値を付けた宣言 cout << "初期値の確認(iは不定) i=" << i << " i2=" << i2 << endl; // int の最大数 i = 0x7FFFFFFF; cout << "int で表せる最大数は " << i << " です。" << endl; cout << "それは INT_MAX で定義されています。 " << INT_MAX << endl; i = 0x80000000; cout << "int で表せる最小数は " << i << " です。" << endl; cout << "それは INT_MIN で定義されています。 " << INT_MIN << endl; unsigned int j = 0xFFFFFFFF; cout << "unsigned int で表せる最大数は " << j << " です。" << endl; //////////////////////////////// // long long型 //////////////////////////////// cout << endl << "-- long long型 --" << endl; // long long は8バイトの数値を表すデータ型 cout << "long long型のサイズは " << sizeof(long long) << " バイトです。" << endl; long long l; // 変数の宣言(ローカル変数の初期値は不定) int l2 = 999; // 初期値を付けた宣言 cout << "初期値の確認(lは不定) l=" << l << " l2=" << l2 << endl; // long long の最大数 l = 0x7FFFFFFFFFFFFFFF; cout << "long long で表せる最大数は " << l << " です。"<< endl; cout << "それは LONG_MAX で定義されています。 " << LONG_MAX << endl; l = 0x8000000000000000; cout << "long long で表せる最小数は " << l << " です。"<< endl; cout << "それは LONG_MIN で定義されています。 " << LONG_MIN << endl; unsigned long long m = 0xFFFFFFFFFFFFFFFF; cout << "unsigned longlong で表せる最大数は " << m << " です。"<< endl; //////////////////////////////// // char型 //////////////////////////////// cout << endl << "-- char型 --" << endl; // char は1バイトで文字または数値を表すデータ型 cout << "char型のサイズは " << sizeof(char) << " バイトです。" << endl; char c; // 変数の宣言(ローカル変数の初期値は不定) int c2 = 'a'; // 初期値を付けた宣言 cout << "初期値の確認(cは不定) c=" << c << " c2=" << c2 << endl; // coutでは数値として扱われる cout << "c2を数として出力すると " << (int)c2 << endl; cout << "c2を文字として出力すると " << (char)c2 << endl; // 数値データとしての char の最大数 c = 0x7F; cout << "char で表せる最大数は " << (int)c << " です。"<< endl; c = 0x80; cout << "char で表せる最小数は " << (int)c << " です。"<< endl; unsigned char c3 = 0xFF; cout << "unsigned char で表せる最大数は " << (int)c3 << " です。"<< endl; //////////////////////////////// // bool型 //////////////////////////////// cout << endl << "-- bool型 --" << endl; // bool は1バイトで論理(真偽)を表すデータ型 cout << "bool型のサイズは " << sizeof(bool) << " バイトです。" << endl; bool b; // 変数の宣言 b = true; // 値を代入(trueは1の値を持つ) if (b) cout << "b は" << b << "です。" << endl; else cout << "b は" << b << "です。" << endl; b = false; // 値を代入(falseは0の値を持つ) if (b) cout << "b は" << b << "です。" << endl; else cout << "b は" << b << "です。" << endl; //////////////////////////////// // 浮動小数点 //////////////////////////////// cout << endl << "-- 浮動小数点 --" << endl; // 浮動小数点 cout << "float型のサイズは " << sizeof(float) << " バイトです。" << endl; cout << "double型のサイズは " << sizeof(double) << " バイトです。" << endl; unsigned long long ull=1; for (int i=0; i<60; i++) ull = ull * 2; double d; d = pow(2, 60); // 標準関数pow()はdouble型の結果を返す cout << "整数型で計算した2の60乗は " << ull << " ですが、" << endl; cout << "doubleで計算した2の60乗は " << d << " になります。" << endl; cout << "浮動小数点を使うと桁落ち誤差が生じるので注意。" << endl; //////////////////////////////// // キャスト //////////////////////////////// cout << endl << "-- キャスト --" << endl; // キャスト i = INT_MAX; l = (long long)i; cout << "intをlong longにキャストします。 i=" << i << " l=" << l << endl; l = LONG_MAX; i = (int)l; cout << "long longをintにキャストします。 l=" << l << " i=" << i << " 桁あふれで失敗します。" << endl; //////////////////////////////// // 定数 //////////////////////////////// cout << endl << "-- 定数 --" << endl; i = 255; cout << "i は " << i << " です。" << endl; i = 0xFF; cout << "16進で書いても i は " << i << " です。" << endl; i = 0b11111111; cout << "2進で書いても i は " << i << " です。" << endl; i = 0377; cout << "8進で書いても i は " << i << " です。" << endl; cout << endl; char ch; ch = 'a'; cout << "ch は " << ch << " です。" << endl; ch = 'a'; cout << "ch は数字で表すと " << (int)ch << " です。" << endl; ch = 'a'; cout << "ch と「c」の差分は " << 'c' - ch << " です。" << endl; cout << endl; char str[80] = "abc"; cout << "str は " << str << " です。文字列は文字(char)の配列です。" << endl; cout << "配列として扱えば、2文字目(添字は1)は " << str[1] << " です。" << endl; str[1] = 'X'; cout << "配列として扱って変更もできます。2文字目(添字は1)を変更すると " << str << " となります。" << endl; return 0; } |
演算
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
#include <bits/stdc++.h> using namespace std; int main() { int i, j; i = 8; j = 5; cout << "--- 演算" << endl; cout << "足し算 " << i + j << endl; cout << "引き算 " << i - j << endl; cout << "掛け算 " << i * j << endl; cout << "割り算 " << i / j << endl; cout << "割った余り " << i % j << endl; cout << "最大値 " << max(i, j) << endl; cout << "最小値 " << min(i, j) << endl; cout << i << " をポストインクリメント " << i++ << " もう一度見ると " << i << endl; cout << i << " をプリインクリメント " << ++i << endl; cout << i << " をポストデクリメント " << i-- << " もう一度見ると " << i << endl; cout << i << " をプリデクリメント " << --i << endl; // 「X 演算子= Y」は「X = X 演算子 Y」と同じ。 cout << "--- 演算子= " << endl; i = 5; i += 2; cout << "足し算 " << i << endl; i -= 1; cout << "引き算 " << i << endl; i /= 2; cout << "割り算 " << i << endl; i *= 2; cout << "掛け算 " << i << endl; bool a, b; a = true; b = false; cout << "--- 論理演算" << endl; cout << "真 " << a << endl; cout << "偽 " << b << endl; cout << "真の否定 " << !a << endl; cout << "偽の否定 " << !b << endl; cout << "論理和 " << (a || b) << endl; cout << "論理積 " << (a && b) << endl; // 0はfalse、非0はtrueとして機能する cout << (0 ? "true" : "false") << endl; cout << (1 ? "true" : "false") << endl; i = 0b0011; j = 0b0110; cout << "--- ビット演算" << endl; cout << "ビット表現 " << i << ' ' << j << endl; cout << "ビット反転 " << ~i << ' ' << ~j << endl; cout << "ビット論理和 " << (i | j) << endl; cout << "ビット論理積 " << (i & j) << endl; cout << "i の下から3桁目を見る " << ((i & (1 << 2)) ? 1 : 0) << endl; cout << "j の下から3桁目を見る " << ((j & (1 << 2)) ? 1 : 0) << endl; cout << "i の下から3桁目を立てる " << (i |= 0b0100) << endl; cout << "i の下から3桁目を落とす " << (i &= ~0b0100) << endl; cout << "ビット左シフト " << (i << 2) << endl; cout << "ビット右シフト " << (j >> 2) << endl; return 0; } |
繰り返しループ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
#include <bits/stdc++.h> using namespace std; #define rep(i, n) for (int i = 0; i < (int)(n); i++) #define range(i, s, e) for (int i = (s); i <= (int)(e); i++) int main() { // for文は (最初に1度実行される; 続ける条件; ループ毎の最後に実行される) と書く // for文は、あとに続く1文、または1ブロックを繰り返す。 // (複数文を繰り返すにはブロックにする) // ループのパラメータ変数(iなど)はfor文内で宣言するとスコープが狭くなり安全。 // (意図的にそうしない場合もある) int N = 3; cout << "---" << endl; cout << "N回繰り返す(0〜N-1)" << endl; for (int i=0; i<N; i++) cout << i << ' '; cout << endl; cout << "rep()を使って、N回繰り返す(0〜N-1)" << endl; rep(i, N) cout << i << ' '; cout << endl; cout << "1からNまで繰り返す(1〜N)" << endl; for (int i=1; i<=N; i++) cout << i << ' '; cout << endl; cout << "range()を使って、1からNまで繰り返す(1〜N)" << endl; range(i, 1, N) cout << i << ' '; cout << endl; cout << "Nから1まで繰り返す" << endl; for (int i=N; 1<=i; i--) cout << i << ' '; cout << endl; cout << "1から10まで奇数だけ繰り返す" << endl; for (int i=1; i<=10; i+=2) cout << i << ' '; cout << endl; cout << "---" << endl; cout << "2重ループ" << endl; for (int i=0; i<3; i++) { for (int j=0; j<4; j++) { cout << "(" << i << "," << j << ") "; } cout << endl; } // 配列の場合、もうひとつのfor文の書き方 cout << "---" << endl; int array[] = {1, 2, 3, 4}; for (int i : array){ cout << i << " "; // iには配列の各要素が入る } cout << endl; // while文は (続ける条件) と書く // while文は、あとに続く1ブロックを繰り返す。 // while (1) {〜} で永久ループを作れる。while(true) {〜} も同等。 cout << "---" << endl; cout << "whileでN回繰り返す(0〜N-1)" << endl; int i = 0; while (i<N) { cout << i << ' '; i++; } cout << endl; cout << "whileで2から10まで偶数だけ出力" << endl; i = 2; while (i<=10) { cout << i << ' '; i += 2; } cout << endl; cout << "whileで10まで奇数だけ出力" << endl; i = 0; while (i<=10) { if (i%2) cout << i << ' '; i++; } cout << endl; // for文やwhile文のループ制御 // continue : 1回のループの残りの処理をキャンセルし、次のループへ進む // break : ループの繰り返しを終了する。直上のループ1つだけ抜ける。 cout << "whileで10まで奇数だけ出力(別解)" << endl; i = 0; while (1) { if (10 < i) { break; // breakで終了 } else if (i%2 == 0) { i++; continue; // continueで継続 } cout << i << ' '; i++; } cout << endl; // do〜while文は do {} (続ける条件); と書く cout << "---" << endl; cout << "do〜whileでN回繰り返す(0〜N-1)" << endl; i = 0; do { cout << i << ' '; i++; } while (i<N); cout << endl; // goto : 指定したラベルへジャンプする。多重ループを抜け出せる。 cout << "---" << endl; cout << "2重ループを抜ける" << endl; for (int i=0; i<3; i++) { for (int j=0; j<4; j++) { cout << "(" << i << "," << j << ") "; if (i+j == 4) goto END_OF_LOOP; // 多重ループの外へジャンプする } cout << endl; } END_OF_LOOP: cout << "2重ループを抜けた" << endl; return 0; } |
配列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
#include <bits/stdc++.h> using namespace std; int main() { // 配列はデータ型と大きさを指定して宣言する int A[3]; int N = 3; int B[N]; // 大きさ指定に変数を使える memset(B, -1, sizeof(int)*N); // 全体を-1で初期化 int C[3] = {10, 20, 30}; // 初期値付きの宣言 int D[3] = {}; // 配列を0で初期化する方法 cout << "---" << endl; cout << "配列に代入、参照" << endl; for (int i=0; i<3; i++) A[i] = i*2; // 配列の要素には添字indexでアクセスする for (int i=0; i<3; i++) cout << A[i] << ' '; cout << endl; cout << "1からNまでのデータを扱う(競プロでよくあるパターン)" << endl; int S[N+1]; // データ番号をindexに使いたいのでS[0]は使わない。(1始まり) S[0] = 0; for (int i=1; i<=N; i++) S[i] = i; for (int i=0; i<=N; i++) cout << S[i] << ' '; cout << endl; cout << "---" << endl; cout << "元データ= "; for (int i=0; i<3; i++) cout << A[i] << ' '; cout << endl; cout << "反転= "; reverse(A, A+3); for (int i=0; i<3; i++) cout << A[i] << ' '; cout << endl; cout << "ソート= "; sort(A, A+3); for (int i=0; i<3; i++) cout << A[i] << ' '; cout << endl; cout << "降順ソート= "; sort(A, A+3, greater<>()); for (int i=0; i<3; i++) cout << A[i] << ' '; cout << endl; cout << "---" << endl << "2次元配列" << endl; int array[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}}; for (int i=0; i<3; i++) { for (int j=0; j<4; j++) { cout << array[i][j] << ' '; } cout << endl; } return 0; } |
ポインタ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
#include <bits/stdc++.h> using namespace std; int main() { // &は参照を表す(参照=そのデータのアドレス) int a = 9; cout << "a の値 " << a << endl; cout << "a の参照 " << &a << endl; cout << "---" << endl; // 配列の名前は、配列の先頭アドレス(つまり参照) int A[5] = {10, 20, 30, 40, 50}; cout << "A[0] の値 " << A[0] << endl; cout << "A[1] の値 " << A[1] << endl; cout << "A の値(参照に相当)" << A << endl; cout << "---" << endl; // *はポインタの指す内容 int *p; // intのポインタp p = &a; cout << "p の値 " << p << endl; cout << "p の指す値 " << *p << endl; *p = 55; // aのアドレスに値を書き込む cout << "a の値 " << a << endl; cout << "---" << endl; // ポインタを増減して配列の要素にアクセス p = A; for (int i=0; i<5; i++) cout << *(p+i) << ' '; cout << endl; for (int i=0; i<5; i++) cout << *p++ << ' '; cout << endl; return 0; } |
配列のlower_bound
lower_boundは、ソートされた配列内で、key以上の要素の内の一番左側のイテレータを返す。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
#include <bits/stdc++.h> using namespace std; int main() { int A[] = {1, 3, 3, 5, 5, 7}; // ソートされている必要がある for (auto i : A) cout << i << " "; int a_size = sizeof(A)/sizeof(*A); // 配列の大きさの取り方 cout << "(size=" << a_size << ")" << endl; // A[] からkeyの位置を知る int keys[] = {3, 4, 7, 8}; for (int key : keys) { cout << "(" << key << ")を探すと、"; int idx = lower_bound(A, A+a_size, key) - A; // A[]のindexが得られる if (idx < a_size) { cout << "A[" << idx << "]に(" << A[idx] << ")が見つかりました。"<< endl; } else { // 見つからなかったら配列サイズより大きいindexが返される cout << "見つかりませんでした。" << endl; } } return 0; } |
char配列の文字列
シングルクォートで囲まれた ‘a’ はひとつの文字(半角文字)。ダブルクォートで囲まれた “abc” は文字列。”a” と ‘a’ は異なる。文字列の末尾には終端記号として ‘\0’ が存在する。文字列は char の配列として扱う。後に述べる string でも文字列を扱うことができる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
#include <bits/stdc++.h> using namespace std; //#include <stdlib.h> int main() { // 宣言 // charの配列に文字列を格納できる。配列の大きさを指定する。 char s1[80]; cout << "s1[80]のサイズ=" << sizeof(s1) << endl; // 初期値を設定。 char s2[80] = "abc"; cout << "s2[80]のサイズ=" << sizeof(s2) << " 内容=" << s2 << " 文字列長=" << strlen(s2) << endl; // 大きさを指定しないと初期値+1となる。+1は'\0'が存在するから。 char s3[] = "abc"; cout << "s3[]のサイズ=" << sizeof(s3) << " 内容=" << s3 << " 文字列長=" << strlen(s3) << endl; // charのポインタ定数として宣言しても同様 const char *s4 = "abc"; cout << "s4の内容=" << s4 << " 文字列長=" << strlen(s4) << endl; cout << "---" << endl; // 文字列の扱い char s[80] = "abc"; // '\0'を目印にして繰り返す for (int i=0; s[i]!='\0'; i++) cout << s[i] << ' '; cout << endl; // 文字数だけ繰り返しても同じ。 for (int i=0; i<strlen(s); i++) cout << s[i] << ' '; cout << endl; // ポインタを介しても同じ for (char *p=s; *p!='\0'; p++) cout << *p << ' '; cout << endl; // 1文字ずつ操作して文字列を作れる s[0] = 'x'; s[1] = 'y'; s[2] = 'z'; s[3] = '\0'; // 終端記号を忘れない cout << "1文字ずつ操作して作った文字列=" << s << endl; // 文字列のコピーはstrcpy()関数 strcpy(s1, s); // 第1引数がコピー先 cout << "コピーされた値=" << s1 << endl; // char配列の文字列を数値に cout << "文字列の100を数値では " << atoi("100") << endl; strcpy(s2, "99"); cout << "s2に格納された文字列を数値では " << atoi(s2) << endl; return 0; } |
条件式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
#include <bits/stdc++.h> using namespace std; int main() { // 条件が満たされれば指定範囲が実行される if (true) { cout << "条件はtrueである。" << endl; } // if文が影響するのは次に続く1文、または1ブロック // ★よくある間違い★ if (false) cout << "条件はfalseである(1)" << endl; // ここはif文の中 cout << "条件はfalseである(2)" << endl; // ここはif文の外(実行されてしまう) int a = 2; int b = 5; if (a < 3) { // 条件がtrueなら cout << "aは3未満" << endl; // ここが実行される } else if (b < 3) { // 次の条件がtrueなら cout << "bは3未満" << endl; // ここが実行される } else { // いずれの条件も満たさなければ cout << "どの条件も満たさない。" << endl; // ここが実行される } // orは|| andは&& if (true && true){ // AND条件 ; } else if (true || true){ // OR条件 ; } // switch文の使い方 char command[] = "abbdcxyzab"; bool break_flag = false; for (char c : command) { switch (c) { case 'a': // breakが無いので次の'b'の処理に進むことに注意 case 'b': cout << c << endl; // 'a'または'b'ならここが実行される break; // switch文を抜ける case 'x': cout << "xを検出したので中断" << endl; break_flag = true; break; // このbreakはswitch文を抜けるが、for文は抜けないことに注意 default: cout << "a,b以外の文字" << endl; break; } if (break_flag) break; } } |
関数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
#include <bits/stdc++.h> using namespace std; // 関数はmain()関数より前(上)で宣言しなければならない。 // 関数は型を持ち、その型の値をリターン値として返す。 // リターン値を返さない関数はvoid型として宣言する。 // 関数の引数は型を持つ // void型の関数の例 void outputSum(int n, int m) // 引数は2つ { cout << n + m << endl; // 合計を表示する return; // リターン値を書く必要なし。return文そのものも無くても構わない。 } // int型の関数の例 int getSum(int n, int m) // 引数は2つ { int sum; sum = n + m; return sum; // 合計をリターン値として返す } // 間違った1増やす関数(値渡し) void wrongIncrement(int n) { n++; } // 正しい1増やす関数(参照渡し) void correctIncrement(int *n) { (*n)++; } // 再帰関数でnまでの和を求める long long get_sum(int n) { if (n <= 0) return 0LL; // 負の値への例外処理も兼ねる if (n == 1) return 1LL; return (long long)n + get_sum(n-1); } // 再帰関数でnの階乗を求める long long get_kaijo(int n) { if (n<=1) return (long long)1; return (long long)n * get_kaijo(n-1); } int main() { // void型の関数を呼ぶ outputSum(10, 20); // int型の関数から値を受け取る int a = getSum(15, 25); cout << "合計は" << a << endl; // 値渡しと参照渡し a = 2; wrongIncrement(a); // aという変数の「値」を与えている cout << "a=" << a << endl; // 関数の中で変更しても影響しない correctIncrement(&a); // aという変数の「参照」を与えている cout << "a=" << a << endl; // 関数の中の処理が影響する // 再帰関数 cout << 10 << " の累積和は " << get_sum(10) << endl; cout << 10 << " の階乗は " << get_kaijo(10) << endl; // main()関数自体もint型の関数なので数値を返す return 0; } |
構造体
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
#include <bits/stdc++.h> using namespace std; // Personという構造体を定義する。メンバは名前と年齢。 struct Person { string name; int age; }; int main() { // Personの配列。大きさは2。 Person family[2]; // 構造体に値を設定する family[0].name = "山田一郎"; family[0].age = 40; family[1].name = "田中花子"; family[1].age = 37; // 構造体の値を参照する for (auto p : family) { cout << "name=" << p.name << endl; cout << "age=" << p.age << endl; } return 0; } |
クラス
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
#include <bits/stdc++.h> using namespace std; // クラスPersonを定義する class Person { public: // 外部から直接参照できるようにpublic宣言 string name; int age; // メンバ関数の宣言 void disp(); }; // この;忘れがちなので注意 // メンバ関数(Person::を省いてクラスの内部に書いても良い) void Person::disp() { cout << name << " さんの年齢は " << age << " 歳です。" << endl; } int main() { // インスタンスを作る auto a = Person(); // 値を設定、参照 a.name = "山田一郎"; a.age = 40; cout << "a.name = " << a.name << ", a.age = " << a.age << endl; // メンバ関数を呼び出す a.disp(); } |
数値操作
数値の操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
#include <bits/stdc++.h> using namespace std; int main() { // 整数の桁の扱い int num = 1234; cout << "データ=" << num << endl; cout << "桁数=" << int(log10(num)+1) << endl; // 4 cout << "---" << endl; cout << "1桁目=" << num % 10 << endl; // 4 cout << "2桁目=" << (num / 10) % 10 << endl; // 3 cout << "3桁目=" << (num / 100) % 10 << endl; // 2 cout << "4桁目=" << num / 1000 << endl; // 1 cout << "---" << endl; cout << "下の桁から順に取り出す" << endl; while (0 < num) { cout << num % 10 << endl; num /= 10; } cout << "---" << endl; // 整数の割り算 int a = 10, b = 3; cout << "10/3を切り上げ=" << (a + (b - 1)) / b << endl; // 4 cout << "10/3を四捨五入=" << (a + (b / 2)) / b << endl; // 3 cout << "---" << endl; // 浮動小数点 double d = 1.234; cout << "1.234を切り上げ=" << ceil(d) << endl; // 2 cout << "1.234を切り捨て=" << int(d) << endl; // 1 cout << "---" << endl; // 絶対値 abs(x); cout << "-100の絶対値=" << abs(-100) << endl; // 100 cout << "-12.34の絶対値=" << abs(-12.34) << endl; // 12.34 // 最大値 max(a, b); cout << "最大値=" << max(1, 20) << endl; // 20 cout << "最大値=" << max(0.3, 0.5) << endl; // 0.5 cout << "最大値=" << max({1, 6, 10, 2}) << endl; // 10 // 最小値 min(a, b); cout << "最小値=" << min(1, 20) << endl; // 1 // 値を交換する(他の型でも同様) a = 1; b = 5; cout << "a=" << a << " b=" << b << endl; swap(a, b); cout << "a=" << a << " b=" << b << endl; // xのy乗 pow(x, y); ※pow()の結果はdouble型。桁落ち誤差に注意。 cout << "pow(3, 2)=" << pow(3, 2) << endl; // 9 // ルートx sqrt(x); cout << "sqrt(2)=" << sqrt(2) << endl; // 1.41421 // 最大公約数、最小公倍数 cout << "最大公約数=" << __gcd(4, 6) << endl; // 2 cout << "最小公倍数=" << 4 / __gcd(4, 6) * 6 << endl; // 12 // 乱数 //srand(0); // 乱数の種を指定 //srand(time(NULL)); // 乱数の種に時刻を使う cout << "乱数=" << rand() << endl; cout << "1から10の乱数=" << rand() % 10 + 1 << endl; cout << "1以下の乱数=" << (double)rand()/RAND_MAX << endl; // 三角関数(ラジアンを使用) #define RAD(a) ((double)(a)*M_PI/180.0) cout << "sin(45度)=" << sin(RAD(45)) << endl; // 0.7.. cout << "cos(45度)=" << cos(RAD(45)) << endl; // 0.7.. cout << "tan(45度)=" << tan(RAD(45)) << endl; // 1 return 0; } |
string
宣言と参照
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
#include <bits/stdc++.h> using namespace std; int main() { // 初期値なしの宣言 string s1; // 長さ(文字数)は正味の値(char配列と異なり、'\0'はカウントされない) cout << "s1=" << s1 << " size=" << s1.size() << endl; // 初期値ありの宣言 string s2("abc"); // コンストラクタで指定 string s3 = "abc"; // 代入しても同じ cout << "s2=" << s2 << " size=" << s2.size() << endl; cout << "s3=" << s3 << " size=" << s3.size() << endl; // 大きさと初期値ありの宣言 string s4(10, 'a'); // 10個の'a'で初期化 cout << "s4=" << s4 << " size=" << s4.size() << " capacity= " << s4.capacity() << endl; // capacityを超えたら自動的に増える s4 += "1234567890"; cout << "s4=" << s4 << " size=" << s4.size() << " capacity= " << s4.capacity() << endl; // 同じ文字を作る cout << "aを5文字=" << string(5, 'a') << endl; // aaaaa // 参照 cout << "---" << endl; string s = "abc"; // 1文字ずつ参照 for (int i=0; i<s.size(); i++) cout << s[i]; // 配列としてアクセス cout << endl; for (int i=0; i<s.size(); i++) cout << s.at(i); // at()でアクセス cout << endl; for (char c : s) cout << c; // charを使う cout << endl; for (auto a : s) cout << a; // autoでもよい cout << endl; // at()で範囲外にアクセスすると例外発生(配列形式のアクセスとの違い) //cout << s.at(3) << endl; cout << "---" << endl; return 0; } |
編集
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
#include <bits/stdc++.h> using namespace std; int main() { string s = "abc"; // stringは文字列のまま代入できる(char配列との違い) string t = s; cout << "代入された=" << t << endl; // stringへの文字追加 s = "abc"; s = s + 'X'; cout << "追加された=" << s << endl; // または s = "abc"; s.push_back('Y'); cout << "push_backされた=" << s << endl; // 文字列をpush_backしたらエラー発生する。 //t.push_back("Y"); s.pop_back(); // push_backの逆 cout << "pop_backされた=" << s << endl; // stringの結合 s = "abc"; s = s + "XYZ"; cout << "結合された=" << s << endl; // 文字列挿入 s = "abc"; s.insert(1, "XYZ"); // 0始まりで指定位置に挿入 cout << "文字列挿入=" << s << endl; // 削除 s = "abcde"; cout << s << endl; s.erase(2, 1); // erase(n, m) n文字目からm文字削除 cout << "2番目から1文字削除=" << s << endl; // "abde" s.erase(1); // erase(n) n文字目以降全削除 cout << "1番目以降全て削除=" << s << endl; // "a" // 検索 s = "abcde"; cout << s << endl; string key = "cd"; int res = s.find(key); if (res == string::npos) cout << key << " は見つかりませんでした。" << endl; else cout << key << " は " << res << " 文字目にあります。" << endl; key = "cd"; res = s.rfind(key); // 後ろから検索 if (res == string::npos) cout << key << " は見つかりませんでした。" << endl; else cout << key << " は " << res << " 文字目にあります。" << endl; // 置換 s = "abcde"; cout << s << endl; s.replace(2, 2, "X"); // 2番目から2文字をXに置換 cout << "2番目から2文字をXに置換=" << s << endl; // "abXe" // 抽出 s = "abcde"; cout << s << endl; cout << "2文字以降=" << s.substr(2) << endl; // 2文字移行を抽出 cout << "2文字以降の2文字=" << s.substr(2, 2) << endl; // 2文字以降の2文字を抽出 return 0; } |
操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
#include <bits/stdc++.h> using namespace std; int main() { // 文字の出現回数を数える string s = "aabcckjatrta"; char ch = 'a'; int count = std::count(s.begin(), s.end(), ch); cout << ch << " は " << count << " 回出現しました。" << endl; // 先頭と末尾の文字 s = "abc"; cout << "front=" << s.front() << " back=" << s.back() << endl; // 反転 reverse(s.begin(), s.end()); cout << "反転文字列=" << s << endl; // ソート sort(s.begin(), s.end()); // 昇順 cout << "昇順ソート結果=" << s << endl; sort(s.begin(), s.end(), greater<>()); // 降順 cout << "降順ソート結果=" << s << endl; cout << "---" << endl; // 文字列から数値へ cout << "文字列100は数として=" << stoi("100") << endl; // 数値から文字列へ cout << "数100は文字列として=" << to_string(100) << endl; return 0; } |
vector
基本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
#include <bits/stdc++.h> using namespace std; struct Point { int x; int y; }; int main() { // vectorの宣言: <型>はclass名なども使用できる vector<int> A; // サイズ指定なし vector<int> B(3); // サイズ指定あり(サイズが分かっている場合) vector<int> C(3 , -1); // サイズ指定、初期値あり(大きさ、すべての要素の初期値) vector<int> num = {10, 50, 100}; // 初期値あり vector<string> str = {"apple", "bird", "cat"}; vector<Point> point(3, {2,3}); // サイズ指定、初期値あり(大きさ, 初期値) // 多重配列 vector<vector<int>> vec(10, vector<int>(10, 0)); // 10x10の2次元vectorを0で初期化 vector<vector<int>> VV = {{1, 2}, {3}}; // 初期値あり vector<vector<vector<int>>> VVV; // 要素があるかどうか調べる if (A.empty()) cout << "A is empty." << endl; // サイズ指定あればemptyではない if (!B.empty()) cout << "B is not empty." << endl; // 要素には添字でアクセス B[0] = 1; B[1] = 2; B[2] = 3; // vectorどうしで代入 A = B; // 末尾に要素を追加 A.push_back(4); // 4を追加 A.push_back(999); // 999を追加 // 末尾の要素を削除 cout << A.back() << " を削除する" << endl; // 末尾の要素の参照 A.pop_back(); // 999を削除 // 参照方法(1) for (int i=0; i<A.size(); i++) cout << A[i] << ' '; cout << endl; // 参照方法(2) for (auto a : |