いわゆる 「やさしい入門」 から

ひとつ前の日記 Java をちょっとかじっただけの文系出身セールスエンジニアが C に興味を持つなど (Oct 22, 2011) でも触れましたが、C 言語の独学を始めました。 使用する教本は、通称 K&R とも呼ばれる プログラミング言語 C 第 2 版 ANSI 規格準拠 (B. W. カーニハン / D. M. リッチー著 石田晴久共立出版 1989 ISBN978-4-320-02692-6) です。 今回は、第 1 章 「やさしい入門」 を読んで感じたことなどを書いてみたいと思います。

波括弧

ここで、波括弧 (brace; curly bracket) とは、‘{’ および ‘}’ のことです。 個人的には 「中括弧」 という呼び方に馴染んでいるのですが、日本語版 Wikipedia括弧 の記事によれば、現在では 「中括弧」 と呼ばず 「波括弧」 と呼ぶのが正しいようです。 ちなみに、石田晴久氏は 「大括弧」 と訳していますが、これはさずがに間違いだと思います。

ところで、C 言語における、波括弧の開始位置について、ちょっと違和感を覚えます。

#include <stdio.h>

main()
{
  printf("Hello, World!\n");
}

これまで Java を勉強してきた者としては、どちらかというと次のように書きたいのです。

#include <stdio.h>

main() {
  printf("Hello, World!\n");
}

もっとも、Java であっても、少し年季の入ったソースコードなどでは、波括弧の開始の前に改行をひとつ入れるスタイルもしばしば見かけますので、とやかく言う筋合いのものではありません。 が、何というか、ちょっと気になってしまいました。

printf

C 言語には printf というものがあります。 シンプルにして便利だなあと思います。 C 言語を知らなくても、この関数は知っているつもりでいましたが、今回そんなことはないんだと気づきました。 最初に間違ったのは、次のようなコードを書いてみたときでした。

#include <stdio.h>

main()
{
  printf("%4.2f\n", 1.23);
  printf("%4.2f\n", 12.34);
  printf("%4.2f\n", 123.45);
  printf("%4.2f\n", 1234.56);
}

整数部が 4 桁、小数点以下が 2 桁、というつもりでした。 これなら、次のように右揃えで出力されるだろうと期待していました。

   1.23
  12.34
 123.45
1234.56

しかしながら、実際には、次のように出力されます。

1.23
12.34
123.45
1234.56

当初期待したように出力するためには、前掲のコードを次のように書かなければなりませんでした。

#include <stdio.h>

main()
{
  printf("%7.2f\n", 1.23);
  printf("%7.2f\n", 12.34);
  printf("%7.2f\n", 123.45);
  printf("%7.2f\n", 1234.56);
}

整数部で 4 桁、小数点で 1 桁、小数点以下で 2 桁、つまり合計 7 桁なので、printf の第 1 引数は "%7.2f\n" でなければならないわけです。

それとは別に、もうひとつ、わたしが printf でつまずいたのは、次のようなコードを書いてみたときです。

#include <stdio.h>

main()
{
  int d;
  d = 1234;
  printf("%7.2f\n", d);
}

次のように出力されるだろうと期待してのことでした。

1234.00

しかしながら、現実には、次のように出力されます。

   0.00

型の変換については、まだよく理解していません。 なので、どうしてこのコードがいけないのか、よくわかりません。 あとで、また振り返って考え直すことにしようと思います。

初期化されていない変数の値

たとえば、Java であれば、次のようなコードはコンパイルエラーになります。

public class NotInitializedVariableTest {
  
  public static void main(args[] args) {
    int d;
    System.out.println(d);
  }
  
}

ところが、C 言語では、次のようなコードをコンパイルすることができます。

#include <stdio.h>

main()
{
  int d;
  printf("%d\n", d);
}

ただし、これを実行すると、何が出力されるかは不定のようです。 わたしの手元の環境では、2147348480 (Windows の場合) だったり -1216237580 (Linux の場合) だったりしています。 それらも、常にそうだというわけではなく、実行のつど値が変化したりしなかったりしています。

後の章などで、ときどき、値は 「ゴミ (garbage)」 です、といったような記述が散見されますので、そういうことなのかもしれません。

うっかり初期化を忘れてもコンパイルエラーにならないところが、C 言語における要注意ポイントなのかもしれません。

まとめ

ほかにも、少し細かいところで気になる点はいくつかありますが、とりあえず本日はここまでにします。