C言語によるプログラミングに関する世界観(A.戯言)です。
C++も参照のこと。
ツール関係はC/C++ツールに移動しました。
システムに依存する部分はLinux(システムコール・API)やWindowsプログラミングも参照のこと。
C/C++は、UNIXやWindowsなどのOSの開発に良く使われる。特に、メモリの操作のような低レベルな処理が可能であることが大きい。
UNIXやWindowsなどにおいて、ネイティブなアプリケーションの開発に良く使われる。
テレビや自動車のような、組み込み機器のような分野で、良く使われる。ただ、最近は「一度書けばどこでも動く」と言う側面から、Javaが使われることも多い。
ゲーム機やゲームソフトの開発にも良く使われる。これはゲームのグラフィックス描画などで、高速な処理が必要だからである。OpenGLが使われることもある。
C言語はそもそもUNIXというOSを書くために生まれた言語。当初からアセンブラを高い移植性でもっと綺麗に書くことを目標としているため、「綺麗なアセンブラ」のような言語である、という特徴がある。ポインタのようなアセンブラ由来の仕組みを採用し、メモリ管理は自分で行わなければならない。アセンブラ言語についてはアセンブラを参照のこと。
そもそもがUNIXの言語であったため、UNIXというOSととても親和性が良い。UNIXのAPIであるopen()/close()/read()/write()は、C言語のライブラリAPIにもそのまま考え方として受け継がれている。LinuxのAPIを参照のこと。
また、Linuxではgccのように、C言語のコンパイラが無料かつオープンソースで用意されている、という点も挙げられる。Linuxでの開発は主にgccとmakeによって行う。Linuxディストリビューションを開発向けに導入するならば、こうした開発環境は必須である。Visual StudioをWindows向けに買うよりもコストが安く、入門者向けである。Linuxはソフトウェアのソースコードもオープンであるため、tarballを解凍してすぐに改造することができる。GNUツールチェインやC/C++ツールを参照のこと。
だが、素のC言語では、コマンドラインでの手続き型プログラムの開発はできるが、オブジェクト指向のような「高度な機能」は用意されていない。この点は、C++の機能を使う必要がある。また、GUIの開発を行うためには、Xサーバーやそれなりのライブラリを使用しなければならない。X11、GNOME、KDEを参照のこと。
Windows開発では、C/C++、C#、VB.NETが使われることが多い。Windowsプログラミングを参照のこと。
C言語が動く環境は多い。そのため、機能の少ない組み込み系の開発には良く使われる。
それに、JavaやRubyはあくまでお遊びのプログラミング言語だ。なぜなら、コンピュータは機械語で動くから、C言語で書かれた何らかのプログラムが既に存在しなければ、JavaやRubyだって動かない。JavaやRubyでプログラミングしたくても、C言語で仮想マシンやインタプリタを作らなければ、動くはずはない。
C/C++言語はコンパイル言語であるため、Javaや.NETに比べて速度が速い。ValaやRustもコンパイル言語だが、C/C++より高速にはならない。
特に、最新のC++には機能が多い。
特に、スマートポインタのように、newとdeleteを使ってメモリを確保するだけではなく、安全かつ自動的にメモリを解放してくれる仕組みは最近存在する。
テンプレートやジェネリックのような機能もC++にはある。
だから、最新のC++を持ってすれば、Javaを使うべき領域は少なくなるかもしれない。
C/C++は、「OSを書くための言語」であると言えます。ここで言うOSとは、カーネルやUNIXのユーザーランドだけではなく、Xサーバーやデスクトップ環境、デスクトップアプリケーションまでを含めたOSです。
確かに、JavaやRubyでアプリケーションを開発した方が、生産性も高くきちんと動くでしょう。ですが、たとえばOfficeやWebブラウザのようなアプリケーションを作りたい場合、C/C++を使って作ります。
WebブラウザやGUIアプリケーションまで含めた「オペレーティング環境」を作るための言語がC/C++です。そのため、既存のシステムを改良したり、オープンソースで開発に参加したい全てのプログラマが、低レベルなC/C++を習得する必要があります。
C/C++言語は、Javaのようなガベージコレクション機能がないため、自分でメモリを管理しなければならない。
そのため、malloc()やfree()のようなメモリ管理関数を使って、動的に管理する場合は、取得したメモリを自分で解放しなければならない。
これは、OSのような基盤的プログラムでは、自分でメモリ管理が出来る、と言う意味で良い点だが、アプリケーションとなると、メモリリークの原因になってしまう。
そのため、Javaのような最初からガベージコレクションが備わっている言語の方が、アプリケーションの開発の意味では作りやすいだろう。
後日注記:逆に、手動で確保したメモリを解放するC/C++の方が、自分でやる代わり確実である、といった考え方もできる。Javaでは、参照がなくなったメモリ領域は自動で回収されるが、参照がある間メモリに残り続ける。C/C++では、自分の解放したい場合や状況に応じて、いつでもメモリを解放できる。
C/C++言語は、プラットフォーム依存性が高く、Windowsの環境ではWindows向けにしか開発出来ず、Linuxの環境ではLinux向けにしか開発出来ないところがある。
この点でも、Javaのようなクロスプラットフォーム性が最初から意識されている言語よりも、作りにくいところがあるかもしれない。
また、PythonやRubyのようなスクリプト言語から言うと、コンパイルしなければならない、という問題もある。
特に、サーバーサイドで動く言語の場合、サーバーに対して実行ファイルをコピーするのは難しい。サーバーで動く環境向けにコンパイルするのは出来ないこともある。
PerlやPHPのようなスクリプト言語なら、サーバーにコピーするのはテキスト形式のスクリプトでよく、手軽である。
それから、Windows向けに配布する場合など、商用のコンパイラしかないことが考えられる。開発するために、有料でお金を出してコンパイラを買わなければならない。
スクリプト言語なら、Windowsの場合はインタプリタをインストールしなければならないかもしれないが、UNIXやMacなどではスクリプトで簡単にコマンド一つで実行出来る。
もちろんC/C++言語でもライブラリを使うことは出来るが、Javaや.NETのような最初から何でも揃っているライブラリがなかなか存在しない。
元々、C/C++のプログラミングでは、ライブラリのような関数も含めて、全て自分たちで開発しなければならない、という風潮がある。
もちろんC/C++の標準ライブラリも存在するが、たまに旧式の使ってはならない関数があったり、文字列をどうするのだと言った問題があったり、簡単に正規表現やネットワーク接続が出来ない、などの問題もある。
Javaや.NET、スクリプト言語などでは、そうしたほとんどの良く使われる関数は最初からクラスライブラリとして揃っている。Javaを使う理由は、まさにそれが一番多いだろう。
C言語のプログラムは、その奇妙さから「何が書いてあるのか分からない」と言う人が多いです。
ですが、基本的にプログラムというものは、「機械にも分かるような手順を書く」だけです。
機械にでも分かる、というのは、機械には計算とメモリ操作しか分かりません。計算とレジスタやメモリの操作はアセンブリ言語で表現できますが、Cではそうしたものを「拡張」して、「構造化プログラミング」を行います。Cで書かれたプログラムは、原則アセンブリ言語にコンパイルされ、機械語に変換された状態でCPUが読み取って実行されます。
C言語でプログラムを書くということは、計算とメモリ入出力しかできないCPUプロセッサに対して、「制限された中で機械でも分かるように手順を書く」ということです。
そう、Cのコードは手順にすぎません。それも、制約がかかった上での手順です。ですから、より分かりづらくなります。
このC言語の入門を読むことで、そのコードを「どのように解読すれば良いか」が分かります。
ですが、実際のところ、プログラミングで重要なのは、「記法」ではなく「目的」です。
プログラムは、人間の頭脳がやっていることと同じことをします。ある特定の領域に記憶領域を確保し、その中に記憶を整理しながら、計算し、論理に基づいて判断し、ファイルの読み書きやネットワークの転送やグラフィックスの描画を行います。
ここで、重要なのは、「人間の頭脳と同じことをできる」ということです。特に、プログラムは「自動的」に人間の頭脳と同じことをやります。「やっていることは人間のやっていることと全く同じ」なのです。
そして、大切なのは、記法ではなく、目的です。そのプログラムが、コンピュータの資源(リソース)を使って、どのようなことをやるか、という「明確な目的」が必要です。
プログラミングを学ぶ、ということは、決してプログラムを作るための記法を学ぶことだけではありません。プログラムの目的を明確化し、何をどのように行うかを考えながら、必要なリソースの処理と制御フローのアルゴリズムを考え、記法に落とし込んでいく、つまり「プログラミングとは、目的を明確化した上で、どのような手段で実現するかを考える」ということなのです。このために、C/C++やJavaのようなプログラミング言語があるのです。