プログラミング言語

C++

22 コメント
views
0 フォロー

C++についての情報。

とくに
作成: 2020/06/29 (月) 19:06:59
通報 ...
1
とくに 2020/06/29 (月) 19:10:45 修正
#include <iostream>
using namespace std;
int main(){
   cout << "Hello,World!" << endl;
   return 0;
}

ハイライト表示はC++は非対応か・・・
対応してたわ。cppでいけた。

2
とくに 2020/06/29 (月) 19:14:29

基本情報:C++はC言語の拡張版として作られた。
C言語にオブジェクト指向の機能を追加したもの。
しかし、実際にはC言語のように手続き型の言語としても使用可能である。

3
とくに 2020/06/29 (月) 19:17:44 修正

C++にはいくつかのバージョンが存在しおもにC++03、C++11、C++14、C++17、C++20などがある。
新しいバージョンになるほど新しい機能や文法が取り入れられたりする。

4
とくに 2020/06/29 (月) 19:23:13

定数
C++11以前

const int HOGE = 20;

C++11以降

constexpr int HOGE = 20;

constは単なる定数であり、変数と同じくメモリ上に確保される。
constexprはconstとは違い、コンパイル時に値が決定される。

5
とくに 2020/06/29 (月) 19:30:54 修正

コンパイル時に実行される関数

constexpr int Factorial(int x){
    return (x == 0)? 1 : x * Factorial(x - 1);
}

constexpr int FACT = Factorial(5);
6
とくに 2020/07/02 (木) 17:17:44

列挙型

enum COLORS{
   COLORS_BLUE,
   COLORS_RED,
   COLORS_GREEN,
   COLORS_BLACK,
   COLORS_WHITE,
};

C++11以降では

enum class COLORS{
   BLUE,
   RED,
   GREEN,
   BLACK,
   WHITE,
};

と書ける。

7
とくに 2020/07/02 (木) 17:19:50

使い方
enum

COLORS color = COLORS_BLUE;

enum class

COLORS color = COLORS::BLUE;
8
とくに 2020/07/02 (木) 17:25:35 修正

enumの型はコンパイラの処理系に依存、enum classは規定ではint型と定められている。
C++11以降ではenumでもenum classでも既定の型を指定可能。
enum

enum COLORS : int{ //int型が既定の型になる。
   COLORS_BLUE,
   COLORS_RED,
   COLORS_GREEN,
   COLORS_BLACK,
   COLORS_WHITE,
};

enum class

enum class COLORS : char{ //char型が既定の型になる。
   BLUE,
   RED,
   GREEN,
   BLACK,
   WHITE,
};
9
とくに 2020/07/02 (木) 18:42:44

std::stringについて
std::stringはC++の標準ライブラリの一つである。
文字列の処理をより簡便に行えるようにしたもの。
C言語ではこれがない為に文字列の処理は非常に面倒な上、メモリの確保を間違えれば直ぐにバッファオーバランが発生する危険性があった。

10
とくに 2020/07/02 (木) 19:10:52 修正

C言語のコード

#include <stdio.h>

int main(){
   char *str1 = "Hello,World!"; //文字列の定義
   printf("%s\n",str1); //文字列を表示
   char *str2 = "Hello,World!";
   if(strcmp(str1,str2) == 0){ //文字列の比較
       printf("文字列は一致\n");
   }else{
       printf("文字列は不一致\n");
   }

   char str3[16];
   strcpy(str3,str1); //文字列のコピー(十分なメモリを確保しておかないとここでバッファオーバーランが発生。)
   printf("%s\n",str3); //Hello,World!

   char str4[64];
   strcpy(str4,"abcdef");
   strcat(str4,"ghijkl"); //文字列の連結
   printf("%s\n",str4); //abcdefghijkl
   return 0;
}

C++のコード(std:stringを使用)

#include <iostream>
#include <string> //std::stringを使う為に必要
using namespace std;

int main(){
    string str1 = "Hello,World!"; //文字列の定義
    cout << str1 << endl; //オペレータ<<がオーバーロードされている為、普通にcoutで表示できる。
    string str2 = "Hello,World!";
    if(str1 == str2){ //文字列の比較オペレータ==が定義されているので比較可能。
        cout << "文字列は一致" << endl;
    }else{
        cout << "文字列は不一致" << endl;
    }

    string str3;
    str3 = str1; //文字列のコピー。オペレータ=が定義されているので可能。
    cout << str3 << endl; //Hello,World!

    string str4 = "abcdef"; //初期化も可能
    str4 += "ghijkl"; //文字列の連結オペレータ+=が定義されているので可能。str4 = str4 + "ghijkl";でもできる。
    cout << str4 << endl; //abcdefghijkl
    return 0;
}
11
とくに 2020/07/02 (木) 19:21:00

