C言語-インタプリタminiCASL
前へ 目次へ 次へ 

 8. プログラムの類似部分を関数にする

 mc08.cのプログラムでは、各演算を処理しているプログラム部分が演算子(+,−,*,/)を除いて同じである。ここでは、共通(類似)部分を関数にするなどしてプログラム全体を短くしてみる。

29〜33行目 変数番号を計算する部分を関数にする。
  関数名はget_valnumとする。処理は次のとおりである。

トークン(グローバル変数token)の先頭文字が
  英字(変数名) → 変数番号(0〜25)を返却する。
  その他 → エラーを表示して終了する。

35〜42行目 変数の値または数値に変換する部分を関数にする。
  関数名はget_paraとする。処理は次のとおりである。

トークン(グローバル変数token)の先頭文字が
  英字(変数名) → 変数に記憶されている値を返却する。
  数字 → 数値を返却する。
  その他 → エラーを表示して終了する。
[mc09.c]
 1:
 2:
 3:
 4:
 5:
 6:
 7:
 8:
 9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "gettoken.h"

#define STRMAX 80       /* 文字列配列の大きさ */
/* グローバル変数 */
double hensuu[26];      /* mc言語の変数用 */

void main(int argc, char *argv[])
{
    int     get_valnum(void);   /* 変数番号取得関数 */
    double  get_para(void);     /* 引数取得関数 */
    FILE    *fp;                /* ファイル操作用 */
    char    inbuff[STRMAX];     /* 入力データ用 */
    int     val;                /* 変数番号用 */

    if(argc != 2){      /* パラメータのチェック */
        printf("使い方:MC filename\n");
        exit(1);
    }
    if((fp = fopen(argv[1], "r")) == NULL){     /* ファイルのオープン */
        printf("ファイルがオープンできませんでした。\n");
        exit(1);
    }
    while(fgets(gt_line, STRMAX, fp)){     /* データの読み込み */
        get_token();
        if(!strcmp(token, "add")){    /* 命令判定 */
            get_token();
            val = get_valnum();
            get_token();
            hensuu[val] = hensuu[val] + get_para();
        }else if(!strcmp(token, "sub")){
            get_token();
            val = get_valnum();
            get_token();
            hensuu[val] = hensuu[val] - get_para();
        }else if(!strcmp(token, "mul")){
            get_token();
            val = get_valnum();
            get_token();
            hensuu[val] = hensuu[val] * get_para();
        }else if(!strcmp(token, "div")){
            get_token();
            val = get_valnum();
            get_token();
            hensuu[val] = hensuu[val] / get_para();
        }else if(!strcmp(token, "end")){
            break;
        }else if(!strcmp(token, "in")){
            get_token();
            val = get_valnum();
            printf("in=");
            gets(inbuff);
            hensuu[val] = atof(inbuff);
        }else if(!strcmp(token, "out")){
            get_token();
            val = get_valnum();
            printf("%f\n", hensuu[val]);
        }else{
            printf("Error : コマンドエラー\n");
            continue;
        }
    }
    fclose(fp);         /* ファイルのクローズ */
}
int get_valnum(void){
    if(isalpha(*token)){
        return(toupper(*token) - 'A');  /* 変数番号 */
    }else{
        printf("変数を指定してください。\n");
        exit(1);
    }
}
double get_para(void){
    if(isalpha(*token)){
        return(hensuu[toupper(*token) - 'A']);  /* 変数値 */
    }else if(isdigit(*token) || *token == '+' || *token == '-'){
        return(atof(token));                    /* 数値 */
    }else{
        printf("変数または数値を指定してください。\n");
        exit(1);
    }
}
実行結果
D:\Data\src>cc mc09.c gettoken.obj
lld @link.i
D:\Data\src>mc09 reidai04.mc
in=12.345
in=11.111
23.456000
12.345000
123.450000
-12.345000

 関数get_valnum()とget_para()のプロトタイプ宣言を関数main()の中でしている。この2つの関数は関数main()の中からしか呼び出していないからである。
 関数のプロトタイプ宣言も変数の宣言も同じで、関数ないで宣言するとその関数内だけで使用できる。関数外で宣言すると同一ファイル内のすべての関数(正確には宣言よりあとの関数)で使用できる。


前へ 目次へ 次へ 
Copyright © 2001 Hiroshi Masuda 

 

 

inserted by FC2 system