今度のプロジェクトはBREWなのでC言語を使う。今まで本格的に使ったことがなかったが、改めて触ってみるとなかなか面白い。
Cで一番癖があると思ったのは、型のメモリ領域の確保についてだ。Javaの場合、参照型はnew演算子を使用して明示的にメモリ領域を確保するが、Cの場合、宣言とメモリ領域の確保は同時に行われる。メモリ領域を確保したくなければ、ポインタとして宣言する必要がある。
だから、以下に示したJavaのコードをCで置き換えると、こんな感じになる。
class Foo {
int bar;
int zoo;public static void main(String[] args) {
Foo foo_fill = new Foo();
Foo foo_empty = null;
}
}
typedef struct _Foo {
int bar;
int zoo;
} Foo;int main() {
Foo foo_fill;
Foo *foo_empty;return 0;
}
多分、C使いの人にとっては自明のことなんだろうが、ようやくポインタが多用される理由がわかった。インスタンスを生成しないで、型の宣言だけしたかった訳だ。
メモリ領域の確保について少し理解できるようになると、malloc()について別の利点がわかる。今まで「動的にメモリ領域が確保する関数」と考えていたが、今は「スコープに左右されないメモリ領域を確保する関数」と考えている。
例えば、以下のコードでは変数aは関数func()が終了した瞬間にメモリ領域が開放されるが、bはfree()で明示的にメモリ領域を開放しなければならない。
int func() {
char a[256];
char *b;b = malloc(sizeof(char) * 256);
...
}
だから、malloc()を使えば、関数foo()で確保したメモリ領域を関数bar()で開放する、ということができる。
void foo(char **pstr) {
*pstr = malloc(sizeof(char) * 256);
}void bar(char *str) {
free(str);
}int main() {
char *str;foo(&str);
...
bar(str);return 0;
}
知らない言語を学ぶと、いつも新しい発見があるのがとても楽しい。