C++   基礎

ホーム   C/C++チュートリアル


C++の基礎を説明しています。
この「C++入門」は、wxWidgesのコードを読むための必要最小限な説明をしています。
他の言語などの予備知識は必要としていません。

コーディング

お好きなエディタで次のコードを記述してください。そしてhello.cppという名前で保存してください。WindowsでMSYSを使う場合は、 C:¥msys64¥home¥ユーザー名 に保存するのが便利です。C++のコードファイルの拡張子は.cppになります。

hello.cpp


#include <iostream>

int main()
{
    std::cout << "Hello C++!" << std::endl;
    return 0;
}
    

実行

C++はコンパイル型の言語です。高速で実行することができます。
コンパイルとは、ソースコードをコンピュータが理解できる機械語に変換することです。

コンパイル

ターミナルもしくはコマンドプロンプトもしくはMSYSを開いて、hllo.cppを保存したディレクトリに移動してください。MSYSの場合で、hello.cpp を C:¥msys64¥home¥ユーザー名 に、保存した場合は、MSYS が起動した画面がそのディレクトリになります。そして次のようにコンパイルして実行します。


g++ hello.cpp
// macOS、Ubuntu、Mintでは実行ファイル a.out が作成されます
// Windowsでは実行ファイル a.exe が作成されます

// macOS、Ubuntu、Mintで実行するには次のようにします
./a.out

// Windowsで実行するには次のようにします
./a.exe
//もしくは
./a

// 実行結果
Hello C++!
    

なお、WindowsでMSYSを使った場合には、作成された a.exe をデスクトップなどに移動させ、コマンドプロンプトで a.exe と実行しようとしても「~~~.dll が見つかりません」などの警告が出て実行できません。これを修正するには、MSYS2でコンパイルするときに次のようなオプションをつけます。


g++ hello.cpp -static -lstdc++ -lgcc

// 作成された a.exe をデスクトップなどに移動させてコマンドプロンプトを起動します
// コマンドプロンプトで a.exe を移動させたディレクトリに移動します
// そして次のように実行します

a.exe
// もしくは
a

// 実行結果
Hello C++!
    

なお、最初からWindowsのコマンドプロンプトでコンパイルする場合は、このオプションをつける必要はありません。

コード説明


#include <iostream>
    

標準装置からの入力と、標準装置への出力に関する機能が定義された iostreama というファイルを読み込んでいます。
標準入力装置はキーボードに、標準出力装置はディスプレイに設定されています。
このような何かの処理をする機能のことを「関数」と呼びます。そして、関数が定義されたこのようなファイルのことをヘッダーと呼びます。
< と > に囲まれたヘッダーは、そのヘッダーが保存されている場所を開発環境が知っていること意味しています。
なお、開発環境のことを一般的には「処理系」と呼びます。


int main() {
    

C++のプログラムは、main( )関数というものから始まる決まりになっています。main( )関数の前にはintと記述しなければなりません。そして関数が実際に行う処理は { と } で囲むことになっています。


    std::cout << "Hello C++!" << std::endl;
    
  1. std::cout は、iostreamで定義されている関数です。<< に続く文字列をターミナルに表示します。文字列は " と " で囲むことになっています。
  2. std::endl も、iostreamで定義されている関数です。ターミナルに文字列を表示したあとに改行するために使います。std::endl は、実際には、改行文字を表示しますので、前の文字列と << でつなぐ必要があります。
  3. << はつなぐという働きをします
  4. C++の式(命令文)は、;(セミコロン)で終わる必要があります。

    return 0;
    

main関数は、何かの整数値を返さなければなりせん。何かを返す場合は、return を使います。main関数は正常に終了する場合は 0 を返す決まりになっています。


}
    

関数が実際に行う処理は、必ず { と } で囲まなければなりません。

キーワード

hello.cppで使われている intreturn は、C++によって定められたキーワード(key word)です。キーワードには、それぞれに意味が定めらています。
int は整数値型という意味です。
return は何かを返すという意味です。
main()の前にintと記述していたのは、main()関数は整数値を返すという意味だったのです。

名前空間

hello.cppは、次のように書き換えることができます。

hello.cpp


#include <iostream>
using namespace std;

int main()
{
    cout << "Hello C++!" << endl;
    return 0;
}
    

using namespace std;と記述することで、std::coutstd:endlをそれぞれcoutendlと省略して記述することができます。
このような仕組みのことを名前空間(name space)と言います。

コメント

プログラムの中にメモを記述することができます。このメモのことをコメント言います。コメントはプログラムの動作になにも影響を与えません。

hello.cpp


#include <iostream>
using namespace std;

/*
hello.cpp
2019/11/30
(c) vivacocoa.jp
*/

