参考
以下のサイトを参考にしている。
目的
- C++の基本文法を整理
- プログラミング言語の主流の文法を整理
予備知識
3つの制御構造
制御構造(3) |
---|
順次 |
分岐 |
反復 |
第1章 基本文法(1.00~1.15)
ファイルの主な構造
#include <bits/stdc++.h> // incloudeディレクティブで機能を読み込み
using namespace std; // プログラムを短く書くための機能
int main() {
// 処理
}
入力と出力
複数の入力の場合は、スペースか改行で区切られていれば自動的に分解して入力してくれる。
// 入力
cin >> 変数; // 入口をイメージ
cin >> 変数1 >> 変数2; // 複数を入力
// 出力
cout << 値; // 出口をイメージ
cout << 値 << endl; // 改行を含む
cout << 値1 << 値2 << 値3 << endl; // 複数を出力
2通りのコメント方法
// コメント
/*
コメント
*/
プログラムの主な3つのエラー
エラー(3) | 説明 | |
---|---|---|
コンパイルエラー | 書いたプログラムの文法にミスがあるときに発生するエラー | Compile-Error |
実行時エラー | 実行時エラーとは、プログラムの文法に間違いはなかったが、内容に致命的な間違いがあったときに発生するエラー(例、3÷0のゼロ除算) | Runtime-Error |
論理エラー | プログラムは一見正しく動作しているが、その動作が実は正しくないときに発生するエラー | Wrong-Answer |
1 | 2 | 3 |
---|---|---|
実行時間制限超過 | Time-Limit-Exceeded |
変数を宣言
「データ型」と「変数」を指定
データ型 変数;
データ型 変数 = 値; // 変数の宣言と代入(初期化)
データ型 変数 = 値1, 変数 = 値2; // 同時に複数を宣言
5つのデータ型
データ型(5) | 説明 |
---|---|
int型 | 整数 |
double型 | 小数 |
string型 | 文字列 |
char型 | 文字(1字) |
bool型 | 真偽値 |
int 変数 = 整数;
double 変数 = 小数;
string 変数 = "文字列"; // ダブルクオーテーション
char 変数 = '文字'; // シングルクオーテーション
bool 変数 = 真偽値;
if文で条件分岐(分岐)
if (条件式1) {
//処理1
}
else if (条件式2) {
//処理2
}
else {
//処理3
}
6つの比較演算子(うち2つ)
1 | 2 |
---|---|
== |
等しい |
!= |
等しくない |
// 等しい場合
if (変数 == 値) {
cout << "等しい" << endl;
}
// 等しくない
if (変数 != 値) {
cout << "等しくない" << endl;
}
3つの論理演算子
1 | 2 |
---|---|
!(条件式) | 条件式の結果の反転 |
条件式1 && 条件式2 | 条件式1が真 かつ 条件式2が真 |
条件式1 |
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 |
---|---|
+= |
足して再代入 |
// 以下は同じ
変数 = 変数 + 値;
変数 += 値;
インクリメントとデクリメント
1 | 2 |
---|---|
++ |
値を1ずつ増やす。 |
-- |
値を1ずつ減らす。 |
このように、プログラムを短く書くための記法のことをシンタックスシュガーと言う。
// 以下は同じ
変数 = 変数 + 1;
変数 += 1;
変数++;
while文で繰り返し処理(反復)
while (条件式) {
// 処理
}
for文で繰り返し処理(反復)
for (初期化; 条件式; 更新) {
//処理
}
//N回処理する
for (int i = 0; i < N; i++) {
//処理
}
break;でループを抜ける
breakはループを途中で抜けるための命令です。
// breakがなければこのループはN回まで繰り返す
for (int i = 0; i < N; i++) {
if (条件式) {
cout << "ぬける" << endl;
break; // 条件を満たすと、ループから抜ける
}
// 処理
}
continueでその後の処理をとばして次のループへ行く
continueはその後の処理をとばして次のループへ行くための命令です。
for (int i = 0; i < N; i++) {
if (条件式) {
cout << "とばす" << endl;
continue; // 条件を満たすとき、これより後の処理をとばす
// 処理
}
// 処理
}
「メンバ関数」
文字列の長さ
- 文字列変数.size()
string str = "Hello";
cout << str.size() << endl;
i番目の文字
- 文字列.at(i)
string str = "Hello";
char c = str.at(0); // 0番目のchar型の値が得られる
エスケープシーケンス(\n)
「改行」などの特殊な文字をプログラム中で表現する場合、エスケープシーケンスを利用します。
cout << "こんにちは\nAtCoder";
行単位での入力(getline関数)
cinを使うと空白や改行区切りの入力を簡単に扱えますが、空白で区切らずに行単位で入力を受け取りたいこともあります。
その場合はgetlineを使います。
- getline(cin, 文字列変数);
string s, t;
getline(cin, s); // 変数sで入力を一行受け取る
getline(cin, t); // 変数tで入力を一行受け取る
cout << "一行目 " << s << endl;
cout << "二行目 " << t << endl;
//入力
I have a pen.
I have an apple.
//実行結果
一行目 I have a pen.
二行目 I have an apple.
配列の宣言と、その操作
配列を宣言
//配列の宣言します。
vector<型> 配列名;
//配列の初期化
vector<型> 配列名(要素数);
// 初期値の指定
vector<型> 配列名(要素数, 初期値);
配列を操作します。
配列は文字列のように +=
で要素を追加することはできません。
代わりに配列変数 .push_back()
を使えば、配列の末尾に要素を追加することができます。
//i番目の要素
配列変数.at(i)
//配列の要素数
配列変数.size()
// 要素の追加
配列変数.push_back()
// 要素の削除
配列変数.pop_back()
for文を使った入力
// 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つの関数
// aとbのうち小さい方の値を返す
min(a, b);
// aとbのうち大きい方の値を返す
max(a, b);
// 変数aと変数bの値を交換する
swap(a, b);
// 配列変数をソートする(要素を小さい順に並び替える)
sort(配列変数.begin(), 配列変数.end());
// 配列変数vecの要素の並びを逆にする
reverse(配列変数.begin(), 配列変数.end())l;
配列を渡す形式
関数名(配列変数.begin(), 配列変数.end())
関数を定義
返り値の型 関数名(引数1の型 引数1の名前, 引数2の型 引数2の名前, ...) {
// 処理
return 返り値;
}
// 返り値がない関数
void 関数名(引数1の型 引数1の名前, 引数2の型 引数2の名前, ...) {
// 処理
return;
}
// 引数がない関数
返り値の型 関数名() {
cin >> 変数; // cinで入力
// 処理
return 返り値;
}
第2章 複雑な計算処理の書き方(2.00~2.03)
範囲for文
全ての要素を取り出し終わるとループを抜けます。
for (配列の要素の型 変数名 : 配列変数) {
// 各要素に対する処理
}
ループ構文の使い分け
- 範囲for文:配列の全ての要素に対する処理
- for文:一定回数、繰り返す処理
- while文:条件に合う限り繰り返す処理
多重ループのbreak/continue
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でここに来る
多次元配列と表形式
配列を宣言します。
vector<vector<要素の型>> 変数名(要素数1, vector<要素の型>(要素数2, 初期値));
vector<vector<要素の型>> 変数名(要素数1, vector<要素の型>(要素数2)); // 初期値を省略
// 表の場合
vector<vector<要素の型>> 変数名(縦の要素数, vector<要素の型>(横の要素数));
2次元配列の要素にアクセス
変数名.at(添字1).at(添字2);
// 表の場合
変数名.at(上から何番目か).at(左から何番目か);
配列の要素数の取得
// 縦の要素数を取得
変数.size();
// 横の要素数を取得する
変数.at(0).size();
N×0の二次元配列
後から配列に要素を追加して使う場合などに、N×0の配列を宣言することがあります。
vector<vector<型>> 変数名(N); // 「要素数0の配列」の配列
長方形にならない二次元配列(ジャグ配列)
N×0の二次元配列に後から要素を追加していく場合などに「行毎に要素数の違う二次元配列」ができることがあります。
多次元配列
// 3次元配列の宣言
vector<vector<vector<要素の型>>> 変数名(要素数1, vector<vector<要素の型>>(要素数2, vector<要素の型>(要素数3, 初期値)));
vector<vector<vector<要素の型>>> 変数名(要素数1, vector<vector<要素の型>>(要素数2, vector<要素の型>(要素数3))); // 初期値を省略