パソコン活用研究シリコンバレー(C、C++、の活用研究)



Cで計算機を作る(足し算、引き算)
―準備中―

C言語で計算機を作ってみます。まずは足し算、引き算だけの基本形から。

プログラムはVB.netで作ったプログラムをC用に改変したものなので、
プログラムの説明は「VB.netで計算機を作る(足し算、引き算)」をご参照下さい。

ここでは、VB.netからC用に改変したコードの部分のみ説明を書きます。

列挙型、構造体の宣言の書き方
VB.netとCでは若干違う。違いはコードを見てください。

Cでは、関数のプロトタイプ宣言が必要。

関数get_token

Cではreturnで構造体変数そのものをを返り値にできないので、
構造体tokenの変数tokをグローバル変数として宣言し、tokを関数の引数として呼び出して、
その引数(構造体変数tok)を変更することにより、変更した値を渡している。
VB.net版ではreturnで構造体の変数そのものを返り値にしている。

ほとんどのコードはほぼ似たようなものですが、異なっているのは以下の2か所

文字列を整数型に変換するところは
VB.netでは、 tok(pos).v = Integer.Parse(tok(pos).str)
Cでは、tok[pos].v = atoi(tok[pos].str)

読み込んだ文字を文字列に連結していくところは
VB.netでは、tok(pos).str = tok(pos).str + statement.Chars(i)
Cでは strcpy(tok[pos].str,st)


calc0.0a.c Borland C++用

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>



typedef enum{
    number,
        dot,
        add_op,
        sub_op,
        mul_op,
        div_op,
        lparen,
        rparen,
        space,
        bad,
        line_end,
        } type;
        
typedef struct {
        type type;
        char str[20];
        int v;
        } token;

type checktype(char);
double expression(void);
double primary_expression(void); 
void get_token(token *t);
void unget_token(void);

token tok[30];  
        
int main(void) {
/* token tok[30]; */  /* Declare as a local variable in the main function */
int i,pos,isnum,len;
double value;
type r;
char exp[50], st[2];

gets(exp);
  len = strlen(exp);
for (i=0; i < len; i++) {
  printf("%d : %c\n", i, exp[i]);
  }
  
        
  printf("token:%d\n",len);
  pos=0;
  isnum=0;
for(i=0; i < len; i++) {
        r=checktype(exp[i]);
/*      printf("%d :%c  : %d \n",i,exp[i],r); */
        st[0]=exp[i]; st[1]='\0';
        
        if (r == space)  continue;  
        if (r == bad)  break;
        if (isnum == 1 && r == number) { strcat(tok[pos].str,st);  tok[pos].v = atoi(tok[pos].str); continue;}
        if (isnum == 1 && r == rparen) { pos = pos + 1 ; strcpy(tok[pos].str,st);  tok[pos].type = r; continue;}
        if (isnum == 1 && (r == add_op || r == sub_op || r == mul_op || r == div_op)) { pos = pos + 1;  strcpy(tok[pos].str,st); tok[pos].type = r ; pos = pos + 1;  isnum = 0; continue;}
        if (isnum == 0 && r == lparen) { strcpy(tok[pos].str,st); tok[pos].type = r; pos = pos + 1; continue; }
        if (isnum == 0 && r == number) { strcpy(tok[pos].str,st); tok[pos].type = r; tok[pos].v = atoi(tok[pos].str); isnum = 1;}
        if (isnum == 0 && r == sub_op) { strcpy(tok[pos].str,st);  tok[pos].type = number; isnum = 1;}
    }

        tok[pos+1].type=line_end;
        
        for( i = 0; i <= pos+1; i++) {
                printf("%d : %s; %d\n",i,tok[i].str,tok[i].type); 
        }

if (r == bad) printf("Wrong expression\n");
        
printf("calculate\n");
        value=expression();
        printf("value=%lf",value);
        
        return 0;
        
}

type checktype(char t) {
                type r;
                r=bad;
                if (isdigit(t) != 0 )  r=number;  /* isdigit return ascii code, if augument is numeric */
                if (t == '+') r=add_op;
                if (t == '-') r=sub_op;
                if (t == '*') r=mul_op;
                if (t == '/') r=div_op;
                if (t == '(') r=lparen;
                if (t == ')') r=rparen;
                if (t == ' ') r=space;
/*      printf("%c  : %d \n",t,r); */
        return (r);
        }


double expression() {
        double v1, v2;
        token t;
        
        v1=primary_expression();
        printf("expession v1:%lf\n",v1);
        
        while (1){
            get_token(&t);
            printf("expression %s: %d : %d\n", t.str, t.type, t.v);
        if (t.type != add_op && t.type != sub_op) { unget_token(); break;}
            v2 = primary_expression();
            printf("expression v2:%lf\n", v2);
        if (t.type == add_op)  v1 = v1 + v2;
        if (t.type == sub_op)  v1 = v1 - v2;
            printf("expression calculated  v1:%lf\n", v1);
        }

        return (v1);
}


double primary_expression() {
         token t;
        get_token(&t);
        printf("primary_expression %s: %d : %d \n", t.str, t.type, t.v);
        if (t.type == number)  return (t.v);
        else return (0);
 }

void get_token(token *t) {
         static int i = 0;
        printf("get_token %d: %s : %d : %d \n", i, tok[i].str, tok[i].type, tok[i].v);
        /* Assign the structure  *t=toku[i]  */
        *t=tok[i];
        i++;
}

void unget_token() {
}




次回は、乗算・除算もできるようにします。ー>「Cで計算機を作る(乗算・除算)

TopPage