int main()
{
    cout << "Hello C++!" << endl;   // Hello C++!と表示されます
    return 0;
}
    

/* と */ で囲まれた部分はコメントになります。複数行もコメントにすることができます。
// で始まる部分は、// から、その行の行末までがコメントになりますので、一行コメントとも呼ばれます。

C++では、データのタイプ(type、型)が決まっています。まずは、文字列型と整数値型があることを覚えまておきしょう。

type.cpp


#include <iostream>
using namespace std;

int main()
{
    cout << "This is a string." << endl;
    // This is a string.は文字列型です
    cout << 100 << endl;
    // 100は整数値型です
    return 0;
}
    

実行結果


This is a string.
100
    

型がある理由

C++は、コンパイルする時にソースコードにエラーがないかを調べます。このチェックは色々な方面で行われますが、そのチェックの一つとして、データ型を使って間違ったデータが使われていないかを調べています。

変数

変数(へんすう)とは、データを保存できる容れ物です。変数を定義する時には、どの型のデータの容れ物であるかを指定しなければいけません。変数の中のデータは、指定された型のデータであれば何度でも上書きすることができます。しかし違う型のデータで上書きしようとするとエラーになります。

variable.cpp


#include <iostream>

int main()
{
    std::string name;
    name = "Jane";
    std::cout << name << std::endl;
    name = "Mary";
    std::cout << name << std::endl;
    
    int number;
    number = 100;
    std::cout << number << std::endl;
    number = 200;
    std::cout << number << std::endl;
    
    return 0;
}
    

実行結果


Jane
Mary
100
200
    

コード説明


    std::string name;
    

文字列型の name という変数を定義しています。変数は「型 変数名;」と記述して定義します。型の指定の部分で std:string という関数を使っていますが、文字列は複雑な型なので、C++ では、関数を使って文字列型を指定します。using namespace std; を使えば、この部分は string と記述できますので、簡単で意味も分かりやすくなります。


    name = "Jane";
    

変数に値(データ)を入れる場合は、=(イコール)という記号を使います。= を使えば、左辺の変数に、右辺の値を上書きするという意味になります。このデータの上書きのことを C++ では、「代入(assign、割り当て)」と呼びます。なお、C++で、イコール(同じ)という意味を表す記号は == となります。
また、文字列を表すデータはダブルクォーテーションの " で囲む決まりになっています。


    std::cout << name << std::endl;
    

変数はコード(式、文)中で上記のように使うことができます。変数の部分は、その変数に入れている値に置き換わります。


    int number;
    

整数型の変数の型指定には、int キーワードを使います。

ポインター

C++には、ポインター(pointer)という変数もあります。

C++では、変数を定義するとメモリーに値を入れる場所が確保されます。
ポインターは、そのメモリーの場所の先頭位置を 0 から 0xfffffff...(コンピューターに備わっているメモリー次第)という16進数の整数値として入れる変数です。
なお、このメモリーの場所のことをアドレス(address)とも言います。

pointer.cpp


#include <iostream>
using namespace std;

int main()
{
    int  num = 100;
    int *ptr = &num;
    
    cout <<  num << endl;
    cout <<  ptr << endl;
    cout << *ptr << endl;
    cout << &num << endl;
    
    num = 200;
    
    cout <<  num << endl;
    cout << *ptr << endl;
    cout <<  ptr << endl;
    cout << &num << endl;
    
    return 0;
}
    

実行結果


100
0x7ffeec062b88
100
0x7ffeec062b88
200
200
0x7ffeec062b88
0x7ffeec062b88
    

コード説明


    int *ptr = &num;
    
  1. ポインターを定義するには、変数名の前に *(アスタリスク)をつけます。
  2. 普通の変数のアドレスを取得するには、その変数の前に &(アンバサンド)をつけます。
  3. ある型のポインターは、そのポインターと同じ型の変数のアドレスしか代入できません。

    cout <<  ptr << endl;
    cout << *ptr << endl;
    

ポインターの値(16進数のアドレス)を取得するには、ポインター名をそのまま記述します。
ポインターが指し示すアドレスに入っている値を取得するには、ポインター名の前に * をつけます。


    num = 200;
    
    cout <<  ptr << endl;
    

変数 num の値を変更しても、そのポインターが表すアドレスは変わりません。

ポインターがある理由

次の「関数」で説明します。

関数

function.cpp


#include <iostream>
using namespace std;

void func()
{
    cout << "I am func." << endl;
}

int main()
{
    func();
}
    

実行結果


I am func.
    

関数は、次のように記述して定義します。


