19日目です。
C++とは
Cの拡張版のコンパイル言語。最新バージョンはC++20
学習はwandboxやpaizaなどのオンライン実行環境がおすすめ
コメント
C++のコメントは2種類ある。
1: // 行コメント
2: /* */ 範囲コメント
//コメント
/*
ここもコメント
*/
コメントじゃない!
範囲コメントの入れ子はできない
*/
Hello World
# include <iostream>
int main(){
std::cout << "Hello World!" << std::endl;
return 0;
}
Hello World!
c++では原則main関数から実行されます。
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>をファイルの頭に書いてください。
[コラム] C++における型
予約語の型(`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++における変数宣言は以下のとおりである。
# 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; エラー 定数に代入などにより変更できない
配列
配列は次のように宣言、使用する。
# 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,
}
[コラム] 生配列
# 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] << ',';
}
文字列
[コラム] 文字列は文字の配列
std::array<char, 64> str{'H', 'e', 'l', 'l', 'o'};
char[64] str2 = "Hello";
また、後述のstringも配列になるため[i]を用いてi番目の文字(char型)を得ることができる
文字列はstringを使う。頭で#include <string>をしてください。
コードは次のようになります。
# include <string>
std::string str = "Hello";
コンテナ
C++には可変長動的配列としてvectorがある。他言語でいうList、ArryListに近い。
#include <vector>を頭に書いてください。
# 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);//末尾に要素を追加
}
演算子
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で割った余り
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
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演算
関数
関数の宣言・定義は次の通りです
//宣言
//戻り値の型 関数名(引数)
int32_t add(int32_t a, int32_t b);
//定義
int32_t add(int32_t, int32_t b){
return a + b; //戻り値は return で返す
}
# include "add.hpp"
//他ファイルで関数を定義した場合、その関数の宣言が書かれたファイル(*.h/*.hpp)をインクルード
int32_t r = add(2, 3); // r is 5
関数の途中にreturnがあると、それ以降は実行されません。
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です。
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
//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
bool Update(){
return system.Update(); //終了するときはfalseが返る
}
int main(){
while(Update()){
//終了操作がされるまで実行される
}
return 0;
}
終わり
追加要望があれば追記します。