ILE RPG で「センス・オブ・プログラミング」

センス・オブ・プログラミング」という本があり、とてもコンパクトにプログラミングの基本について解説してあります。
前半は特に"プログラム"というものの基礎として、「逐次遂行」「計算」「条件分岐」「ループ」などの解説とサンプルプログラムが載っているのですが、これを RPG で書くとどうなるのだろうかとちょっと思ったので (我流ですが) 書き直してみました。

以前も別の記事でふれましたが、フリー・フォーマットの RPG は C あたりを源流とする"モダン"な言語 (Java だって、上記のような「プログラムの基礎」に関してはほとんど C と同じですね) とほとんど同じようなものになっています。

固定フォーマットはそれ自身のよさがあるのだと思いますが、"モダン"なプログラムのまず一番の特徴である「スタイル」を実装できないことに難点があります。
簡単に言ってしまえば「字下げ」ができない、というのは致命的です。

とりあえず、それぞれについて C から書き直してみました。
最後に載っているワープロの例などはさすがに RPG では無理だと思いますが、大変参考になる本だと思います。ちゃんとした解説などは本の方を参照してください。

ちなみに c のプログラムについてはフリーのボーランドのコンパイラを使用して稼動を確認しています。
入手元は↓です。

http://www.borland.com/jp/products/cbuilder/freecompiler.html

Hello, World

まず最初はおなじみの Hello, World です。

#include <stdio.h>

int main(void)
{
    printf("Hello World!\n");

    return 0;

}

printf の代替ということで DSPLY 命令を使ってみました。

/Free                     
   dsply 'Hello World!' ; 
   *inLR = *on ;          
/End-Free

逐次遂行

命令の順番での実行ですね。

#include <stdio.h>

int main(void)
{
    printf("Hello World!\n");
    printf("Hello World!!\n");

    return 0;

}

これはまぁそのままです。

/Free                      
   dsply 'Hello World!' ;  
   dsply 'Hello World!!' ; 

   *inLR = *on ;           
   return ;
/End-Free

計算する

さすがに内容が当たり前すぎるかと思ってサンプルを作りませんでした ......

変数と入力

変数を受け取って処理します。

#include <stdio.h>

int main(void)
{
    double      base;
    double      height;
    double      area;

    printf("底辺を入力してください>");
    scanf("%lf", &base);

    printf("高さを入力してください>");
    scanf("%lf", &height);

    area = base * height / 2;

    printf("面積は%f\n", area);

    return 0;

}

scanf の代替にもやはり DSPLY を使用しています。
変数の定義には D 仕様書を使用します。

D base            S             10i 0   
D hight           S             10i 0   
D area            S             10i 0   
 *                                      
 /Free                                  

    dsply ' 底辺 : '  '*EXT' base ;     
    dsply ' 高さ : '  '*EXT' hight ;    
    area = base * hight /2 ;            
    dsply  (' 面積は '+ %char(area))   ;

    *inLR = *on ;                       
    return ;
 /End-Free

条件分岐

if の使用ですが、まずは最初に以下の一連のプログラムの叩き台になるシンプルな三角形の面積を計算するプログラムです。
C での sqrt 関数はほぼそのままの %sqrt 関数を使用します。

D a               S             10i 0        
D b               S             10i 0        
D c               S             10i 0        
D s               S             10i 0        
D area            S             10i 0        
 *                                           
 /Free                                       
    dsply 'a.. '  '*EXT' a ;                 
    dsply 'b.. '  '*EXT' b ;                 
    dsply 'c.. '  '*EXT' c ;                 
                                             
    s = (a + b + c) /2 ;                     
    area = %sqrt(s * (s-a) * (s-b) * (s-c)) ;
                                             
    dsply  (' 面積は '+ %char(area))   ;     
                                             
    *inLR = *on ;                            
    return ;                                 
 /End-Free

heron2

if が出てきています。

#include <stdio.h>
#include <math.h>

int main(void)
{
    double      a;
    double      b;
    double      c;
    double      s;
    double      area_pow_2;

    printf("a..");
    scanf("%lf", &a);

    printf("b..");
    scanf("%lf", &b);

    printf("c..");
    scanf("%lf", &c);

    s = (a + b + c) / 2;

    area_pow_2 = s * (s-a) * (s-b) * (s-c);

    if (area_pow_2 < 0) {
        printf("そんな三角形はありません。\n");
    } else { 
        printf("面積は..%f\n", sqrt(area_pow_2));
    }

    return 0;

}

