C言語にはないC++独自の文法の簡単な列挙

C++はC言語を拡張して開発された言語であり、C++ではオブジェクト指向をサポートする文法が追加されています。
基本的にC言語で使用していた文法はC++でも使用できるので、学習という面で見るとC言語を扱える方であればC++で追加された文法を覚えればC++も扱えるようになります。

今回の記事では、C++で追加された文法の中から、主なものを簡単に列挙していきます。

なお、javaやC#といったオブジェクト指向言語も扱えるのであれば、オブジェクト指向の概念は理解しているはずなので、追加された文法の理解も早いと思います。
javaは基本情報技術者試験で出題される言語、C#はC++と同じく.NET Frameworkでサポートされる言語であり、C++を学ぼうとする方はjava・C#についてある程度の知識があることが多いと思うので、javaやC#とも簡単に対比します。

・クラスの概念の追加

C++では、”class クラス名”でクラスを定義することができます。
javaやC#ではお馴染みの、
 アクセス識別子
 コンストラクタ
 継承
 抽象クラス
 static
といった機能が使用できます。
C#で実装されているデストラクタ(オブジェクト破棄時の後処理)もC++で使用可能です。

javaやC#とは記述方法が若干異なりますが、javaやC#の経験があれば戸惑うことは少ないと思います。
ただし、newで確保した領域を意図的にdeleteで破棄する必要がある、ということには注意する必要があります。
忘れるとメモリリークになります。
(javaやC#のようなガベージコレクションの仕組みは無い)
newはC言語で言うmalloc、deleteはC言語で言うfreeに似ていますが、new/deleteの場合はコンストラクタ/デストラクタが呼ばれるという違いがあります。

なお、インターフェースの機能は使用できませんが、書き方次第でインターフェースに近いことはできます。

・参照の概念の追加

クラスの概念とも関連があるのですが、javaやC#ではお馴染みの参照型変数の概念が追加されています。

参照型変数の中身はポインタで、C言語ではお馴染みのポインタ型変数とその点では同じなのですが、参照型変数の場合は指し示すアドレスを自由に変更できない(インクリメント等ができない)という違いがあります。
この違いにより、ポインタ型変数で犯しがちなミスを減らす効果があります。

・スコープ解決演算子の追加

C++では、変数名やメソッド名の衝突を避けるため、スコープ解決演算子(::)を使用します。

例えば、”std::cout”と書いた場合、stdという名前空間(クラス名)のcout(main関数実行時にシステムにより生成されるオブジェクト名(変数名))という意味になります。
また、外部の自作クラスにアクセスするような場合も、このスコープ解決演算子を使用します。

なお、スコープ解決演算子は、ソースコードの冒頭で using namespace 名前空間;のようにデフォルトの名前空間を指定することで省略可能です。

・ストリームの概念の追加

“<<“で出力ストリーム、”>>”で入力ストリーム、という意味となります。
(”<<“はostreamクラス、”>>”はistreamクラスから派生させることで使用できます)

例えば、
“std::cout << “Hello World!\n”;”
と書けば標準出力に”Hello World!”と出力できますし、
“std::cin >> hoge;”
と書けば標準入力を変数”hoge”に渡すことができます。

・string型の追加

C言語で文字列操作を行う場合はchar型のポインタを使う必要がありましたが、C++ではjavaやC#と同じように用意に文字列操作を行うためにstring型が用意されています。
string型のc_str()関数を用いれば文字列の先頭のポインタを取得することもできるので、C言語の従来の文字列操作用の関数も併用できます。

・bool型の追加

意外にもC言語にはtrue/falseを保持するbool型が用意されていません。
C++には、java(boolean型)やC#のようにbool型が用意されています。

・関数のオーバーロードの追加

同じ名前の関数でも、関数の引数が異なれば複数定義できます。
これはjavaやC#ではお馴染みの機能です。

・例外制御の追加

C++ではtry~catch構文が用意されています。
throwで意図的に例外を投げることもできます。
これもjavaやC#ではお馴染みの機能です。
ただし、finallyは用意されていません。
finally句で行うようなリソースの解放を行いたい場合は、前述のデストラクタや、デストラクタで自動的に領域を解放するオブジェクト(スマートポインタ)を利用する必要があります。


いかがでしたでしょうか。

個人的には、C++はスコープ解決演算子やストリームの概念で戸惑いました。
しかし、簡単な例で学んでいけばスコープ解決演算子やストリームの概念を理解するのは難しくないですし、他の文法はC言語やjava・C#に近いので、これらの言語を学んでいる方ならすんなり理解できると思います。
基本情報技術者試験で出題されるC言語やjavaに比べると、これまで紹介してきたC#や今回紹介したC++は学んでいる方は少ないと思いますが、これらの言語は文法的には近いものがあるので、ある日突然必要になったとしても習得は難しくないと思います。

では、また次回!

C言語:ポインタの概念の図解

C言語を学ぶ上でポインタは重要概念で、この概念を理解していないと実務で通用するプログラミングはできません。
にもかかわらず、C言語の主要なつまずきポイントにもなってしまっており、未経験者のみならず他言語を学んできた方にとっても難しい概念です。
ポインタの難しさはイメージのしにくさにあり、イメージするにはコンピュータ内部の仕組みを理解する必要があります。
今回の記事では、ポインタのイメージをなるべく簡単に書きたいと思います。

【変数の領域の確保】

コンピュータにはメモリ領域が存在し、メモリ領域の中に様々なデータがセットされています。
メモリ領域は区分けされており、それぞれの区分けごとにアドレスが割り振られています。

プログラムで変数を宣言すると、そのメモリ領域の一部がその変数用に確保され、他の用途で使用されないようにします。
変数に値をセットすると、その変数用のメモリ領域が変更されます。

以上のことを図にすると以下のようになります。

なお、この挙動はC言語に限った話ではなく、他言語にも言えることです。

【アドレスの参照と値の参照】

ここからがC言語ならではの話になります。

他の言語では変数のメモリ領域が指す値のみを使用するのですが、C言語では変数のメモリ領域の(先頭)アドレスを使用することがあります。
通常の変数でも、「&」演算子をつけて参照することでアドレスを取得することができます。

そして、C言語では普通の変数の他にポインタ変数というものがあり、変数の宣言時に「*」演算子をつけることでポインタ変数になります。
ポインタ変数はアドレスを扱う用の変数であり、演算子をつけずに普通に参照するとアドレスを取得できます。
また、「*」演算子を付けて参照することで、その変数のメモリ領域が指す値を取得することができます。

以上のことを図にすると以下のようになります。

【コーディング例】

・test.c

 ※HTMLエスケープ回避のため、特殊文字を全角文字にしています。ご了承ください。

・実行結果

【ポインタは何のために使うのか】

ポインタを使う理由は主に以下の2つです。

・関数で参照渡しをするために使う

 簡単に書くと、引数でポインタ変数を指定し、呼び出し先の関数でそのポインタ変数に値を代入すると、呼び出し元でもその代入された値を使用可能になります。
 C言語の関数は、多くの場合「ビジネスロジックで使用するアウトプットは参照渡しされた変数に代入し、returnではリターンコード(例:0なら正常、1以上ならエラー)を返す」という形になっています。

・インクリメント/デクリメントで次の/前の変数の値を取得するために使う

 文字列や配列の処理で使用します。