【初心者必見！】C/C++言語を学んではいけない理由と学ぶべき理由

みなさん、開発がんばってますか？
さて、今日は、いつもとは少し趣向を変えて、C/C++言語について書いてみようと思います。

いささか、釣り気味のタイトルですが、感覚的にわかりやすいよう焦点を絞って書いていきたいと思います。
少し前にこんなの流行りましたよねw

https://twitter.com/skhaz/status/574655441990467584
![Java VS C++](http://images-cdn.9gag.com/photo/aw7GN0Q_460s.jpg)

![C Perl etc](https://v1.std3.ru/71/b7/1450110575-71b77b2bd06f431f2bd0b4abb983738f.gif)

これは本当かどうか？
**本当です！**

ただし前提条件が抜けています。
CもC++もそれなりに多大な時間をかけて修行すれば！
の話です。
つまり修行をして、達人になればの話ということになります。

それではC/C++を学んではいけない理由から説明しましょう

# C/C++を学んではいけない理由

##C編

- 言語仕様はとても簡単だが、概念がわかりにくい

CはそれこそJavaやその他の後々出てくる言語に多大な影響を与え、文法も参考にされた言わずと知れた
基礎中の基礎の言語です。
それゆえ、言語の仕様はとても簡単で、馴染みやすい文法です。
どれかプログラムを書いたことがある人であれば、それこそすぐに習得できる言語だと思います。

しかし、言語が簡単な分、概念がわかりにくいです。
理由はCPUの動作そのものを、人間にわかりやすく置き換えた言語であると言えるからです。
いわゆる、**高級アセンブラ**と言われる所以ですね！
簡単にいうと、ポインタ？？？なんだそれwの世界なわけです。
ポインタなんて単なるメモリのアドレスなんですけどねw

- オブジェクト指向言語ではない

今は普通にオブジェクト指向が受け入れられていますが、Cにはオブジェクト指向という考え方はありません。
~~それゆえ、基本的にプログラムは上から下に逐一的に処理されます。
ただ、最近はスレッドなどの考え方が定着しており、上から下に流れるだけではないですが。~~
とはいえ、以下のように書いてあげれば、Cでもオブジェクト指向の恩恵を少し受けることができます。

```c

typedef int (*FUNCTION_POINTER)(object this);
struct object {

  int a;
  FUNCTION_POINTER fp;

};

```
初期化関数を作ってそのポインタをfpに格納するわけですね。
thisを示す自分自身のアドレスも入れることを忘れると大変なことになりますw


##C++編
C++はオブジェクト指向のプログラムが書けるようにCを拡張した言語です。それゆえ、C編のデメリットも含んでいます。
それに加えて

- 言語仕様がとても複雑

というのがあります、特に多重継承とか多重継承とか多重継承とか多重継承とか・・・・・（ごほんw）

C++言語は多重継承を受け入れたことにより、ポリモーフィズムにも影響があります。複数の継承元で同じ名称、同じ引数の関数が定義されていたらどうなるか。など悩ましい部分が多く、一筋縄にはいかない言語です。
それゆえ、正しいプログラムを書くには、正しい言語知識と理解が必要です。

また、C++は遅いと思われがちですが、それは大きな間違いです！
書き手の問題であることが殆どです。
例を示しましょう。

```cpp

class ClassA {
 int a;
 void funcA();
};

for (int i = 0; i < 1000 ; i++) {
  ClassA a;

}

```

はい、アウトです！
for分の中でaを作っていますね。
これだと、aが1000回作られるわけです。つまりどういうことか？
コンストラクタとデストラクタもこれでは見えませんが、1000回コールされることになります。
これでは高速に動作させられませんね！

つまり、C++は見えない関数コールなどもあるため、そのあたりも正しく理解していないと高速動作させることもままならない言語仕様なわけです。

**（追記）
上記の例は、デフォルトコンストラクタとデストラクタがコールされるので、ほぼ影響は無視していいでしょう。
肝は、ぱっと見プログラム上には現れない関数コールが発生することを覚えておいていただければということです。
例えば、上の例ではないですが、コピーコンストラクタであったり、演算子関数であったりが（コンパイラによって）
コールされる場合があるということです。
コメントにてご指摘いただいた通り、その他未定義動作であったりなど動作がわかりにくいトラブルに遭遇することもあります。**



# C/C++を学ぶべき理由
学ぶべき理由は、CにもC++にも共通していることを書きますので一緒に書いちゃいますw

## IoTに役にたつ
今流行りにIoTなわけですw
まぁ最近はJSだかけちゃうなんてのもあったりしますが、割り込みを使ったり、本格的に制御しようとするとC/C++は不可欠になります。わかりますよね？

## CPUの動作理解に役に立つ
PerlでもPHPでもRubyでもPythonでもJavaでもとにかくありとあらゆる言語はコンピュータ上で動作しています。
しかし多くのエンジニアは、コンピュータってどうなっているのだろうか、どうして動作しているのだろうか、などといういわゆるハードウェア的なことは理解が薄いと思います。
しかしC/C++は例えば**ポインタ**ひとつとっても、CPUの動作が分かっていれば難なく理解できることなわけです。

## 高速動作
最近はCPUパワーが強いので、そんなに影響はないと思われがちですが、そうでもありません。
例えば、画像処理。これはとてもCPUパワーを要求され、場合によっては、画像解析時間を厳しく制限される場合があります。こういった場合には、やはり、直接マシン語に変換されるC/C++の方が有利になります。
特に、画像処理なんかは、同じ計算を何回もしなければいけないなんて場合もありますが、こういった場合にはSIMD命令を積極的に使っていくといったこともC/C++を熟知していればできるわけです。

## より深い知識を習得することが可能
いわゆるLinuxやその他のOSはほとんどがC/C++で書かれています。Linuxのカーネルはどうなっているのかなどの深い知識を習得するにはC/C++が必要不可欠なわけです。

## インストールが苦ではなくなる
Linuxなんかは特に、ソースが公開されているが、オブジェクトがないなんて時も多々あります。
しかし、C/C++の知識さえあれば、万が一コンパイルで詰まっても、それを理解し、修正することも可能なわけです。

## 新技術対応が速い
ディープラーニングとか、語句解析とか、最初にC/C++で実装されるケースも多々あります。
またCUDAなどの高速化技術を取り入れやすくなることも事実で、自分でCUDAで実装することも可能になります。

## その他
私個人的には、C/C++はほとんどの言語で参考とされている文法なわけですので、C/C++さえ覚えちゃえばどんな言語でも難なく習得できるというのが一番の利点かと思います。
ソースは俺www

# まとめ
C/C++を習得するメリットデメリットについて簡単に書きました。
このほかにもメリットデメリットは色々あると思います。

C/C++はコンピュータの基礎知識であると言えると思うので、ぜひ習得してもらいたいなと思っていますが、上に書いたように一筋縄にはいかないという現実もあります。


C/C++を学び、少しでも皆さんが、基礎知識を学ぶことができ、コンピュータについて深く理解していくきっかけになれば幸いでございます!


とりあえずCで実装するか。
そんな気持ちになれば、もうあなたも職人レベルですね！