はじめての C

C programming note*1
今度は、ポインタ配列の argv が 使われてる プログラム。(p64-65) これは UNIX の コマンド cat と ほぼ 同じ 働きをする。 つまり こういうことが 可能、

$./cat1 file1 file2 file3 > outfile
コードは こちら、
/* cat1.c */
#include

main(int argc, char *argv[])
{
FILE *fp;
int c;

--argc; /* argv[0] の分を 減らす */
++argv; /* ← ここで 使われてる */

if (argc < 1) { /* パラメータが ないと */
fprintf(stderr, "parameter error\n");
exit (1);
}

while (argc--) { /* パラメータの順に file を 渡っていく */
if )((fp = fopen(*argv, "r"))( == NULL) {
fprintf(stderr, "can't open %s\n", *argv);
exit (1);
}
while )((c = fgetc(fp))( != EOF)
fputc(c, stdout);
fclose(fp);
argv++; /* 次の ポインタ配列へ */
}

return 0;
}

while の中に も1つ while が あり、そこの部分は ptr2 プログラムに 似ている。 その詳しいことは どんどん 後まわしにしといて、標準エラー出力の 仕組みから、

標準エラー出力 standard error は stdio.h で 定義されている 名前で、特別な ストリームの 一種だ。 どういう ストリームかと いうと、名前から 予想されるとおり「エラーメッセージの出力」に 使われる。

標準エラー出力は、通常は ユーザが見ている 画面に 出力されている。 リダイレクション '>' によって 標準出力が ファイルなどに つなぎ替えられたときも、標準エラー出力は 切り替えられずに そのまま 画面に 出力される

この性質を 利用して、データの出力に エラーメッセージが 混じってしまうのを 防ぐことが 可能だ。(p66)

フムフム ...
次は cat プログラムを いじって、複数の 関数に 分けてみる ...んだけど、cat1 には インクリメント演算子が いくつも 使われてるので、その説明から、

インクリメント increment 演算子は 変数の値を 1つ分 増加させるもので
i++
というのは、
i = i + 1
という式と ほとんど 同じである。 つまり 整数型の 変数に 適用した場合は「値を 1つ 増やす」という 働きになる。

逆に、変数の値を 1つ分 減らす デクリメント演算子は "--" だ。

実は インクリメント演算子と デクリメント演算子には、
i++
というように 使う 使い方のほかに
++i
という 使い方がある。 どちらも「i の値を 1 増やす」という機能には 変わりはないが、その式の値に 違いがある。

前者は 式の値を 評価してから インクリメントが 行なわれるが、後者は インクリメントしてから その式の値を 評価する。

「式の値を 評価する」とは、「その結果が 式の値となる」と いったほうが わかりやすいかもしれない。

たとえば、i の値が 10 だったとき、
j = i++;
では i は 11 になるが、j には 増加 (インクリメント) する前の 10 が 代入される。

それに 対して、
j = ++i;
では、i は やはり 11 になるが、j にも 増加後の 11 という数値が 代入される。(p54-55)

この cat1 プログラムには 両方 使われてますね。

*1:「作ってわかる Cプログラミング」