サイトアイコン CV & Technologies

C++の基本

C++のプログラムは、int main()で始まります。プログラムの最後には「return 0;」を必ず書きます。行の終わりにはセミコロン「;」を書かなくてはなりません。典型的なプログラムは以下のようになりますが、このプログラムは何もしません。またスラッシュ2つを続けて書くことで、その行のそれ以降の文字が意味を持たなくなり、コメントとなります。

int main(){
    return 0; //プログラムの終わり
} 

変数の型と宣言

C++に限らず、プログラミング言語では変数を扱います。C++では整数型、浮動小数点型、文字列型などがあります。整数を入れておくにはintという型、小数点を含む数を入れておくにはdoubleという型、文字列を入れておくにはcharという型を使います。ただし、charにはアスタリスク「*」をつけます。最初に変数を使うことを宣言しなくてはなりませんが、宣言するときには、型 変数名 の順で書きます。下の例では、「number」「number2」「output_text」は変数の名前です。定義すると同時に値を入れていますが、これを初期化しているといいます。初期化した後でも、等号によって代入することで変数の値を変えることができます。

int number = 6;
double number2 = 3.5;
char* output_text = "output.txt";
number = 12; //値を変更

配列

同じ型の変数を何個も宣言する代わりに配列を使うと便利です。[ ]の中の数字をインデックスと言いますが、この数の分だけ同じ型の変数を入れておくことができます。ただし、インデックスは必ず0から始まることに注意してください。下の例では100個のint型の変数を配列として宣言し、配列中のインデックス0、1、6、99に0、10、100、1000を代入している例です。繰り返しますがnumber[100]は存在しません。インデックスは1つ目が0から始まって100個目は99だからです。

int number[100];
number[0]=0;
number[1]=10;
number[2*3]=100
number[99]=1000;

四則演算と余りの計算

数値やint、double型のような数値を入れてある変数には、+ – * / 演算子により加減乗除を行うことができます。また%演算子は余りを求めます。

int number = 6; 
number = 6*12; // 72
number = 6/3; // 2
number = 3/2; // 注意 1.5ではなく1となる int型は整数型なので切り捨てた数値が入る
number = 2+4; // 6
number = number + 1; // 7
number += 1; // 8 上と同じ意味
number ++; // 9 上と同じ意味
number = number * 3; // 27
number *= 3; // 81 上と同じ意味
number = 20%3 // 2 すなわち20を3で割ったときの余り 

比較演算子

数値どうしを比較するために用います。等しいことを表すには等号を2つ重ねることに注意してください。
a == b  aとbが等しい
a != b  aとbが等しくない
a < b   aがbより小さい
a <= b  aがbと等しいかbより小さい
a > b   aがbより大きい
a >= b  aがbと等しいかbより大きい

if-else文

条件によって処理を分けたい場合に使います。else if(条件){処理;}の部分はいくつでも可能です。

if(number == 1){
    //ここにnumberが1の場合の処理を書く
}else if(number ==2){
    //ここにnumberが2の場合の処理を書く
}else if(number ==3){
    //ここにnumberが3の場合の処理を書く
}else{
    //ここにnumberが1でも2でも3でもない場合の処理を書く
}

for文

決められた回数だけ同じ処理を繰り返したい場合に使います。for(int i=0; i<100; i++)というように書きます。これは、「iを0から始めてiが100より小さい限り続ける繰り返しで、1回繰り返すごとにiを1ずつ増やしていく」ということを表しています。このときのiをループインデックスと言いますが、ループインデックスは任意の変数名が可能で、ループ中でその値を利用できます。以下の例では0~99の100個の数(注意:100は含まれません!)の和と二乗和を求めています。

int sum=0;
int square_sum=0;
for(int i = 0; i<100; i++){
    sum += i;
    square_sum += i * i;
}

while文

ある条件を満たす限り同じ処理を繰り返したい場合に使います。while(num<100)というように書きます。下の例は上のfor文と全く同じ動きをします。

int i=0;
int sum=0;
int square_sum=0;
while(i<100){
    sum += i;
    square_sum += i * i;
    i++;
}

C++標準ライブラリ

C++には標準ライブラリというものがあり、様々なアルゴリズムやデータ構造を難しいプログラミングをせずに利用できます。非常に多種類のアルゴリズムがありますが、特に重要なものでOpenCVプログラミングでよく使うのはiostream、vector、math.h、の3つでしょう。

