C++完全に理解した

Last-modified: 2022-12-04 (日) 01:28:29

完全に理解した
関数を作る喜び

どうせみんなWindowsだからそれ前提で

ダウンロード

Visual Studio Communityをインストールしよう!
これはMicrosoftが開発するプログラム作成のための統合開発環境(IDE)です

  • 統合開発環境では、エディタ(プログラムを書く)、コンパイラ・リンカ(機械語に翻訳・プログラムをつなぐ)、デバッガ(プログラムの動きを見ながら修正する)、リソースエディタ(音声、画像などの作成管理)、プロジェクト管理(複数人や複数のプログラムを管理)、バージョン管理ができるよ!

手順

Visual Studioで検索→Visual Studio Communityを無料ダウンロードして「vs_community...exe」を実行→インストーラーを続行→「C++によるデスクトップ開発」をチェックしてインストール
→7GBくらいダウンロードされる→PCの再起動

Visual Studio

新しいプロジェクトの作成→ 空のプロジェクトを選択し「次へ」→
→ソースファイルを右クリックして「追加→新しい項目」を選択してソース作成→C++ファイルを選択して、ファイル名を付ける .ccpで終わることがC++言語のプログラムであることを意味する
→メモ帳の要領でプログラムを書く

ソリューションとプロジェクト

  • プロジェクトは一つのプログラムのコンパイルや実行のために必要なファイルや設定を管理する仕組み。(ソースコード、ライブラリ関数、画像ファイル、音声…)
  • ソリューションは複数のプロジェクトをまとめて管理する仕組み

試しに打ち込んで見る

#include <iostream>
using namespace std;
int main(void){
     cout << "あなたの一番のお友達アントニーナですにゃん\n";
}

プログラムを打ち終わったらF5キーまたはメニューのデバックからデバックの開始を選択、するとビルド(コンパイルして機械語を作る)が実行される。
ビルドに成功すると黒い画面が出て結果が表示されます。何かキーを押すと実行は終了です

ビルドに失敗した場合プログラムにミスがあります。画面下にミスの原因が書いてありますので修正してビルドしてみるを繰り返しましょう。

C/C++ では、命令の末尾に必ずセミコロン「;」を記す必要がある。
半角の空白を書くべきところに全角の空白を書くとエラーを吐く

初歩的なプログラム

#include <iostream>
#include <cstdlib>//インクルードファイル(工具箱)の指定。ちなみに//の後はコメントとなりプログラムに影響しないからいっぱい書こう
    int main(void)//main文の記述
    {
    std::cout << "Hello World" << std::endl;//関数(じゃないけど)の利用
    exit(0);//関数の利用
    }

変数

int x

で変数を宣言する。変数は値の入る箱であり、コンピュータにわざわざ教えてやらないといけないのだ。

int x = 5;

と書くことで符号あり整数の型の箱を作りxと名付け、そこに5の値を代入したことになる。

定数はconstで定義

const int x=100;

こうすると値を変えられなくなる

変数の型はfloatとかdoubleとか他にもいっぱいあるよ!だいたいは整数を格納できるint型と、小数点以下の数を格納できるdouble型を知っとけばいい。他は使うときに調べてね!
なお、同じ宣言を二度書くとエラーになるので注意。

演算子

足し算+、引き算-、掛け算*、割り算の商/
割り算の余り%、代入=、増分加算++、+=など

  • a++はa=a+1の意味、a+=3はa=a+3という意味です。数学的にあり得ない式だけどそういうものです。

他にも色々あるから調べてみようね!
代入演算子=に注意。イコール(等しい)ではなくコピー(右辺の値を左辺の変数に代入する)と言う意味です
演算子には優先順位(左から順に計算、掛け算は足し算より先に処理、()中は更に優先…)があるけど数学やったことあるならあまり気にしなくて良い。

変数の型変換

暗黙的な型変換、例えば

