● StrCalc の実装

1-1.基本手順

StrCalc Ver 3.9 のほとんどの関数は、初期化と終了処理を必要とします。

  1. 関数StrCalc_init により初期化

  2. StrCalc を使用する

  3. 全ての処理が終わったら関数StrCalc_term を呼び出し、終了処理を行う

例1.

#include <stdio.h>
#include "sc39.h"

void    main(void)
{
    STRCALC_PARAM       prm;
    int                 ret;

    /*
      StrCalc環境の初期化。
      このエラーチェックは必ず行ってください。
    */
    if (!StrCalc_init(&prm)){
        printf("メモリの確保に失敗しました\n");
        return;
    }

    /* 計算式を格納する領域のアドレスをメンバ str にセットします */
    prm.str = "sin(4.53)^2 + cos(4.53)^2";

    ret = StrCalc(&prm); /* 計算を行う */

    /* 環境の解放 */
    StrCalc_term(&prm);

    if (ret != STATUS_NORMAL)
        printf("error.  %d\n",ret);
    else
        printf("ans. : %.16G\n",prm.ans);
}

例1ソースファイル(zip)

関数StrCalc_init は、変数、数学関数、定数の情報を管理する環境を、STRCALC_PARAM 構造体の実体の中に作成します。StrCalc の関数は、その環境を使用して計算処理を行い、関数StrCalc_term により環境を解放します。
計算に必要な情報は、全て STRCALC_PARAM 構造体の中に納まっていますので、実体を複数用意すれば、その数だけ異なる環境を作成する事ができます。


関数StrCalc を使用する時は、STRCALC_PARAM 構造体のメンバstr に計算対象の文字列を指定します。この文字列は末尾がヌルである必要があります。
関数実行後、エラーが無ければメンバ ans に結果が格納されています。

引数に環境(STRCALC_PARAM 構造体)のアドレスを指定する関数は、StrCalc_init 、StrCalc_term による一連の手順を必要とします。

環境を指定する関数を実行した場合、環境の内容は更新されると思ってください。例えば、関数StrCalc_substitution 等は内部でメンバstr を使って関数StrCalc を呼び出すため、関数の呼び出し前、呼出し後では内容が異なります。


1-2.括弧の階層

括弧の階層とは、括弧の中に括弧がある状態(入れ子、ネスト、nest)の事を指します。

    (1+2+3+4+5+6)+7       一階層

    (1+2+3+(4+5)+6)+7     二階層

    ((1+2+3+(4+5))+6)+7   三階層

この階層には制限が設けられており、STRCALC_PARAM 構造体のメンバ paren_cnt に設定されている階層数が上限となっています。このメンバは、関数StrCalc_init によりデフォルト値 64 が設定されます。

関数StrCalc_init 実行後に、このメンバの値を変えれば、括弧の階層数上限を変更する事ができます。

通常の使用で 64 階層にもなる事は無いと思います。
多くの場合、デフォルトのままで問題は無いと思いますが、デバッグや記述の洗練のために、条件を厳しくする方向で(階層数上限を減らす方向で)変更する使い方もあります。


1-3.計算式で乱数を使用する場合

数学関数の "rnd" (擬似乱数)を計算式で使用する場合は、関数StrCalc を実行する前に StrCalc_srand を実行して、擬似乱数を初期化してください。

例2.

#include <stdio.h>
#include <time.h>
#include "sc39.h"

void    main(void)
{
    STRCALC_PARAM       prm;
    int                 i,ret;

    if (!StrCalc_init(&prm)){
        printf("メモリの確保に失敗しました\n");
        return;
    }

    /* StrCalc の擬似乱数初期化 */
    StrCalc_srand((unsigned)time(NULL));

    /* 乱数を 10 回表示する */
    prm.str = "rnd(100)";
    for(i = 0;i < 10;i++){
        if ((ret = StrCalc(&prm)) != STATUS_NORMAL){
            printf("error.  %d\n",ret);
            break;
        }else
            printf("%2d : %.16G\n",i + 1,prm.ans);
    }

    StrCalc_term(&prm);
}

例2ソースファイル(zip)

乱数を使用する事が事前に判らない場合は、とりあえず初期化しておく事を推奨します。

なお、StrCalc の擬似乱数は、関数srand(標準:stdlib.h)では初期化できない事に注意してください。