const char*の値が欲しい時は

string str = "abcdef";
const char *cStr = str.c_str();

で可能である為、引数がconst char*である関数に渡すことができる。

12
とくに 2020/07/03 (金) 15:59:35

ラムダ式

auto func = []{
	cout << "ラムダ式" << endl;
};

func();
13
とくに 2020/07/03 (金) 16:06:02

引数を取ることも可能

auto func = [](int n, int m){
	cout << n + m << endl;
};

func(10.20);

戻り値を明示

auto func = [](int n, int m)->int{
	return n + m;
}

int sum = func(10,20);
14
とくに 2020/07/03 (金) 16:22:29

キャプチャ

int a = 10;

//ラムダ式のスコープ外の変数を使用するには変数のキャプチャを指定する。
auto func1 = [a]{ //変数aを指定
	cout << a << endl;
}

auto func2 = [a]{
	a = 5; //コピーしたキャプチャは書き換えられない。
}

auto func3 = [a]()mutable{
	a = 5; //mutable属性を指定すれば書き換えることができる。
}

auto func4 = [&a]{
	a = 7; //参照キャプチャは書き換えられる。
}

int x = 20,y = 4,z = 98;

auto func5 = [=]{
	cout << x << "," << y << "," << z << endl; //複数の変数をキャプチャするには=を使う
}

auto func6 = [&]{
	cout << x << "," << y << "," << z << endl; //参照でも同様。
}

auto func7 = [a,x,&y,&z]{
	cout << a << "," << x << "," << y << "," << z << endl; //個別に指定することも可能。
}
15
とくに 2020/07/03 (金) 16:38:59

std::functionを使ってもラムダ式を代入可能。

#include <iostream>
#include <functional>

using namespace std;
int main(){
	function<void()> func = []{
		cout << "Hello,World!" << endl;
	}

	func();

	function<int(int,int)> sum = [](int x,int y){
		return x + y;
	}

	int ans = sum(20,30);
	cout << ans << endl;
}
16
とくに 2020/07/03 (金) 23:24:03 修正

std::vectorは可変長配列である。
通常の配列とは異なり、自由に配列の長さを変えることができる。
また、イテレータを扱えたりと色々便利な関数が用意されている。

17
とくに 2020/07/03 (金) 23:26:55

std::vectorの定義

std::vector<int> arr1; //int型の配列を宣言
std::vector<double> arr2; //double型の配列を宣言
std::vector<std::string> srr3; //string型の配列を宣言
18
とくに 2020/07/03 (金) 23:31:12

要素を追加・アクセス

std::vector<int> arr;
arr.push_back(10); //10が追加
arr.push_back(20); //20が追加
int a = arr[0]; //0番目の要素にアクセス
int b = arr.at(1); //at関数でもアクセス可
19
とくに 2020/07/03 (金) 23:35:28

要素アクセスの[]とatの違いは範囲チェックを行うかどうか。
[]は範囲チェックを行わないので、範囲外を見に行った時にバッファオーバランが発生するときがある。
atは範囲チェックを行うので範囲外を見に行くとstd::out_of_range例外が投げられる。

20
とくに 2020/07/03 (金) 23:53:11

初期化方法

std::vector<int> arr1; //空のvectorオブジェクトを生成
std::vector<int> arr2(5,10); //5つの要素を持ち、全て10で初期化
std::vector<int> arr3(arr2.begin(),arr2.end()); //vectorのイテレータから初期化arr2と同じ内容のvectorが作成される
std::vector<int> arr4(arr3); //コピー

int nums[] = {10,5,6,7,9};
std::vector<int> arr5(std::begin(nums),std::end(nums)); //普通の配列から生成
std::vector<int> arr6 = {3,8,10,9,7}; //初期化リストから生成
21
とくに 2020/07/07 (火) 21:34:43

int型の値を1バイトずつ切り分ける。

#include <iostream>
using namespace std;
int main(){
    int a = 0x7fffffff;
    char *p = (char*)&a; //char*に変換
    for(int i = 0;i < sizeof(int);i++){
        cout << (void*)p[i] << endl;
    }
    return 0;
}
22
とくに 2020/07/07 (火) 21:38:33

表示される順番は環境依存。
リトルエンディアンとビックエンディアンがある。
リトルエンディアン(LE)は下位バイトから順にメモリに書き込む。
ビックエンディアン(BE)は上位バイトから順にメモリに書き込む。

0xfeac9845
LE→45 98 ac fe
BE→fe ac 98 45