int x = 3.14;

C++ではこのときdouble型の数である3.14はint型に型変換される。そして小数点以下の数値は切り捨てられる。
つまりx=3である
このdouble型をint型に型変換することは、実際には意図せず行ってしまうことが多い。そのため、double型の数をint型の変数に代入すると、コンパイル時に警告が出る。

変換を意図的に行いたい場合、警告が出るのは鬱陶しいのでそういうときは()内に型を書いたものを用いて明示的に型変換をする。

int x = (int)3.14;   // 3.14 を整数に型変換された3がxに代入
std::cout <<  "x は" << x << "\n";    // x は3

上記はdoubleという小数点も含む「広い」型の数値をintという整数のみの「狭い」型の数値に代入する場合の話であり、最初から「広い」型なら問題なし

for文

同じ命令を何度も繰り返す際に用いられるのがfor文である。

C++で「アントニーナと10回にゃんにゃんするプログラム」を実現すると以下のようになる。

for(int i=0 ; i<10 ; i++){
std::cout << "アントニーナですにゃん\n";
}

こうすると『アントニーナですにゃん』と10回表示される(実際やるときは上の例みたいに#include <iostream>を記述してからmain関数内に書いてね)
中身を説明すると

  • int i=0:10回の回数を数える値の初期化、値はほんとは0でなくてもいいんだ…
  • i<10:いつまでfor文を繰り返すかを示す条件。この場合iが10よりも小さい間繰り返すという条件でこれによりi=0~9の10回を繰り返す。
  • i++:変数iを更新する方法。for文の中の命令を一度実行する度に実行する。この場合実行ごとにi+1される

A.なんで1~10の10回じゃなくて0~9の10回なんですか?
Q.いずれわかるさ…

関係演算子

for文の終了条件を記述する際によく用いられるのが関係演算子である

if文

for文とif文の組み合わせ

for文とif文を組み合わせることで、for文で処理を何度も繰り返す間、if文の判定によりある特定の回に処理を変えるとかできる。
この使い方・考え方はプログラミングでは常套手段です!

関数

関数を探す喜び
関数とは処理をひとまとまりにして名前をつけたもの、つまりプログラムのあるまとまった単位のモジュールである。(z=f(x,y)みたいな感じ)
実はさっきまではmain関数一つだけのプログラムだったりする。main関数とはその様々な関数を呼び出して、ある目的の処理を実行するものなのだ。

与える値(ここては変数 x,y)を引数という。またf(x,y)の答えを返り値という。型もある。
関数は用意されているのもあるし、自分で作ってもいい。用意されてるものはライブラリ関数という

例えば足し算関数を作りたい!と思ったときは

int tasu ( int x, int y ) //返り値の値 関数名 引数
{
int kotae ;  //kotaeというこの関数の中だけ使える変数を宣言
kotae = x + Y ;  //xとyの和をkotaeに代入
return kotae ;  //returnの後の値を返り値として関数を終わる
}

使うときはどこかのプログラム中で

int z;
z = tasu( 3, 5 )	//zには関数の返り値8が代入される

というふうに使う。

よく使う関数にprintf()関数(画面に文字列を入力)とか


関数を探す喜びが味わえたのでここで終わりでも良いんだけど、ここからC++どんどんクソッ!になってくるよ

アドレスとポインタ

あどれす…
メモリはデータを格納する場所とその住所(アドレス)で構成される。
今まで変数という入れ物について扱ってきたが、入れ物の実体はどこにあるのかといえばそれはメモリ上である

(工事中)
変数をメモリ上にどう配置するかはコンパイラの仕事なので、任せておけば問題ナシ!

ポインタ(*演算子)、あるいはポインタ変数とはメモリアドレスを格納できる変数である
(工事中)
なんでこんな事するの…と思われるだろうが、センサやモータなどのI/Oを用いるときはそれらが接続されているメモリアドレスを直接読み書きすることがある。
これができるのはCとC++言語くらいのもので、危ないから最近の言語ではできません(間違えるとすぐ暴走、エラーを起こすから)

値渡しとアドレス、参照渡し

配列

配列は同じ型のデータをひとまとめに取り扱うときに使う。センサのデータ等、複数になるとこれが便利になる。

long int data[1024] //整数1024個
char names[256] //256個分の文字列

使うときは0から始まる添え字を使う

data[0]=100;
data[12]=100;
namae[0]='A';

変数宣言時のみ次の構文が使える

int data[5]={100,200,300,400,500};

こんなの何に使うの?と思うだろう。
例えば音は1次元の信号なので、時間で配列を取る。CD程度の音質ならば44.1kHzで標本化した16bitデータ、1秒分のモノラル音声が入る配列は以下で表現できる。

short int otodata[44100];

多次元配列

「int型4個の配列」が3個あると表現するとき以下のように書く

int data[3][4];

初期化時は次の構文がとれる。

int data[3][4]=
{{1,2,3,4},
{5.6.7.8},
{9,10,11,12}};

例えば測域センサデータ、1000個のデータを1秒に60回計測すると

short int data[60][1000];

となる。多次元配列は行列演算や画像、動画に使えるということだ

連続の物理世界をプログラムで扱うとき、二次元三次元の小さい領域(格子、グリッド、セルといったもの)に量子化して多次元配列として扱う。
物理シミュレーション、ロボットの移動とか気象シミュレーションとか応力計算とかの力学シミュレーションに使えるよ。
ドルフロらしくなってきたね

new演算子とメモリの動的確保

プログラムで使用するメモリは自分で管理するのがC/C++でのプログラミングです!

ナイショの話

プログラムが複雑になればなるほど、メモリリーク (メモリの解放し忘れ) によるバグ起きがちである。というわけで、C++より後に作られた、例えばJavaやC#では

  • ポインタの廃止 (ただしC#ではポインタを使う手段はある)
  • メモリの解放をシステム任せに (deleteが存在しない。自動的なメモリ解放のことをガベージコレクションと言う)

なんかやってる。
やっぱC++はクソだよ
でもメモリ管理の知識は最低限知っていた方が効率的なプログラムを書けるかもね…

スマートポインタ

実は、最近のC++ではスマートポインタという機能がメモリの動的確保の作業をやってくれる。
メモリ上の値をどの変数が使えるかを管理する『責任者』としてスマートポインタが機能してくれる。

メモリの所有権という概念でメモリ管理する。所有権とはメモリ上の値をどの変数が使えるか、という概念でありそれを使うことができる変数は"所有者"と呼ばれる。
所有権が無くなれば値は破棄される。値を持つこと自体が所有権であり、所有者を失えばどんどん自動的に破棄といったことになる。この所有権によりメモリ安全かつ、ガベージコレクションが無くなり効率的となる。

正確なやり方はここに書くにはアレなんで各自ググってくれ

構造体

オブジェクト指向

出た…

  • クラス:変数や関数をまとめて取り扱う。C++では関数が書ける構造体
  • インスタンス:クラスから作成したオブジェクト

継承

うわでた
機能追加した新クラスを作ることを継承という。即ち、元のクラスに機能を追加したクラスを作成できる。
元のクラスを親クラスまたは基本クラス、機能を追加したクラスを子クラスまたは派生クラスと呼称する。そして子クラスは親クラスの機能を引き継ぎさらに新しい機能を持つ。
さらに、多重継承により複数の親クラスの機能を持つ子クラスを作れる。
これによりプログラムの拡張が容易になります!

OpenCVで遊ぼう!

OpenCVはインテルが作ってる画像や動画を扱うライブラリで、無償配布です。

OpenCVを使った顔認識(Haar-like特徴分類器) - Qiita
局所特徴量と統計学習手法による物体検出 (slideshare.net)