インクルード

例えば、vectorライブラリを使うときには、#include をプログラムの先頭に書きます。int main()よりも前です。これによってライブラリをインクルード、すなわち取り込んだことになり、そのライブラリ内のアルゴリズムを使えるようになります。

名前空間

標準ライブラリを使うときには、#include 文の後にusing namespace std; という文を書くようにしてください。これがないと後で標準ライブラリ内の関数を使ったときに、その関数が標準ライブラリのものなのかわからないというエラーになります。

iostream

入力、出力を簡単に行うことができます。cinは入力関数、coutは出力関数です。これらの関数は「>>」または「<<」という特殊な演算子を使用します。下の例では入力した数字を4倍してから出力します。なお、endlは改行するときに使います。

#include <iostream>
using namespace std;
int main(){
    double num=0;
    cin>>num;
    cout<<num*4<<endl;
    return 0;
}

vector

大きさが自由に変えられる可変長配列を宣言できます。vectorを扱う関数はたくさんありますが、よく使うのは、要素数を返すsize()、任意番目の要素にアクセスするat()、末尾に追加するpush_back()、末尾を削除するpop_back()、要素をすべて削除するclear()関数だと思います。るclear()関数だと思います。

#include <stdio.h>
#include <vector>
using namespace std;
int main(){
    vector<int> vec; //vecという名前のint型の可変長配列を宣言
    vec.push_back(10); //末尾に10を追加
    vec.push_back(12); //末尾に12を追加
    vec.pop_back(); //末尾を削除(12を削除)

    vec.push_back(12); //末尾に12を追加
    vec.push_back(15); //末尾に15を追加
    for(int i=0; i<vec.size();i++){ //vecのすべての要素に繰り返し処理をする
        printf("%d\n",vec.at(i)); //i番目の要素を出力
    }
    vec.clear(); //要素をすべて削除
    return 0;
}

math.h

数学的な計算を簡単に行えます。三角関数のsin、cos、tan、さらにこれらの逆関数のasin、acos、atanの他、累乗計算を行うこともできます。最もよく使うのが、累乗計算のpow関数かもしれません。実はこのpow関数を使って平方根を計算できます。平方根を取るにはどうすれば良いでしょうか??(答えはこちら)

#include "math.h"
using namespace std;
int main(){
    double value = cos(3.141592); //余弦を求める
    value = acos(0.5); //逆余弦を求める
    value = fmax(1.3,2); //最大値を求める
    value = pow(2,3); //累乗を求める ここでは2の3乗で8
    copysign(-5,value); //valueの絶対値に-5の符号をつける
    return 0;
}

random

乱数を作る時に用います。このライブラリは様々な性質を持つ乱数を生成できますが、ここでは最も簡単に使える、random_deviceの用法だけ紹介します。random_device rnd; というようにしたあとに、rnd()とすれば、乱数が生成されます。この乱数は最小値0、最大値4294967295を持ちます。ちなみに、4294967295は232-1の値です。以下のコードでは、出力する乱数の範囲を0~1にするために、最大値4294967295で割っており、forを使って10個の乱数を出力しています。このrandom_device関数で得られる乱数は、区間内で全ての実数が同じ確率で現れる一様乱数となります。

#include <random>
#include <iostream>
using namespace std;
int main()
{
    random_device rnd;
    for (int i = 0; i < 10; i++) {
        cout << rnd()/4294967295.0 << endl;
    }
    return 0;
}

大量のデータを扱うために

一度に何百枚もの写真を処理したり、長い動画ファイルを処理したりするなら、結果をファイルに保存するのはほぼ必須と言っても良いでしょう。このステップでファイル出力をマスターしましょう。準備としてWindowsのVisual Studioでは先頭に#define _CRT_SECURE_NO_WARNINGSと記述する必要があります。これは警告を抑制するという意味です。_CRT_SECURE_NO_WARNINGSをdefineしない場合、複数のプログラムで同じファイルを開いた時に衝突することを警告するためにプログラムが動きません。

#define _CRT_SECURE_NO_WARNINGS

ファイルに出力する

