Cプログラミング入門

第22回[最終回]Appendix.3 配列とポインタ、構造体と共用体、makeについて

年頭から始まったこの連載も最終回となりました。ここまでのご愛読ありがとうございます。最終回の今回は、Cならではの特徴的なTipsをまとめて取り上げます。

配列

C言語では、配列

char array[10];

のように宣言します。この例ではchar型の、要素数10のarrayという配列が宣言されています。配列の添字は0から数え、この例ではarray[0]からarray[9]までの10個の要素が使えます。

C言語では文字列はchar型の配列です。また、配列名はその配列の先頭要素を指すポインタになります。 リストA3.1は、char型のbufという配列を宣言し、この要素にbuf[0]から順番に1文字ずつ「Hello World」の文字を代入して、printf()を行っています。配列名のbufは、その先頭要素へのポインタとなるため、printf()の引数にこれを渡してprintf(buf)とすることができます。

また、C言語の文字列の仕様により、buf[]に代入される文字の最後の\nの次に\0という特殊文字を入れて、文字列の終端を表す必要があります。

リストA3.1 hello_array.c
#include <stdio.h>

int
main()
{
  char buf[32];

  buf[0] = 'H';
  buf[1] = 'e';
  buf[2] = 'l';
  buf[3] = 'l';
  buf[4] = 'o';
  buf[5] = ' ';
  buf[6] = 'W';
  buf[7] = 'o';
  buf[8] = 'r';
  buf[9] = 'l';
  buf[10] = 'd';
  buf[11] = '\n';
  buf[12] = '\0';

  printf(buf);
  return 0;
}

ポインタ

C言語では、char型へのポインタpを、

char *p;

と宣言します。p自体はchar型へのポインタであり、*pはchar型のひとつの値を指しています。

リストA3.2は、" "で囲まれた文字列をchar型へのポインタであるpに代入しています。C言語では、" "で囲まれた文字列自体がchar型へのポインタの型を持ち、その値は文字列の先頭の文字を指しているため、これをいったんpに代入してからprintf(p)とすることができるのです。

リストA3.2 hello_pointer.c
#include <stdio.h>

int
main()
{
  char *p;

  p = "Hello World\n";
  printf(p);
  return 0;
}

関数の呼び出し

プログラム中の一定の処理をまとめて、関数として独立させることができます。プログラムが大きくなると、main()関数に直接プログラムが書き切れなくなり、mainから、各関数を呼び出す形でプログラムの記述が行われるようになります。

hello.cは短いプログラムですが、これをあえて関数にして関数呼び出しを行った例をリストA3.3に示します。

リストA3.3 hello_function.c
#include <stdio.h>

static void
pr(char *p)
{
  printf(p);
}


int
main()
{
  pr("Hello World\n");
  return 0;
}

構造体

構造体を使えば、複数の変数をひとまとめにしてあたかも1つの変数のように使うことができます。構造体は次のような形で宣言されます。

struct s_example {
  int i;
  char *p;
};

共用体

C言語には、構造体と似た共用体という型も存在します。共用体では、構造体とは違って共用体内の各メンバーが、同じメモリを共有します。共用体は次のような形で宣言されます。

union u_example {
  unsigned char c[4];
  unsigned long l;
};

makeコマンドを単独で使う

プログラムをコンパイルするたびにgccのコマンドラインを入力するのは大変です。makeというコマンドを使えば、gccのコマンドラインの入力作業を自動化することができます。たとえばhello.cをコンパイルするためには、図A3.1の実行例のように、単にmake helloとコマンド入力すれば、makeコマンドがhelloという実行バイナリファイルを作るためのgccのコマンドラインを自動的に考え、gcc hello.c -o helloというコマンドを実行します。

図A3.1 make helloの実行例
$ make hello
gcc  hello.c  -o hello
$

最適化オプションを付けたい場合は、あらかじめそのオプションを環境変数CFLAGSの値にセットしておきます図A3.2⁠。

図A3.2 make helloの実行(環境変数CFLAGSをセット)
$ CFLAGS=-O2
$ export CFLAGS
$ make hello
gcc -O2  hello.c -o hello
$

ここで紹介した例は、makeコマンドのほんの一部の使い方に過ぎません。通常は、カレントディレクトリにMakefileという、makeのルールを記述したファイルを用意します。makeコマンドはMakefileの内容を読んで、プログラムのコンパイルのために必要なコマンドを判断します。

Makefileを記述すれば、makeコマンドにもっと複雑な判断を行なわせることが可能ですが、ここでの例のように単純なプログラムのコンパイルならば、Makefileがなくてもmakeコマンドを使ってのコンパイルが可能です。

おすすめ記事

記事・ニュース一覧