こんにちは。田原です。
本日より「実践C++入門講座」を始めます。
原則として、毎週日曜日の夜24:00に公開します。
この講座は、C++の特長を活かして高性能なプログラムを書けるようになるための実践的な入門講座にしたいと思います。よろしくお願い致します。
まず初めに、難しいと言われるC++を学ぶメリットについて説明します。
C++は高速なプログラムを多くのプラットフォーム向けに高い生産性で開発できることが特長です。
- 多数のCPUメーカ、OSベンダー、オープン・ソース・プロジェクトから
- 多種類のコンピュータ用コンパイラとライブラリ(以後、処理系と呼びます)が提供されてます
- しかも、ワールド・ワイドな標準規格(ISO/IEC)により、多数の実装において比較的高いレベルで仕様が統一されています
これらの特長により、多くの基幹的なアプリケーション・ソフトウェアや各種ミドルウェアがC++で開発されています。更に膨大なソフトウェア資産あります。
従って、今後も基幹的なソフトウェアや高速性が要求されるソフトウェアの開発にはC++が使われ続けます。
C++に近い言語として、C++の前身であるC言語があります。C言語も高速なプログラムを多くのプラットフォーム向けにアセンブラよりは高い生産性で開発できます。そして、C++よりも更に小型のコンピュータ(というよりマイコン)でも使うことができます。
しかし、近代的なプログラム開発スキーム(オブジェクト指向や各種コンテナ)を使えません。そのため脆弱性の少ない安全なプログラムを開発する苦労は並大抵のものではありません。
そして、古い時代に設計され互換性を維持してきた標準ライブラリは歴史的な問題点を多数抱えているため、それを使うために多くの知識(ノウハウ)を必要とします。その結果、標準ライブラリを含めた実用プログラミングの学習難易度は決して低くありません。
ところで、C言語で近代的なプログラム開発スキームを使えないのは実は当たり前です。C言語にそれらを追加した言語がC++なのですから。そして、C言語を拡張するのではなくC++という別の言語になったのには理由があります。C言語とC++では狙いが大きく異なるのです。
- C言語
アセンブラ程ではありませんが、C言語は出力されるマシン語コードをプログラマが制御できます。そのような細かい部分の作り込みが必要な分野(OSのカーネルや小型CPUのファームウェアなど)向けです。メモリをギリギリまで節約するとか、ガチガチに高速化するなどの細かい部分をプログラマが制御できます。 -
C++
これに対してC++は細かい部分はコンパイラに任せて、プログラマはプログラムのより高度な部分に注力することで高い生産性で開発できます。安全性の高いクラス群をC++の近代的な機能で開発し、それらを用いて短期間で安全かつ機能豊富なアプリケーション・プログラムを開発するのに向いています。
もちろん、C++はC言語仕様をほぼ含んでますのでC言語のような細かい部分を制御するプログラムを書くこともできますが、プログラム全体をC言語スタイルで記述するのではC++を使う意味がありません。ギリギリの最適化が必要な部分のみに限定する使い方が望まれます。
このように向き不向きがありますが、習得の容易なC言語でも工数を余分にかければC++分野のプログラムを開発することも可能であるため、C言語とC++のシェアは拮抗しています。しかし、近年C++が増えてきつつあり、特にIT技術先進国のアメリカでは既にC++のシェアはC言語のシェアを超えているようです。
CとC++のシェアを比較してみました。(2016/12/22調べ)
サイト | Cタグの質問数 | C++タグの質問数 |
---|---|---|
本家stackoverflow | 237,648 | 488,840 |
日本stackoverflow | 148 | 226 |
teratail | 1,529 | 1,359 |
TIOBE IndexでもC言語のシェアが急落(-7.73%)していますし、ワールドワイドではC++のシェアが伸びつつ有る様子が伺えます。
現在、最も多く使われているプログラミング言語の1つはJavaと思います。
JavaはC++よりも更に生産性が高く、かつ、学習が容易になるよう設計されています。これにより多くのプログラマを確保することを狙っています。
しかし、コンピュータの資源(主にメモリ)を多量に消費するため、小型コンピュータには移植されていません。提供するベンダもC++に比べると少なく稼働するコンピュータも少ないです。(CPUメーカでJava処理系を提供しているところを見たことはありません。)
また、速度はJITコンパイラによりC/C++に近づいているという記事も散見されますが、原理的に追いつくことはありえません。これはAndroidとiPhoneのスムーズさの違いに現れてます。(AndroidはJavaでGUI制御しているため、ガベージ・コレクションでひっかかりもっかかりしてしまいます。)
そしてJava処理系の基幹部分はC/C++で記述されてます。
生産性が重要だが速度はそれほど重要でない部分にはJavaのような生産性の高い言語、速度が重要な部分にはC++のような高速な言語と住み分けるのが適切です。(例えばJava処理系の基幹部分は後者に属します。)
ちなみに、複数のプログラミング言語について比較している記事がありました。参考になると思います。
言語仕様がたいへん大きいため、確かに難しいです。私も未だにマクロ(#define)によるメタ・プログラミングの深い部分は使いこなせません。正直断念しました。(ああ、これはC言語からありますね...)
そのため、C++は難しいと聞いて最初から断念している人も少なくないと思います。しかし、ここへ来られている皆さんはきっとC++を学びたいと思って来られていると思います。であれば大丈夫です。断言します。
C++はたくさん勉強すればするほど高速なプログラムをより高い生産性で開発できるようになります。しかし、その全てを把握してなくても問題ありません。理解できた部分を使いこなせば良いのです。C++は普通に使っても高速ですし、その一部を使うだけでも随分生産性は上がります。
C++の特長を活かすために、大きく貢献するC++の機能については難易度の高いことも含めて解説します。そのための最大の課題はメモリ操作周りですので、C++で取り扱うメモリについてはかなり丁寧に解説します。意外に種類が多いことにびっくりすると思います。
できるだけ初心に返って初心者の方にも分かり易い解説を心がけますが限界はあると思います。少しプログラミング経験のある方でC++を学びたい人をメイン・ターゲットとさせて頂きます。
パソコンを使い慣れていること、テキスト・エディタ(メモ帳でもOK)を使ってテキスト・ファイルを作成できること、コマンド・プロンプトの基本操作ができることは前提とさせて下さい。
しかし、コメントでご質問やご意見頂ければできるだけ善処します。
また、当講座固有ではなくC++一般の質問でしたら、teratailやstackoverflowで質問されても良いと思います。私自身はteratailに出没してますので可能な時はそちらでも回答致します。
当サイトのコメント機能について
コメントは現在、承認制としています。スパム・コメントが多数入るためです。ですので、書き込み後、反映されるまでしばらくお待ち下さい。また、内容によっては公開しない場合があることをご了承下さい。
C++はISO/IEC 14882にて標準規格として制定されています。JIS X3014でも制定されてますが、新しい規格に追従していないようです。
2011年に制定されたC++11(ISO/IEC 14882:2011)でコア言語仕様が大きく拡張され、その後2014年に制定されたC++14が2016年現在の最新です。C++14以降の変更は応用的な機能に関する変更がほとんどですので、当講座ではC++11を主な対象とします。
(私自身が現在開発中のTheolizer®もC++11をターゲットにしているので、C++11に慣れていると言う事情もあります。)
規格書そのものは有償でないと入手できませんが、C++11制定後の次のドラフトN3337が発行されています。これはC++11とほぼ同じであり、無償で入手できます。そこで、疑義がある場合はN3337を参照しつつ解説致します。
ところで、本の虫の江添亮氏がC++11の言語仕様を解説されています。
また、C++14で追加された言語仕様についても解説されています。
規格書よりの正確な記述のため、ちょっと難しいですがリファレンスとしてたいへん有用です。私もありがたく参照させて頂いてます。遠いところからで申し訳ないのですが、ここからも感謝させて頂きます。
高校生の頃に当時出始めたワンボード・マイコンH68/TRを購入し、アセンブラでこの世界にハマりました。当時はメモリが1KBytesくらい(メガではないです。キロです)しかなく、パソコンなんてありませんでした。
そして、あまりに楽しかったので情報工学系の大学に入りました。当時は人工知能全盛で、私もC言語で開発したオセロで卒論を書きました。最近、また人工知能の春が訪れているようで歴史は繰り返すことをシミジミと感じてます。
その頃、Appleがマッキントッシュの3代目Macintosh Plusを出荷し、メモリが標準で1MBytes載っていると聞いて「個人で1MBytesなんて使うのか!! あり得ないぞ」とか思っていたのは懐かしい思い出です。(笑)
その後、幾つかの会社を経て電子部品メーカに入りファームウェア開発を長らく専門としてました。当初はアセンブラでしたが、複数のメーカのCPU向けにC言語で同じ機能のファームウェアを開発し、私としては初めてのマルチプラットフォームを成功できたのは嬉しかったです。
並行して長らくWindowsバソコン側のプログラムを開発してましたが、ずっとベターCとしてC++を使っていました。2年前に独立起業してからはC++を精力的に勉強し今に至ってます。C++の深い部分の勘所を掴むのに1年くらいかかりました。Theolizer®はテンプレート・メタ・プログラミングをバリバリ使って開発してますので高速です。
最後に当講座で使用する開発ツールについて説明します。
C++を学ぶ時たくさんある開発ツールのどれを用いても良いのですが、当講座ではC++の特長を活かせるようにするために低レベルな部分も解説します。その時、多くの開発ツールに適合するような解説は現実的ではないため、開発ツールを限定致します。(使っている人が多いこと優先で選びました。)
特殊な操作はしない予定ですので、ご自身がお使いの開発ツールで同様な操作をできるスキルをお持ちの方は、そのまま既にお使いのものを使って頂ければ十分です。
これは、当講座一押しの開発ツールです。
講座の中でCMakeを使っていきますので、追々その便利さに気づいて頂けると思いますが、簡単にメリットを説明します。
- マルチプラットフォーム対応なプロジェクトを開発する時たいへん強力です。
ビルド・プロジェクト設定ファイル(CMakeLists.txt)を書けば、基本的には多数のプラットフォーム用にビルド・プロジェクトを生成出来ます。 - これは一種のスクリプト・エンジンです。
ビルド・プロジェクトのジェネレータだけでなくスクリプト・エンジン機能も内蔵していますので、これ1つで複数のプラットフォームに対応できます。
また、スクリプト・エンジンはperl、pythonなど多数ありますが、多数の実装に分岐しているものもあり、どれを使うべきかの調査だけでも時間を要します。しかし、CMakeは分岐しておらず、最新版を使って於けば概ね間違いありません。(個人的に、これはたいへんありがたいと感じました。) - Visual Studio向けのプロジェクトを手軽に生成できます。
Visual Studio上であっちクリックこっちクリックしなくて済み、設定し忘れも発生し難いです。
サンプル・ソースにはCMake用の(最小限の)CMakeLists.txtを添付するように致します。
そこで用いたCMakeLists.txtについても簡単な説明を行う予定です。
なお、CMakeは非常に強力で膨大なソフトウェアですので、その使い方解説を始めるとキリがありません。
CMake専用で講座1つ開ける程のものです。当講座はC++用ですので詳しい解説は省略致します。
CMakeは結構特殊な概念を含んでいます。
特にDebugとReleaseの切り替え方法がVisual Studioとそれ以外で全く異なるので解りにくいです。Visual Studioが特殊なのですがシェアが大きいため無視できないことが原因と思います。しかし、この概念について解説しているサイトを見たことがありません。これについては当講座内で解説したいと思います。
C++開発ツールのシェアは、WindowsではMicrosoft Visual C++が最大でしょう。次にはlinux上でgccが多く使われています。
そこで、この講座ではこの2大処理系を使って解説していきます。必要な方はお好みの方を選択下さい。
次に、効率的なデバッグのためには統合開発環境(IDE)も使えた方が好ましいです。デバッグ時にブレーク停止やステップ実行、変数の値の観察ができるとデバッグが捗りますので。そこで、当講座でサンプル・プログラムの解説で用いる統合開発環境を選択しました。
Visual C++はVisual Studio一択ですが、gccは選択肢が多数ありどれを使うべきか悩ましく、本家stackoverflowのタグで調べてみました。そのタグが付けられた質問やそのタグのフォロワーが多い程メジャーと考えました。
統合開発環境 | タグ名 | 質問数 | フォロワー数 |
---|---|---|---|
Visual Studio | [visual-studio] | 63,013 | 13K |
NetBeans | [netbeans] | 19,416 | 2.6K |
QtCreator | [qt-creator] | 3,284 | 307 |
Code::Blocks | [codeblocks] | 2,791 | 343 |
Eclipse + CDT | [eclipse-cdt] | 2,576 | 222 |
CLion | [clion] | 658 | 133 |
Dev-C++ | [def] | 586 | 92 |
KDevelop | [kdevelop] | 172 | 51 |
CodeLite | [codelite] | 135 | 17 |
(2016/12/22調べ。なお、Visual Studioも載せたのは参考のためです。)
Visual StudioとNetBeansはC++専用ではないのでユーザ数が多いのだと思います。
NetBeansは主にJava用のIDEです。JavaプログラマはC/C++プログラマよりかなり多いですし、この内C/C++で使っている人の割合も読めません。候補の1つとし他も検討します。
CLion以下は質問もフォロワーも少なくシェアは低いので候補から外しました。
そこで、NetBeans, QtCreator, Code::Blocks, Eclipse + CDTについて評判を調べてみました。
まず、Eclipse + CDTは使い勝手が酷いと言う評価が多く、またCMakeとの連携もやり難いようでしたので外しました。
Code::Blocksが良いと評価している人をちらほら見かけました。NetBeansは起動が遅いようです。QtCreatorは以前使っていたのですがCMakeプロジェクトの生成手順が多く、CMakeとの連携は不便でした。(それ以外の部分は優れていると思います。)
そして、Code::BlocksはCMakeが直接サポートしており、Visual Studio並に連携が便利そうですのでCode::Blocksを選択しました。
以上の検討の結果、当講座ではコンパイラ(処理系)と統合開発環境は下記を用いて解説します。Windows本体を除き、個人利用であれば全て無料で使えます。
もちろん、これら以外のものを使われても何ら問題はありません。
OS | C++処理系 | 統合開発環境(IDE) | 処理系の呼称 |
---|---|---|---|
Windows 10 | Microsoft Visual C++ 2015 | Microsoft Visual Stduio 2015 Community | msvc |
ubuntu 16.04 LTS(*1) | gcc 5.4.0 | Code::Blocks 16.01 | gcc |
(*1)
linux用に専用PCを用意しないで済むようVirtualBox上のubuntuを用います。
既にubuntuがインストールされたPCをお持ちの方はVirtualBoxを使う必要はありません。
そこそこ長い手順ですので別記事とします。必要な記事を参考にして下さい。
- 第2回目 Visual Studio 2015 Communityを準備する
- 第3回目 ubuntu on VirtualBox+開発環境を準備する
- 第12回目 Visual Studio 2017 Communityを準備する
では、次回をお楽しみに。
CodeLiteなんてのもなかなか良かったりする。
なるほど。
確かにCodeLiteの良い評判もちょっと見かけました。
どの辺が便利です? CMakeとの相性はどうでしょう?
IDEの数が多すぎて全部はお試しできなかったのですよ。
素晴らしいです。
本当の意味でプログラミングとC++を理解されている
「プロフェッショナル」の方が、体系立ててC++を解説されているサイトは初めてでは無いでしょうか
自分は既にある程度の勉強サイクルを確立してしまったのでサイトでプログラミングを勉強することはもうありませんが、初心者の人には真っ先に勧めたいサイトです
うわっ。ありがとうございます。こんなに褒められるとちょっと気恥ずかしいものですね。
C++は本当に良い言語と思いますので、お互い頑張りましょう。
良い記事をありがとうございます。
いつもC++で分からないことがあれば参考にしています。
これからも見に来るのでよろしくお願いします〜。
ありがとうございます!
最近業務が忙しくて少し滞っていますが、近い内にCMake編を立ち上げますので、今後共よろしくです。