条件判断と分岐を書き換える
オプション・スイッチを調べる処理でifを使いましたが、1つの文字を順に調べていく場合にはswitch caseの方が合理的です。リスト1を書き換えてみましょう。
switch caseで書き換える
リスト1では、forループの中でpがパラメータ文字列の先頭アドレスを受け取って、その先頭が'-'であった場合、続く1文字をifで調べていきました。調べる対象が同じなら、switch caseの方が効率的であることは既に説明したとおりです。
そこで、forループの中の最初のif文で先頭文字が'-'であった場合、続く1文字がc、n、f、wのいずれかなら対応する処理を実行する部分をswitch caseを使って書き換えたのがリスト2です。
処理結果はまったく変わりませんが、どの変数を何と比べてどのように処理するのか──という処理構造は、こちらの方が分かりやすくなります。
リスト2:リスト1と同じ処理をswitch case文で書き直した(ex2902.c, ex2902.exe)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define bool int /* 論理型を定義 */
#define _FALSE 0 /* 偽 */
#define _TRUE !_FALSE /* 真 */
int main(int argc, char * argv[])
{
int i; /* ループカウンタ */
char *p; /* 各パラメータ(argv[])の受け皿 */
/* 各パラメータを保持する変数 */
char *filename;
char *word;
bool sw_capt = _FALSE;
int maxnum = 0;
for (i=1; i<argc; i++) {
p = argv[i];
if (p[0] == '-') {
p++;
/* '-'記号の次の1文字で分岐 */
switch (p[0]) {
case 'c' : {
sw_capt = _TRUE;
}
case 'n' : {
maxnum = atoi(++p);
}
case 'f' : {
filename = ++p;
}
case 'w' : {
word = ++p;
}
default : {
/* 先頭が'-'でなければ何もしない */
}
}
}
}
/* パラメータの示す内容を表示 */
printf("Caps : %s, MaxNumber : %d, File name : %s, Word : %s\n",
sw_capt ? "TRUE" : "FALSE", maxnum, filename, word);
}
forの代わりにwhileも使える
main関数の第1引数argcがパラメータの数を保持しているため、リスト1もリスト2も繰り返し処理には以下のようにforループを使っています。
for (i=1; i<argc; i++) {
配列argvの最後はNULLポインタとなっているため、whileループで『argv[ ]がNULLでない間』という条件を指定しても同じことになります。
i = 1;
while (p = argv[i++]) {
:
}
|
|
|