プログラミングのメモ帳(C/C++/HSP)

日々のプログラミングで気づいた点や小技集を紹介します。(Windows 10/XP/Vista、VC2017、HSP)

[HSP]整数電卓のソース

2018年08月06日 19時55分00秒 | HSP講座

スクリプト言語の HSP については、公式ホームページの「HSPTV!」をどうぞ。(戻る)


ここには、整数電卓のサンプル・ソースを載せておきます。
この整数電卓は、整数型(32ビット)を使った9桁の簡単な電卓です。
そのため小数部は自動的に切り捨てられます。
また、便利な[=]キーの連続演算、累乗、逆数も対応してません。
しかし、その分だけ理解しやすかったり、機能拡張や自作ソフトに組み込みやすい事でしょう。

使い方

  • [AC]キーは[A]、[ESC]キー
  • [CE]キーは[C]キー
  • [→]キーは[B]、[BS]キー
  • [±]キーは[TAB]キー
  • [=]キーは[ENTER]キー
  • 置数キーは[0]~[9]の数字キー
  • 演算キーは[+]、[-]、[*]、[/]キー

エラーが発生した場合には、[A]、[ESC]キーでしかエラーをクリアできません。

整数電卓のソース

管理上このサンプルは sample97c(整数電卓).hsp のソースです。

//------------------------------------------------------------------------------
// 整数電卓の製作講座 by 科学太郎
//==============================================================================
// 新規作成日:2015-12-23 (水) 13:14:00
// 最終更新日:2015-12-24 (木) 04:12:00
//------------------------------------------------------------------------------

//--------------------------------------
// 記号定数
//--------------------------------------
#const MAX_DIGIT    (999999999)

//--------------------------------------
// 列挙定数(キー番号)
//--------------------------------------
#enum KEY_AC=0
#enum KEY_7
#enum KEY_4
#enum KEY_1
#enum KEY_0
#
#enum KEY_CE
#enum KEY_8
#enum KEY_5
#enum KEY_2
#enum KEY_00
#
#enum KEY_BS
#enum KEY_9
#enum KEY_6
#enum KEY_3
#enum KEY_EQU
#
#enum KEY_CHG
#enum KEY_DIV
#enum KEY_MUL
#enum KEY_SUB
#enum KEY_ADD

//--------------------------------------
// 列挙定数(演算マーク)
//--------------------------------------
#enum OPE_SET=0                         ;[ ]マーク
#enum OPE_ADD                           ;[+]マーク
#enum OPE_SUB                           ;[-]マーク
#enum OPE_MUL                           ;[×]マーク
#enum OPE_DIV                           ;[÷]マーク
#enum OPE_EQU                           ;[=]マーク

//--------------------------------------
// メイン部
//--------------------------------------
*Init
    g_sw=0                              ;表示モード(0=結果メモリ,1=入力メモリ)
    g_ope=0                             ;演算マーク(OPE_xxx)
    g_ans=0                             ;結果メモリ
    g_num=0                             ;入力メモリ
    g_err=' '                           ;エラー文字(SPC,'E')
    g_mark(0)=" ","+","-","×","÷","="
*Main
    x=6+6+(64*4)
    y=6+6+(32+24*5)+6
    screen 0,x,y,SCREEN_NORMAL|SCREEN_TOOL:gsel 0,2
#if(0)
    x=(x/2)
    gradf 0,0,x,y,0,$339900,$CCFF66
    gradf x,0,x,y,0,$CCFF66,$009900
#else
    y=(y/2)
    gradf 0,0,x,y,1,$339900,$CCFF66
    gradf 0,y,x,y,1,$CCFF66,$009900
