Cを経験してみよう

まだ経験したことないの? 誰だって最初は初めてなんだよ。ちょ、ちょっと、何変なこと考えてるの! C言語のことだからねっ!

スポンサーリンク

こんな時代にC言語

ウェブアプリやスマホアプリが席巻する昨今。プログラミング言語と言って思い浮かぶのは、PythonだったりRubyだったりJavaScriptだったりPHPだったり。同じC言語の系統でも、そこから進化したC++、Java、C#なんかがあったりして、今さら無印のC言語に何の意味があるのかと思われるかもしれません。

プログラミング言語の人気ランキングやら年収ランキングのようなものをよく見かけますが、そもそもプログラミング言語というのは適材適所なので、どれが優れているとか劣っているとかというのはありません。

とは言っても、さすがに無印のC言語は、ねぇ。実際の現場で使うことも無さそうだし…。

C言語には基本が詰まっている

然り。今や、C言語が使われている現場は少ないです。なので、「C言語を経験しよう」と言っても、現場で使えるから経験しようという意味ではありません。

僕が言いたいのは、C言語にはコンピュータと対話するための基本が詰まっているので、一度は一通り勉強しておいたほうがいいよ、ということです。

コンピュータのしくみ

昔ながらの書籍や情報処理試験の教科書などには、こういう「コンピュータの原理」的な図が載っているかもしれません。しかし、今時のプログラミング言語というのは、こういう泥臭い部分は高度に抽象化されて内部の奥深くに隠蔽されています。

泥臭い部分というのは、「プログラムを使って現実の問題を解決する」という点においては、ぶっちゃけ本質ではありません。だから、そんな泥臭いことに気を使わなくていいように最近のプログラミング言語はうまく設計されているのです。

C言語は古い言語です。まだそのような高度な抽象化は行われておらず、今メモリがどういう状態でどんなデータの列が流れているのかを慎重に把握しないと、すぐにエラーが発生してしまいます。面倒の極みですね。

でも、逆に言えば、C言語はそういう一番泥臭いところまで降りていって厳密にコンピュータを制御できるプログラミング言語であるともいえます。C言語を学べば、おのずとコンピュータの原理を知ることができるというわけです。

泥臭いことをしなければいけないとき

例えば、最近の新しいプログラミング言語を使って、Web上から何かデータを取ってきたとします。もしそのデータがバグってたらどうしよう?

バグデータ

例えばそのWeb通信では、1~19のうちのどれかの数字が来るはずだったとしましょう。ところが実際に取得されたデータは301989888。な、なんじゃこりゃ、バグってるぞ!

カンのいい方はお気付きかもしれませんが、これはリトルエンディアンとビックエンディアンの違いによるものです。301989888は16進で0x12000000。ってことは多分、本来は0x00000012だったんだな、送られてきた数字は10進で18か、ということがわかります。

C言語を一通り学んでいれば、エンディアンの話がどこかで出てくると思います。そして、バグった数字を見てピンと来るわけです。インディアン、うそつかない。

わかってしまえばあとはバイト順を逆にすればいいだけです。最新のプログラミング言語は基本的には高度に抽象化されていますが、バイト順を逆にするような泥臭い方法も大体用意されています。滅多に使うことが無いのでググることになると思いますが、解決の糸口は見えています。

エンディアンの話は1つの例ですが、他にも文字エンコードの問題とか浮動小数点の精度の問題とか、いろいろと難しい問題に直面したとき、C言語で学んだ知識はきっと役に立つはずです。

文字列すらもデータ列

ほとんどの最新のプログラミング言語では、文字列は文字列として扱います。つまり、"puyo"という文字列があったらそれは"puyo"以外の何物でもありません。

しかしC言語では、"puyo"という文字列があったら、それは

70 75 79 6F 00

というデータ列です。文字列というのはなかなか厄介なもので、長さの情報だったりエンコードの情報だったりを適切に扱わなければいけません。最近はそんなことを考えなくても文字列を文字列として扱えるありがたい時代になりましたが、もし文字に関する取り扱いでバグが発生したときは、文字列の正体はデータ列であるということを思い出してバグ修正に取り組まないといけなくなることもあります。

そんなときもやはり、C言語で学んだ知識は大いに役に立つことでしょう。

ポインタ

C言語を学ぶ上で初学者の大きな壁となっているのが、悪名高きポインタです。教科書にはよく、こんな解説があります。

int a = 0;
int *b = &a;
*b = 1;
printf("%d\n", a);   /* 1が出力される */

いやまぁそうなんだけどさ、何がしたいねん? って思うよね。

わざわざこんなややこしいことをして、何がメリットなのかわからない。教科書にも、そういうメリット的なことが何も書いてないので、どうにもこうにも身に付かない。

これは個人的な意見なんですが、僕はポインタより先に、構造体と関数を学ぶべきだと思うんですよ。文字列操作のために必要なポインタの知識は最小限に留めておいて、「*b = 1」のようなアホみたいなことをぐだぐだ解説するより先に、構造体と関数を。

typedef struct _Person {
    int person_id;
    int is_dead;
    int age;
} Person;
void AddAge(Person *p)
{
    if (p->is_dead) return;
    p->age++;
}

まず、世の中のデータというのは大体、「整数」だとか「文字列」だとかの単一のデータじゃなくて、「人間一人の情報」とか「建物1個の情報」とかのような複合的なものなので、それを構造体という形で表わしましょう、という指針。

そして、データを操作するためには関数を定義して、同じ操作を何度でも別のデータに対して行えるようにサブルーチン化する習慣。

この2つを先にしっかり学んでおけば、ポインタの有用性というのはおのずと見えてくると思います。おお~、こりゃ便利だ~、ってね。

そりゃぁ誰だっていきなり 「*b = 1」 とか言われたら嫌になりますよ。なんでそんな意味の無いことを覚えなアカンねん、って。そうじゃなくてもっと、有用性も含めてポインタを学べるようなカリキュラムになっていればいいのにな~と、つくづく思います。

学ぶか学ばざるか

今の時代、現場ではほとんど使われていないC言語。だけど基本が詰まっているC言語。まずコンパイラやら開発環境を用意するのも時代遅れすぎて大変ですが、そんなC言語を学ぶか学ばざるかは、あなた次第。

スポンサーリンク