パソコン活用研究5番街(Visual Basic、Excel(VBA)、BASIC プログラミング研究)

構造体変数の渡し方(プログラミング言語による違い)
〜計算機を作る番外編

「VB.NETで計算機を作る」プログラムの、get_token関数では、構造体変数をreturnで返していますが、
他のプログラミング言語に移植するときは、この部分をそれぞれの言語にあわせて変更する必要が
あります。

VB.Netで計算機を作る(足し算引き算)のプログラムの当該部分


Structure token
Dim type As type
        Dim str As String
        Dim v As Integer
    End Structure

    Public tok(20) As token

   Function expression() As Double
        Dim v1, v2 As Double
        Dim t As token

        v1 = primary_expression()
        Console.WriteLine("expression v1:{0}", v1)
        While (1)
            t = get_token()
            Console.WriteLine("expression {0}: {1} : {2} ", t.str, t.type, t.v)
            If (t.type <> type.add_op And t.type <> type.sub_op) Then unget_token() : Exit While
            v2 = primary_expression()
            Console.WriteLine("expression v2:{0}", v2)
            If t.type = type.add_op Then v1 = v1 + v2
            If t.type = type.sub_op Then v1 = v1 - v2
            Console.WriteLine("expression calculated  v1:{0}", v1)
        End While

        Return v1

    End Function

    Function primary_expression() As Double
        Dim t As token
        t = get_token()
        Console.WriteLine("primary_expression {0}: {1} : {2} ", t.str, t.type, t.v)
        If t.type = type.number Then Return t.v Else Console.WriteLine("Syntax error") : End
    End Function

    Function get_token() As token
        Static Dim i As Integer = 0
        REM       t = tok(i)
        Console.WriteLine("get_token {0}: {1} : {2} :{3} ", i, tok(i).str, tok(i).type, tok(i).v)
        REM Console.WriteLine("get_token {0}: {1} : {2} :{3} ", num_token, t.str, t.type, t.v)
        i = i + 1
        Return tok(i - 1)
    End Function

C言語では構造体変数丸ごとをreturnで返すことができないので、構造体変数のポインタを引数として
渡して(参照渡し)、get_tokenをコールし、get_token関数のなかで、構造体のそれぞれのメンバ変数に
値を代入することで、結果を返しています。

typedef struct {
        type type;
        char str[20];
        int v;
        } token;

token tok[30];  

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);
        t->type=tok[i].type; 
        strcpy(t->str,tok[i].str);
        t->v=tok[i].v;
        i++;
}

Pythonには構造体はないので、クラスを使います。
Tokenというクラスを用意し、tokという変数に代入します。
更にtoksという変数のリストとして、tokを追加していきます。


class Token:
  def __init__(self,k,str,v):
        self.kind=k
        self.str = str
        self.v=v

def get_token():
# global変数のcountを使うという宣言
        global count 
        print("get_token:", count,":", toks[count].str,":", toks[count].kind,":", toks[count].v)
        
        count = count + 1
        return toks[count-1]






def primary_expression():
        t = get_token()
        print("primary_expression :", t.str, t.kind, t.v)
        if t.kind == kind.number: return t.v 
        else: print("Syntax error"); end




def expression():

  v1 = primary_expression()
  print("expression v1:", v1)
  while 1:
    t = get_token()
    print("expression:",t.str, t.kind, t.v)
    if (t.kind != kind.add_op and t.kind != kind.sub_op) : unget_token() ; break
    v2 = primary_expression()
    print("expression v2:", v2)
    if t.kind == kind.add_op: v1 = v1 + v2
    if t.kind == kind.sub_op: v1 = v1 - v2
    print("expression calculated  v1:", v1)
        
  return v1

tok=Token(kind.number,"",0)
toks=[tok]






TopPage > Visual BasIc&Excel活用研究目次