戻り値の型 関数名( 引数 )
{
    処理;
}
    
  1. 戻り値がない場合は、void と記述します
  2. 関数名は任意に決められますが、後述する「識別子の命名規則」に従わなければなりません
  3. 関数名に続く ( と ) の間に引数(ひきすう)を記述します。引数とは、関数に与えるデータのことです。引数がない場合は、( ) と記述するか、( void ) と記述します。引数がなくても ( ) を省略することはできません。
  4. 関数が行う処理は、{ と } の間に記述しなければなりません。

    func();
    
  1. 関数を実行する場合は、関数名( 引数 ); と記述します。
  2. 引数がない場合も、( ) を省略することはできません。
  3. 関数を実行することを「関数を呼び出す(コールする)」と言います。
  4. 関数は、呼び出される前に定義されていなければなりません


関数の前方宣言

関数は呼び出される前に定義されていなければなりませんが、複数の関数が、お互いを呼び出すようなプログラムを記述する場合は、大変なことになります。そこで「関数の前方宣言」という方法を使います。
前方宣言を使うと function.cpp は、次のようになります。

function.cpp


#include <iostream>
using namespace std;

void func(); // 関数の前方宣言

int main()
{
    func();
}

void func() // 関数の実際の定義は、関数の呼び出しよりも後で記述しています。
{
    cout << "I am func." << endl;
}
    

前方宣言は関数の実装部分以外( { } 以外の部分)にセミコロン ; をつけたものです。前方宣言はプロトタイプ(prototype)とも呼ばれます。


識別子の命名規則

変数名や関数名のようにプログラマーが自由につけられる名前のことを識別子(identifier)と言います。識別子には次の命名規則があります。

  1. 使える文字は、アルファベットの大文字と小文字、アラビア数字、アンダースコア( _ )のみ
  2. アルファベットの大文字と小文字は区別されます。num と Num と NUM は違う識別子です。
  3. 識別子を数字で始めることはできません。数値と誤認されると覚えると良いでしょう。
  4. キーワードと同じ名前の識別子は使えません


引数の使い方

parameter.cpp

#include <iostream>
using namespace std;

int sum(int a, int b);

int main()
{
    cout << sum(5, 5) << endl;
}

int sum(int a, int b)
{
    return a + b;
}
    

実行結果


10
    

コード説明


int sum(int a, int b);
    
  1. 引数は、型と引数名を指定します。複数の引数がある場合は、カンマ( , )で区切ります。
  2. 引数名はその関数の中で変数として使えます。
  3. 関数定義や関数前方宣言の中で記述されている引数を「仮引数(parameter)」と言います。

    cout << sum(5, 5) << endl;
    

関数を呼びだす側では、引数に実際の値を、仮引数の順序に合うように、カンマ( , )で区切って指定します。
関数の呼び出し側で与える引数のことを「実引数(argument)」と言います。


    return a + b;
    

ここで使われている + のような記号ことを「演算子(operator)」と言います。+ 演算子の意味は数学と同じで、「足す」という意味です。


値渡しと参照渡し

引数の使い方には、「値渡し(by value)」と「参照渡し(by reference)」があります。

byreference.cpp


#include <iostream>
using namespace std;

int  plus100(int  a);
void plus200(int *a);

int main()
{
    int a = 100;
    a = plus100(a);
    
    cout << a << endl;
    
    plus200(&a);
    
    cout << a << endl;
    
    return 0;
}

int  plus100(int a)
{
    return a + 100;
}

void plus200(int *a)
{
    *a = *a + 200;
}
    

実行結果


200
400
    

plus100 関数では、aの値のコピーが引数として渡されています。aが直接渡されているわけではありません。したがってplus100 関数の中で、渡された値を加工しても、main 関数の中の a の値は変わりません。このような引数の渡し方を値渡しと言います。

一方、plus200 関数では、aのアドレス(ポインター)が引数として渡されています。plus200 関数の中では、ポインターをたどって main 関数の中の a の値を直接加工することができま。このような引数の渡し方を参照渡しと言います。


ポインターが必要になる理由

ポインターが必要となる大きな理由の一つとして、上記の引数の渡し方の違いにあります。値渡しで渡されるのは元のデータのコピーです。元のデータが動画データのような大きなサイズだった場合は、それと同様のメモリー容量が必要となります。
一方、ポインターを使った参照渡しでは、新たに必要となるメモリーサイズは、ポインター(アドレスを格納する変数)に必要な 8 バイトだけです。また、直接データが加工ができることも大きな点です。 関数がデータを戻り値として返す場合、その戻り値もメモリーに新たにコピーされ、新たなメモリー領域が消費されます。


87 visits
Posted: Nov. 30, 2019
Update: Dec. 10, 2019

ホーム   C/C++チュートリアル   目次