if からのところ、ほとんど同じですね。
endif で if の境界は終わりです。

D a               S             10i 0            
D b               S             10i 0            
D c               S             10i 0            
D s               S             10i 0            
D area_pow_2      S             10i 0            
 *                                               
 /Free                                           
    dsply 'a.. '  '*EXT' a ;                     
    dsply 'b.. '  '*EXT' b ;                     
    dsply 'c.. '  '*EXT' c ;                     
                                                 
    s = (a + b + c) /2 ;                         
    area_pow_2 = s * (s-a) * (s-b) * (s-c) ;     
                                                 
    if (area_pow_2 < 0) ;                        
      dsply  (' そんな三角形はありません ') ;    
    else ;                                       
      dsply  (' 面積は '+ %char(%sqrt(area_pow_2)))   ; 
    endif ;                 
                            
    *inLR = *on ;           
    return ;                
 /End-Free

ループ

プログラムの基幹部分ですね。なくてはならないループ処理です。

while ループ

先に条件をチェックし、その条件が正しいあいだはループされ続ける、というループです。

#include <stdio.h>
#include <math.h>

int main(void)
{
    double      a;
    double      b;
    double      c;
    double      s;
    double      area;

    printf("a..");
    scanf("%lf", &a);

    while (a > 0) {
        printf("b..");
        scanf("%lf", &b);

        printf("c..");
        scanf("%lf", &c);
 
        s = (a + b + c) / 2;
        area = sqrt(s * (s-a) * (s-b) * (s-c));

        printf("面積は..%f\n", area);

        printf("a..");
        scanf("%lf", &a);

    }

    printf("入力終了!\n");

    return 0;

}

DoW (Do While) というオペレーションコードが使用されます。

D a               S              4f               
D b               S              4f               
D c               S              4f               
D s               S              4f               
D area            S              4f               
 *                                                
 /Free                                            
    dsply 'a.. '  '*EXT' a ;                      
                                                  
   DoW ( a > 0) ;                                 
    dsply 'b.. '  '*EXT' b ;                      
    dsply 'c.. '  '*EXT' c ;                      
                                                  
    s = (a + b + c) /2 ;                          
    area = %sqrt(s * (s-a) * (s-b) * (s-c)) ;     
    dsply  (' 面積は '+ %char(area))   ;          
                                                  
    dsply 'a.. '  '*EXT' a ;                      
   EndDo ;                                     
                                               
    dsply  (' 入力終了 !')   ;                 
                                               
    *inLR = *on ;                              
    return ;                                   
 /End-Free

無限ループを作成して、ループの中で条件を比較して、条件があった時に break で脱出する、というループのやり方もあります。

#include <stdio.h>
#include <math.h>

int main(void)
{
    double      a;
    double      b;
    double      c;
    double      s;
    double      area;

    while (1) {
        printf("a..");
        scanf("%lf", &a);
        if (a < 0) {
            break;
         }

        printf("b..");
        scanf("%lf", &b);

        printf("c..");
        scanf("%lf", &c);
 
        s = (a + b + c) / 2;
        area = sqrt(s * (s-a) * (s-b) * (s-c));
        printf("面積は..%f\n", area);
    }

    printf("入力終了!\n");

    return 0;

}

break ではなく leave というオペレーションコードを使用します。
while(1) を書き直すのに、とりあえず常に true である、という意味の同等性をもって DoW ( 1 = 1) としてみました。※

D a               S              4f                
D b               S              4f                
D c               S              4f                
D s               S              4f                
D area            S              4f                
 *                                                 
 /Free                                             
   DoW ( 1 = 1 ) ;                                 
    dsply 'a.. '  '*EXT' a ;                       
    if ( a < 0) ;                                  
     leave ;                                       
    EndIf ;                                        
                                                   
    dsply 'b.. '  '*EXT' b ;                       
    dsply 'c.. '  '*EXT' c ;                       
                                                   
    s = (a + b + c) /2 ;                           
    area = %sqrt(s * (s-a) * (s-b) * (s-c)) ;      
    dsply  (' 面積は '+ %char(area))   ;     
                                             
   EndDo ;                                   
                                             
    dsply  (' 入力終了 !')   ;               
                                             
    *inLR = *on ;                            
    return ;                                 
 /End-Free
