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 |