#endif
    title "整数電卓"
    ;ボタンの配置
    x=6
    y=6+32+6
    pos x,y:x+=64
    button gosub "AC",*Push
    button gosub "7",*Push
    button gosub "4",*Push
    button gosub "1",*Push
    button gosub "0",*Push
    pos x,y:x+=64
    button gosub "CE",*Push
    button gosub "8",*Push
    button gosub "5",*Push
    button gosub "2",*Push
    button gosub "00",*Push
    pos x,y:x+=64
    button gosub "→",*Push
    button gosub "9",*Push
    button gosub "6",*Push
    button gosub "3",*Push
    button gosub "=",*Push
    pos x,y:x+=64
    button gosub "±",*Push
    button gosub "÷",*Push
    button gosub "×",*Push
    button gosub "-",*Push
    button gosub "+",*Push
    ;割り込み設定
    onkey gosub *OnKeyBoard
    ;液晶画面
    font "HG明朝E",32
    repeat
        if(g_sw){
            DrawCalc 6,6,(6+64*4-1),(6+32-1),g_num
        }else{
            DrawCalc 6,6,(6+64*4-1),(6+32-1),g_ans
        }
        await 100
    loop
    stop
//--------------------------------------
// 液晶画面の描画
//--------------------------------------
#deffunc DrawCalc int _cx_,int _cy_,int _ex_,int _ey_,int _num_
    redraw 0
    color $33,$66,$33:boxf(_cx_+0),(_cy_+0),(_ex_-0),(_ey_-0)
    color $CC,$DD,$CC:boxf(_cx_+1),(_cy_+1),(_ex_-1),(_ey_-1)
    color $66,$99,$66:pos _cx_,_cy_
    mes strf("%c%12s.%s",g_err,MakeComma(_num_),g_mark(g_ope))
    redraw 1
    return
//--------------------------------------
// カンマ文字列の作成
//--------------------------------------
#defcfunc MakeComma int _num_,\
    local s0,\
    local s1,\
    local s2,\
    local s3,\
    local s4
    
    if(_num_<0):return"-"+MakeComma(-_num_)
    s0=strf("%13d",_num_)
    s1=strmid(s0,0,4):if(peek(s1,0)!=' '):poke s1,0,'\''
    s2=strmid(s0,3,4):if(peek(s2,0)!=' '):poke s2,0,'\''
    s3=strmid(s0,6,4):if(peek(s3,0)!=' '):poke s3,0,'\''
    s4=strmid(s0,9,4):if(peek(s4,0)!=' '):poke s4,0,'\''
    s0=s1+s2+s3+s4
    return strtrim(s0)
//--------------------------------------
// 電卓ボタンの分岐
//--------------------------------------
*Push
    if(g_err=='E')and(stat!=KEY_AC)     :return
    switch stat
        case KEY_AC:    CalcAC          :swbreak
        case KEY_CE:    CalcCE          :swbreak
        case KEY_BS:    CalcBS          :swbreak
        case KEY_CHG:   CalcCHG         :swbreak
        case KEY_00:    CalcNum 0
        case KEY_0:     CalcNum 0       :swbreak
        case KEY_1:     CalcNum 1       :swbreak
        case KEY_2:     CalcNum 2       :swbreak
        case KEY_3:     CalcNum 3       :swbreak
        case KEY_4:     CalcNum 4       :swbreak
        case KEY_5:     CalcNum 5       :swbreak
        case KEY_6:     CalcNum 6       :swbreak
        case KEY_7:     CalcNum 7       :swbreak
        case KEY_8:     CalcNum 8       :swbreak
        case KEY_9:     CalcNum 9       :swbreak
        case KEY_ADD:   CalcOpe OPE_ADD :swbreak
        case KEY_SUB:   CalcOpe OPE_SUB :swbreak
        case KEY_MUL:   CalcOpe OPE_MUL :swbreak
        case KEY_DIV:   CalcOpe OPE_DIV :swbreak
        case KEY_EQU:   CalcOpe OPE_EQU :swbreak
    swend
    return
//--------------------------------------
// [AC]ボタンの処理
//--------------------------------------
#deffunc CalcAC
    g_sw=0
    g_ope=0
    g_ans=0
    g_num=0
    g_err=' '
    return
//--------------------------------------
// [CE]ボタンの処理
//--------------------------------------
#deffunc CalcCE
    g_num=0
    return