※これを書いた時点では知らなかったのですが、
dow '1' ;
と書くことができます。→
以下の部分、そのように読み換えていただいても OK です。

同様の例について、別のサンプルです。

#include <stdio.h>
#include <math.h>

int main(void)
{
    double      a;
    double      b;
    double      c;
    double      s;
    double      area;
    double      total = 0;
    int         count = 0;
    double      max = 0;

    while (1) {
        printf("a..");
        scanf("%lf", &a);
        if (a < 0) {
            break;
         }

        printf("b..");
        scanf("%lf", &b);

        printf("c..");
        scanf("%lf", &c);
 
        s = (a + b + c) / 2;
        area = sqrt(s * (s-a) * (s-b) * (s-c));
        printf("面積は..%f\n", area);

        total += area;
        count++;
        if (area > max) {
            max = area;
         }

    }

    printf("平均値..%f\n", total / count);
    printf("最大値..%f\n", max);

    return 0;

}

ほとんど同じように書くことができるのがわかりますね。

D a               S              4f                  
D b               S              4f                  
D c               S              4f                  
D s               S              4f                  
D area            S              4f                  
D total           S              4f   inz(0)         
D count           S             10i 0 inz(0)         
D max             S              4f   inz(0)         
 *                                                   
 /Free                                               
   DoW ( 1 = 1 ) ;                                   
    dsply 'a.. '  '*EXT' a ;                         
    if ( a < 0) ;                                    
     leave ;                                         
    EndIf ;                                          
                                                     
    dsply 'b.. '  '*EXT' b ;                         
    dsply 'c.. '  '*EXT' c ;                         
                                                    
    s = (a + b + c) /2 ;                            
    area = %sqrt(s * (s-a) * (s-b) * (s-c)) ;       
    dsply  (' 面積は '+ %char(area))   ;            
                                                    
    total += area ;                                 
    count = count + 1;                              
    if ( area > max ) ;                             
     max = area ;                                   
    EndIf ;                                         
                                                    
   EndDo ;                                          
                                                    
    dsply  (' 平均値 ..' + %char(total/count) )   ; 
    dsply  (' 最大値 ..' + %char(max) )   ;         
                                                    
    *inLR = *on ;                                   
    return ;                                        
 /End-Free

後判定型のループ

先にループの中の処理を一回は実行してしまって、その後に判定を行う、というループもあります。

do {
     } while (条件) ;

という形の、とりあえず一回は {} の中の繰り返し処理は実行してもらう、というループですね。
これは DoU (Do Until) というオペレーションコードで実現できます。

配列

若干唐突気味ですが、配列の例です。

D a               S              4f            
D b               S              4f            
D c               S              4f            
D s               S              4f            
D area            S              4f            
D area_array      S              4f   dim(100) 
D total           S              4f   inz(0)   
D i               S             10i 0 inz(0)   
D count           S             10i 0 inz(1)   
D max             S              4f   inz(0)   
 *                                             
 /Free                                         
   DoW ( 1 = 1 ) ;                             
    dsply 'a.. '  '*EXT' a ;                   
    if ( a < 0) ;                              
     leave ;                                   
    EndIf ;                                    
                                               
    dsply 'b.. '  '*EXT' b ;                   
    dsply 'c.. '  '*EXT' c ;                       
                                                   
    s = (a + b + c) /2 ;                           
    area = %sqrt(s * (s-a) * (s-b) * (s-c)) ;      
    dsply  (' 面積は '+ %char(area))   ;           
                                                   
    total += area ;                                
    area_array(count) = area ;                     
    count = count + 1;                             
    if ( area > max ) ;                            
     max = area ;                                  
    EndIf ;                                        
                                                   
   EndDo ;                                         
                                                   
    // 余計な配列を削除                            
    count = count - 1 ;                            
                                                   
    i = 0 ;                                                               
    DoW ( i < count ) ;                                                   
     i = i + 1 ;                                                          
     dsply  (' 三角形 ' + %char(i) + ' 面積は '+ %char(area_array(i)))   ;
    EndDo ;                                                               
                                                                          
    dsply  (' 平均値 ..' + %char(total/count) )   ;                       
    dsply  (' 最大値 ..' + %char(max) )   ;                               
                                                                          
    *inLR = *on ;                                                         
    return ;                                                              
 /End-Free