ファイルを開くfopen()関数、ファイルに書き込むfprintf()関数、ファイルを閉じるfclose()関数を使います。出力する文字列に変数の値を含めることができます。変数の内容を書き出すには文字列中に %d などの記号をひとまず置いておき、後からその場所に変数の値を入れ込んでファイルに書き込みます。例えば、xの値が10である時に、fprintf(fp, “xの値は%dです\n”,x); と書けば、”xの値は10です”と出力されます。整数値の時には %d を使いますが、浮動小数点型の時には %f を使います。それから、プログラムの終了前にfclose()関数でファイルを閉じるのを忘れないようにしてください。WindowsとMacでファイルへのパスの記述法が異なるので注意が必要です。また、%を出力したい時には%%というように2つ重ねる必要があります。

#include <stdio.h>
using namespace std;
int main(){
    FILE* fp; //ファイルの場所を保持する入れ物 FILE*は型の名前
    //下は出力するテキストファイルのパスを指定する文
    char filename[] = "output¥¥output.txt"; //Windowsの場合 パス中の¥は重ねて¥¥とする
    char filename[] = "output/output.txt"; //Macの場合
    fp = fopen(filename, "w"); //"w"は書き込み可能な状態でファイルを開くことを指定
    for(int i=0; i<10;i++){
        fprintf(fp, "%dの2乗は%dです\n",i , i*i); //ファイルに書き込み
    }
    fclose(fp); //ファイルを閉じる
    return 0;
}

同じ処理を何度も実行するなら関数が便利!

何度も同じ処理を実行するコードを書くのは、読み易さ、メンテナンス性の観点から好ましくありません。このような場合には関数を定義しましょう。ここでは3つの関数の例を挙げておきます。関数はmain(){…..}の前に記述します。

1つのint型の変数を受け取って、その2乗を計算する関数

f(x)=x2と書ける関数をC++で記述します。関数の名前は自由ですが、ここではpow2という名前を使うことにします。すなわち、pow2(x)=x2となる関数を作ります。完成形は下のようになります。pow2関数には戻り値としてint型の答えを返して欲しいので int pow2(…){…} というように初めに書いています。また、受け取る数をint型として受け取るので、int pow2(int x){…} というように書いています。変数名xは自由に変えることができます。
ここで作った関数を使いたい場合には、pow2(4)というようにして、カッコの中にint型の整数を入れます。

#include <stdio.h>
using namespace std;

int pow2(int x){
    return x*x;
}

int main(){
    printf("%d",pow2(4));
    return 0;
}

2つのdouble型の変数を受け取って、その積を計算する関数

C++で作る関数は引数をいくらでも取ることができます。ここでは引数がxとyの2つの、f(x,y)=xyと書ける関数を記述します。関数の名前は、ここではmulという名前を使うことにします。すなわち、mul(x,y)=xyとなる関数を作ります。完成形は下のようになります。mul関数には戻り値としてdouble型の答えを返して欲しいので double mul(…){…} というように初めに書いています。また、受け取る数2つをdouble型として受け取るので、double mul(double x,double y){…} というように書いています。このように複数の引数を取る場合にはコンマで区切ります。ここでも、変数名x,yは自由に変えることができます。
ここで作った関数を使いたい場合には、mul( 4.2 , 5.1 )というようにして、カッコの中にdouble型の数値2つをコンマ区切りで入れます。

#include <stdio.h>
using namespace std;

double mul(double x, double y){
    return x*y;
}

int main(){
    printf("%f",mul( 4.2 , 5.1 ));
    return 0;
}

3つのdouble型の変数を受け取って、最大値を求める関数

C++で作る関数の中に、if文を使った処理を書いてみましょう。ここでは引数がx、y、zの3つの関数を記述します。関数の名前は、ここではfindmaxという名前を使うことにします。いろいろな書き方があると思いますが、完成形の一例は下のようになります。findmax関数には戻り値としてdouble型の答えを返して欲しいので double findmax(…){…} というように初めに書いています。また、受け取る数3つをdouble型として受け取るので、double findmax(double x,double y,double z){…} というように書いています。
ここで作った関数を使いたい場合には、mul( 4.2 , 5.1 , 7.2 )というようにして、カッコの中にdouble型の数値3つをコンマ区切りで入れます。

#include <stdio.h>
using namespace std;

double findmax(double x, double y, double z){
    if(x>y&&x>z){ return x;} // 「A && B」は「AかつB」を表す
    if(y>x&&y>z){ return y;}
    if(z>x&&z>y){ return z;}
}

int main(){
    printf("%f",findmax( 4.2 , 5.1 ,7.2 ));
    return 0;
}

モバイルバージョンを終了