//--------------------------------------
// [→]ボタンの処理
//--------------------------------------
#deffunc CalcBS
    if(g_sw):g_num/=10:else:g_ans/=10
    return
//--------------------------------------
// [±]ボタンの処理
//--------------------------------------
#deffunc CalcCHG
    if(g_sw):g_num=-g_num:else:g_ans=-g_ans
    return
//--------------------------------------
// 置数ボタンの処理
//--------------------------------------
#deffunc CalcNum int _num_
    if(g_sw==0){
        g_sw=1
        g_num=0
    }
    if(abs(g_num)<=(MAX_DIGIT/10)){
        g_num*=10:if(g_num<0):g_num-=(_num_):else:g_num+=(_num_)
    }
    return
//--------------------------------------
// 演算ボタンの処理
//--------------------------------------
#deffunc CalcOpe int _ope_
    if(g_sw){
        if OverFlowCheck(g_ope){
            if(g_num<0):g_num=-1:else:g_num=1
            if(g_ans<0):g_ans=-1:else:g_ans=1
            g_sw=0
            g_ans=g_ans*g_num*MAX_DIGIT
            g_ope=OPE_EQU
            g_err='E'
            return
        }
        switch g_ope
            case OPE_SET:g_ans =g_num:swbreak
            case OPE_EQU:g_ans =g_num:swbreak
            case OPE_ADD:g_ans+=g_num:swbreak
            case OPE_SUB:g_ans-=g_num:swbreak
            case OPE_MUL:g_ans*=g_num:swbreak
            case OPE_DIV:g_ans/=g_num:swbreak
        swend
        g_sw=0
    }
    g_ope=_ope_
    return
//--------------------------------------
// オーバーフローのチェック
//--------------------------------------
#defcfunc OverFlowCheck int _ope_
    if(_ope_==OPE_ADD){
        if(abs(g_ans+g_num)>MAX_DIGIT):return 1
    }
    if(_ope_==OPE_SUB){
        if(abs(g_ans-g_num)>MAX_DIGIT):return 1
    }
    if(_ope_==OPE_MUL){
        if(abs(g_num)>abs(MAX_DIGIT/g_ans)):return 1
    }
    if(_ope_==OPE_DIV){
        if(g_num==0):return 1
    }
    return 0
//--------------------------------------
// キーボードの割り込み処理
//--------------------------------------
*OnKeyBoard
    if(g_err=='E')and(iParam!=$1B)and(iParam!='A'):return
    switch iParam
        case $1B:CalcAC             :swbreak    ;[ESC]
        case 'A':CalcAC             :swbreak
        case 'C':CalcCE             :swbreak
        case 'B':CalcBS             :swbreak
        case $08:CalcBS             :swbreak    ;[BS]
        case $09:CalcCHG            :swbreak    ;[TAB]
        case '0':CalcNum 0          :swbreak
        case '1':CalcNum 1          :swbreak
        case '2':CalcNum 2          :swbreak
        case '3':CalcNum 3          :swbreak
        case '4':CalcNum 4          :swbreak
        case '5':CalcNum 5          :swbreak
        case '6':CalcNum 6          :swbreak
        case '7':CalcNum 7          :swbreak
        case '8':CalcNum 8          :swbreak
        case '9':CalcNum 9          :swbreak
        case '+':CalcOpe OPE_ADD    :swbreak
        case '-':CalcOpe OPE_SUB    :swbreak
        case '*':CalcOpe OPE_MUL    :swbreak
        case '/':CalcOpe OPE_DIV    :swbreak
        case $0D:CalcOpe OPE_EQU    :swbreak    ;[ENTER]
    swend
    return
//------------------------------------------------------------------------------
// End of IntCalc.hsp
//------------------------------------------------------------------------------

スクリーン・ショット

関連記事



コメント   この記事についてブログを書く
« [HSP]モニター付きランチャ... | トップ | [HSP]単位文字列について »
最新の画像もっと見る

コメントを投稿

HSP講座」カテゴリの最新記事