for ループ

while ループは for ループで書き直すことができます。
どちらかといえば for を使う方がより一般的かもしれません。
ちなみにこちらにも関連記事があります。

DoW を for で書き直したものです。

H DFTACTGRP(*NO)                               
D a               S              4f            
D b               S              4f            
D c               S              4f            
D s               S              4f            
D area            S              4f            
D area_array      S              4f   dim(100) 
D total           S              4f   inz(0)   
D i               S             10i 0 inz(0)   
D count           S             10i 0 inz(1)   
D max             S              4f   inz(0)   
 *                                             
 /Free                                         
   DoW ( 1 = 1 ) ;                             
    dsply 'a.. '  '*EXT' a ;                   
    if ( a < 0) ;                              
     leave ;                                   
    EndIf ;                                    
                                              
    dsply 'b.. '  '*EXT' b ;                  
    dsply 'c.. '  '*EXT' c ;                  
                                              
    s = (a + b + c) /2 ;                      
    area = %sqrt(s * (s-a) * (s-b) * (s-c)) ; 
    dsply  (' 面積は '+ %char(area))   ;      
                                              
    total += area ;                           
    area_array(count) = area ;                
    count = count + 1;                        
    if ( area > max ) ;                       
     max = area ;                             
    EndIf ;                                   
                                              
   EndDo ;                                    
                                              
    // 余計な配列を削除                       
    count = count - 1 ;                                                   
                                                                          
    For i = 1 to count ;                                                  
     dsply  (' 三角形 ' + %char(i) + ' 面積は '+ %char(area_array(i)))   ;
    EndFor ;                                                              
                                                                          
    dsply  (' 平均値 ..' + %char(total/count) )   ;                       
    dsply  (' 最大値 ..' + %char(max) )   ;                               
                                                                          
    *inLR = *on ;                                                         
    return ;                                                              
 /End-Free

サブルーチン・関数

C では関数を使うことが一般的です。
処理の局所化、ですね。

#include <stdio.h>
#include <math.h>

double heron(double a, double b, double c)
{
    double      s;
    double      area;

    s = (a + b + c) / 2;
    area = sqrt(s * (s-a) * (s-b) * (s-c));

    return area;

}

int main(void)
{
    double      outer_a = 6;
    double      outer_b = 8;
    double      outer_c = 10;
    double      inner_a = 3;
    double      inner_b = 4;
    double      inner_c = 5;
    double      outer_area;
    double      inner_area;

    outer_area = heron(outer_a, outer_b, outer_c);
    inner_area = heron(inner_a, inner_b, inner_c);

    printf("面積は..%f\n", outer_area - inner_area);

    return 0;

}

RPG でも関数は使用できます。
上の C の例ではおそらく説明を簡単にするためにプロトタイプ宣言をしていませんが、こちらではやはり実際に使用される局面にあわせてプロトタイプ宣言をしています。

D outer_a         S              4f   inz(6)          
D outer_b         S              4f   inz(8)          
D outer_c         S              4f   inz(10)         
D outer_area      S              4f                   
D inner_a         S              4f   inz(3)          
D inner_b         S              4f   inz(4)          
D inner_c         S              4f   inz(5)          
D inner_area      S              4f                   
 *                                                    
Dheron            PR             4f                   
D a                              4f                   
D b                              4f                   
D c                              4f                   
 *                                                    
 /Free                                                
                                                      
    outer_area = heron(outer_a : outer_b : outer_c) ; 
    inner_area = heron(inner_a : inner_b : inner_c) ; 
                                                            
    dsply  (' 外側の面積は '+ %char(outer_area))   ;        
    dsply  (' 内側の面積は '+ %char(inner_area))   ;        
    dsply  (' 面積は '+ %char(outer_area - inner_area))   ; 
                                                            
    *inLR = *on ;                                           
    return ;                                                
 /End-Free                                                  
 *                                                          
Pheron            B                                         
Dheron            PI             4f                         
D a                              4f                         
D b                              4f                         
D c                              4f                         
D s               S              4f                         
D area            S              4f                         
 *                                                          
 /Free                                                      
    s = (a + b + c) /2 ;                      
    area = %sqrt(s * (s-a) * (s-b) * (s-c)) ; 
    return area ;                             
 /End-Free                                    
Pheron            E

[Top Pageに戻る]

Ads by TOK2