私のおもちゃ箱-プログラミングテキスト


プログラミング何でも掲示板(過去分)
私のおもちゃ箱
 −−プログラミングテキスト−−
<> フローチャート
<> ハードウェア
<> C言語 (C language)
<> Visual Basic 2005
<> Visual Basic 6.0
<> COMETU & CASLU
<> JavaScript
<> HSP 3.0
<> Windows Xp
  Word2000, Excel2000,PowerPoint2002
<> ホームページ作成

過去ログ
メニューに戻る


CASL2 PRと分岐命令  しほる - 2008/12/01(Mon) 23:15 No.250

こんばんわ、先日はお世話になりまして
どうも有難うございます。

ttp://masudahp.web.fc2.com/casl2/
上記urlも"算術、論理等演算命令 2-2"まで勉強させて頂きました。

現在「PRと分岐命令」を勉強しております。
シュミレータの理解不足(命令行、PR、EA、FR、M(EA))で、今一つ掴めていおりません
当方の解答プロセスにご助言頂ければ幸いです。
---------- ---------- ----------
【問1】
実行した命令語のアドレスとPRを16進数、FRを3ビットと日本語、GR0とGR1を10進数でトレースしなさい。

   RET6002 START
8000:     LAD  GR0,1
8002:     LD   GR1,DATA
8004: LOOP  ADDA  GR1,ONE
8006:     JOV   EXIT
8008:     JNZ   L1
800A:     JZE   L2
800C:     LAD   GR0,2
800E: L1   JMI   L11
8010:     JPL   L12
8012:     LAD   GR0,3
8014: L11  LAD   GR0,4
8016:     JUMP  LOOP
8018: L12  LAD   GR0,5
801A:     LAD   GR1,32767
801C:     JUMP  LOOP
801E: L2   LAD   GR0,6
8020:     JUMP  LOOP
8022: EXIT  RET 
8023: DATA  DC   -2
8024: ONE   DC   1
  :     END
---------- ---------- ----------
8002:は、命令行=#8002、PR=#8004、EA=#8023、FR=010(負)、M(EA)=-2  GR0=1 GR1=-2
(FRは、演算結果の情報なので 1+(-2)=-1 FR=010(負)で良いのでしょうか?)

8004:は、命令行=#8004、PR=#8006、EA=#8024、FR=、M(EA)=1  GR0=1 GR1=-1
(解答ではFR=010(負)です。が、演算結果は0になるのでは…)

8006:は、命令行=#8006、PR=#8008、EA=#8022、FR=(負)、M(EA)=-32512(#8100)  GR0=1 GR1=-1
(RETは#8100(負)であり。しかし、演算結果は0になるのでは…)

、という具合で行詰っております。(8006:以下わかりません)
アドバイス頂ければ幸いです、宜しくお願いします。

Re: CASL2 PRと分岐命令  しほる - 2008/12/02(Tue) 21:54 No.251

解答プロセスの修正

8002:、8004:について凡ミスをしておりました。
後日、問題をよく読み返し 解答プロセスを下記の通り修正いたします。

8002:、8004: ともに問われているのは、GR1= なので
---------- ---------- ----------
8002:のGR1=-2 なので、FR=010(負)
8004:のGR1=-1 なので、FR=010(負)
---------- ---------- ----------

Re: CASL2 PRと分岐命令  Hiroshi - 2008/12/02(Tue) 22:36 No.252

ようこそ、しほる さん
まずは質問についてです。
>8002:は、命令行=#8002、PR=#8004、EA=#8023、FR=010(負)、M(EA)=-2  GR0=1 GR1=-2
>(FRは、演算結果の情報なので 1+(-2)=-1 FR=010(負)で良いのでしょうか?)
8002はLD命令でGR1=-2になったためFR=010(負)です。

>8004:は、命令行=#8004、PR=#8006、EA=#8024、FR=、M(EA)=1  GR0=1 GR1=-1
>(解答ではFR=010(負)です。が、演算結果は0になるのでは…)
8004で算術加算(ADDA)をするので、GR1=-2+1=-1です。

>8006:は、命令行=#8006、PR=#8008、EA=#8022、FR=(負)、M(EA)=-32512(#8100)  GR0=1 GR1=-1
>(RETは#8100(負)であり。しかし、演算結果は0になるのでは…)
8006では演算をしません。

次に、トレース結果です。
   RET6002 START      ;PR,GR0,GR1,FR(OSZ)
8000:     LAD  GR0,1   ;8002,1,?,000
8002:     LD   GR1,DATA ;8004,1,-2,010
8004: LOOP  ADDA  GR1,ONE ;8006,1,-1,010
8006:     JOV   EXIT  ;8008,1,-1,010
 →FRを参照してジャンプを判定します。OV=0ですからジャンプせず、次の行に移ります。
8008:     JNZ   L1   ;800E,1,-1,010
 →FRを参照してジャンプを判定します。ZF=0ですからL1にジャンプします。
800E: L1   JMI   L11   ;8014,1,-1,010
 →FRを参照してジャンプを判定します。SF=1ですからL11にジャンプします。
8014: L11  LAD   GR0,4  ;8016,4,-1,010
 →LAD命令ではFRは変化しません。
8016:     JUMP  LOOP   ;8004,4,-1,010
8004: LOOP  ADDA  GR1,ONE ;8006,1,0,001
8006:     JOV   EXIT  ;8008,1,0,001
8008:     JNZ   L1   ;800A,1,0,001
 →FRを参照してジャンプを判定します。ZF=1ですからジャンプせず、次の行に移ります。
800A:     JZE   L2   ;801E,1,0,001
 →FRを参照してジャンプを判定します。ZF=1ですからL2にジャンプします。
801E: L2   LAD   GR0,6  ;8020,6,0,001
8020:     JUMP  LOOP   ;8004,6,0,001
8004: LOOP  ADDA  GR1,ONE ;8006,1,1,000
8006:     JOV   EXIT  ;8008,1,1,000
8008:     JNZ   L1   ;800E,1,1,000
 →FRを参照してジャンプを判定します。ZF=0ですからL1にジャンプします。
800E: L1   JMI   L11   ;8010,1,1,000
 →FRを参照してジャンプを判定します。SF=0ですからジャンプせず、次の行に移ります。
8010:     JPL   L12   ;8018,1,1,000
 →FRを参照してジャンプを判定します。SF=0ですからL12にジャンプします。
8018: L12  LAD   GR0,5  ;801A,5,1,000
801A:     LAD   GR1,32767 ;801C,5,32767,000
801C:     JUMP  LOOP   ;8004,5,32767,000
8004: LOOP  ADDA  GR1,ONE ;8006,5,-32768,100
8006:     JOV   EXIT  ;8022,5,-32768,000
 →FRを参照してジャンプを判定します。OF=1ですからEXITにジャンプします。
8022: EXIT  RET       ;8022,5,-32768,000

急いでトレースしましたので、誤りがあるかもしれませんが、参考にしてみてください。

それでは、またいつでもどうぞ。

Re: CASL2 PRと分岐命令  しほる - 2008/12/04(Thu) 22:11 No.254

Hiroshiさん、アドバイスありがとうございます。
ラベルの…RET6002 わざわざお調べ下さったのでしょうか
すみません、お気遣い頂いて恐縮です。

問題を解く上で、ネックになっていったところが、"JOV,JPL,JMI,JZE,JNZ命令ではFR設定しない"というところでした。
(参考書やWEB等で、上記命令について仕様説明がされていますが…実際に問題に触れて、解けずに挫折しないと
それ{FR設定しない}を実感できないものですね…勉強になりました)
改めて、FR設定しない命令を再確認できました。

FR設定しない:ST,LAD,OV,JPL,JMI,JZE,JNZ命令
FR設定する:LD,ADDA,SUBA命令
RET:PRはE000

大変参考になりました、アドバイス有難うございます。

Re: CASL2 PRと分岐命令  Hiroshi - 2008/12/05(Fri) 23:46 No.255

しほるさん、参考になりなによりです。
もう一言だけ。
>RET:PRはE000
これは、正確ではないと思います。CASL2は仮想計算機COMET2で動作する言語です。
実際には存在しない計算機で、メモリ上の番地が決められているわけではありません。
問題の前提として、「システムプログラムから呼び出されたCASL2のプログラムは8000番地以降に
ロードされて実行される。実行後、システムのE000番地に戻る。」であれば、"RET:PRはE000"で
正解ですが、前提がなければ"RET:PRは????"で不定です。ということで、私のトレースでは、
"RET:PRは8022"のままとしてあります。
紙の上で考えるときに具体的に番地を割り当てて動作を実感してもらう目的のようですが、
基本情報処理試験の過去問を見ても番地を問う問題はなかったと思います。分岐先はラベルで
指定されていますし、GRとFRの値の変化、実行順を正しくトレースできればよいと思います。
あまり番地にとらわれずに考えていけばいいと思います。
それでは、勉強がんばってください。

Re: CASL2 PRと分岐命令  しほる - 2008/12/06(Sat) 21:35 No.256

RETのPRについて、フォローして頂いてありがとうございます

>紙の上で考えるときに具体的に番地を割り当てて動作を実感してもらう目的のようですが、
なるほど、確かにCASLUの参考書内の問題は番地指定がされています。
初心者が言語を学習する上
学習者(CASLU未経験者)は、その番地指定(予めの前提として、8000番地からスタート等)された問題を解き
CASLUを理解していくという事なのですね。

RET = E000 というのは、(○:問題の前提上。   ×:CASLUの概念)

初学習者で恐縮です、有難うございます。

CaslUを学習しています  しほる - 2008/11/18(Tue) 22:27 No.244

初めまして、しほる と申します

基本情報処理試験に向けてCASLUの問題集で学習しております
(学習書:福嶋宏訓 著 CASLU完全合格教本)

問題が解けず行き詰った際に、こちらの掲示板を知り訪問致しました。
どうぞ、宜しく御願い致します。


次の問題で解らない箇所があります
アドバイス頂ければ幸いです。

■問題   FRを3ビットで、GR1とGR3を10進数でトレースしなさい。

   RET4002   START
8000:       LD   GR1,P32760
8002:       ADDA  GR1,TEN
8004:       LD   GR1,M32760
8006:       SUBA  GR1,TEN
8008:       LD   GR1,P32760
800A:       LD   GR3,P32760
800C:       ADDA  GR1,GR3
800D:       LD   GR1,M32760
800F:       LD   GR3,P32760
8011:       SUBA  GR1,GR3
8012:       RET     
8013:TEN      DC 10
8014:P32760    DC 32760
8015:M32760    DC -32760
         END

質問@
#8002:のGR1は、-32766となっております。
#8002のGR1を求めるには、「#8002を算術10進数にせよ」というのが問いの本質なのでしょうか?
#8002を書き直す(算術10進数)と、確かに-32766ですが、

ADDA GR1←GR1+M(TEN)は? この式は必要ないの? #8002だけを考えれば良いの?

と、不安になります。
また、下記解説は何のためのものでしょうか?
(FRを導き出すためのものであるとは理解はするのですが、GR1を問われているのだから…あまり関係ないのでは?)
-----
>解説
>32760+10=32770になり、32768よりも大きいため#8002番地のADDA命令であふれが発生し、OFが1になります。
わかります。

>16進数で足し算すると、#7FF8 + #000A = #8002で、符号ビットが1なのでSFが負数の1になります。
これもわかります。…が。
-----
つまり、#8002に至っては、余計な計算せず、#8002を算術10進数に書き直す。という事でしょうか?
(問題というのは、今まで「計算を解いて答えを出すもの」と思い、解いてきましたので…何か落着かない心持です)


質問A
#8006:のGR1は、トレースリストを確認すると+32766 となっておりますが
なぜ、そうなるのか解りません。プロセスを解説頂ければ幸いです。

と、初歩的な質問で恐縮です
お助け頂ければ幸いです。

Re: CaslUを学習しています  Hiroshi - 2008/11/19(Wed) 01:33 No.245

ようこそ、しほる さん
■問題 「FR」を3ビットで、「GR1」と「GR3」を10進数でトレースしなさい。

答えは次のようになります。

   RET4002  START         GR1 GR3  OSZ
8000:      LD   GR1,P32760  32760 ??  000
8002:      ADDA  GR1,TEN   -32766 ??  110
8004:      LD   GR1,M32760  -32760 ??  010
8006:      SUBA  GR1,TEN    32766 ??  100
8008:      LD   GR1,P32760  32760 ??  000
800A:      LD   GR3,P32760  32760 32760 000
800C:      ADDA  GR1,GR3   -16  32760 110
800D:      LD   GR1,M32760  -32760 32760 010
800F:      LD   GR3,P32760  -32760 32760 000
8011:      SUBA  GR1,GR3    16  32760 100
8012:      RET
8013:TEN     DC 10
8014:P32760   DC 32760
8015:M32760   DC -32760
        END
ポイントは、32767(#7FFF)に1を算術加算すると-32768(#8000)になると言うことと、正の上限を
超えたのでOFが1に、計算結果が負数になるのでSFが1になると言うこと。また、逆に-32768(#8000)
から1を算術減算すると32767(#7FFF)になると言うことと、負の上限を超えたのでOFが1になる
ことです。すなわち、正と負の境界の値の変わり方とそのときのフラグ変化がポイントです。

「質問@」に書かれていることは、番地の8002と16進数の#8002が混同されていませんか。
8002番地の命令 ADDA GR1,TEN の計算結果がたまたまその番地と同じ#8002(-32766)になっただけです。
ですから、この命令は必要です。
解説は、その通り、FRを導き出すためのものです。問題をよくご覧ください。FR,GR1,GR3が問われて
います。

「質問A」は、8004番地でGR1に-32760が格納されます。次の8006番地でGR1から10を算術減算します。
-32760-10=-32770ですが、負数の上限を2だけ超えています。負数の上限 -32768から1ずつ減算して
いくと「-32768 → 32767 → 32766」となっていきます。すなわち、-32770は32766のこととなります。
16進数で計算すると、#8008(-32760)-#000A(10)=#7FFE(32766)となります。

私のサイトにCASLのテキストもありますので、よろしければご覧ください。
http://masudahp.web.fc2.com/casl2/
また、同じページの下の方に、
「情報処理技術者試験 COMETII & CASLII シミュレータ InfoCASL
東京理科大学  情報処理技術者試験研究会」
を紹介しています。実際に実行してみるとよくわかると思います。

それでは、またいつでもどうぞ。


Re: CaslUを学習しています  しほる - 2008/11/19(Wed) 21:50 No.246

有難うございます。とても解り易いご指摘で、内容を理解できました。


「質問@」についてのご指摘通り、番地の8002と16進数の#8002が混同してました
#8002(16進数)と理解した後、32766(#8002)を算術10進数に直して -32766 となるのですね。

「質問A」について、"すなわち、-32768から2つ超えている"のご説明で理解できました。

1000 0000 0000 1000
+1111 1111 1111 0110

=0111 1111 1111 1110 =32766(#7FFE)

全問、ご回答頂いて大変助かりました。
800Cも8011も解けず、参考書とにらめっこしていたところ(汗)
回答の16と、-16をもとにプロセスを考えて解答に辿り着きました。
-----------------------------------------
800C: ADDA GR1,GR3  GR1←GR1+GR3

32760+32760=

0111 1111 1111 1000
+0111 1111 1111 1000

=1111 1111 1111 0000 =-16(#FFF0)
-----------------------------------------
8011: SUBA GR1,GR3  GR1←GR1-GR3

-32760-32760=

1000 0000 0000 1000
+1000 0000 0000 1000

=0000 0000 0001 0000 =16(#0010)
-----------------------------------------

http://masudahp.web.fc2.com/casl2/
テキストまでご案内頂いて恐縮です、有難うございます
こちらもお世話になります、勉強させて頂きます。

済みません。再度質問宜しいでしょうか?  くりーむぱん - 2008/10/15(Wed) 02:18 No.241

先日は、解り易い説明ありがとうございました。

フォーム上をドラッグすると
直線が引けるという課題をやっているのですが、
下から4行目

LineInput(startX,startY) - (e.X,e.Y) Color.Blue

がうまく出来ません。
エラーメッセージは、引数が多すぎと
ステートメントの終わりの指定が無いです。
いろいろ調べましたが、
あと少しなのに、なかなか出来なくて・・・。
済みません。

エラーの出ているコード
Public Class Form1
Dim startX As Integer
Dim startY As Integer
Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
If e.Button = Windows.Forms.MouseButtons.Left Then
startX = e.X
startY = e.Y
End If
End Sub
Private Sub Form1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp
If e.Button = Windows.Forms.MouseButtons.Left Then
LineInput(startX, startY) - (e.X,e.Y) Color.Blue
End If
End Sub
End Class

済みませんが、よろしくお願いします。

Re: 済みません。再度質問...  Hiroshi - 2008/10/15(Wed) 23:57 No.242

ようこそ、くりーむぱん さん
実は、と言いますか、VBを勉強しながらテキストを作っています。VB6の時のようにはグラフィックスは使えないようで、詳しくはわかりません。
しかし、とりあえず、やってみました。コードをコピーして入力すると、
LineInput(startX, startY) - (e.X,e.Y) Color.Blue
でエラーがでます。そもそもLineInputはファイルからデータを入力する関数で、グラフィクス描画には関係ありません。
以前のBASICではLINE命令で直線が描画できました。そこでInputを消して次のようにしてみました。
Line(startX, startY) - (e.X,e.Y) Color.Blue
まだ、エラーはでますが、メッセージの中に「グラフィックス機能は'System.Drawing.Graphics.DrawLine'として使用できます。」とあります。
そこで、LineをGraphics.DrawLineに変更して次のようにしてみました。
graphics.drawline(startX, startY) - (e.X,e.Y) Color.Blue
まだ、エラーがでます。ここで、drawlineにカーソルをあわせて[F1]キーを押してヘルプをみました。すると、ヘルプに直線を描画するサンプルが出てきました。
Dim myPen As New System.Drawing.Pen(System.Drawing.Color.Red)
Dim formGraphics as System.Drawing.Graphics
formGraphics = Me.CreateGraphics()
formGraphics.DrawLine(myPen, 0, 0, 200, 200)
myPen.Dispose()
formGraphics.Dispose()
これをMouseUpのメソッドに組み込んでみました。
  Private Sub Form1_MouseUp(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp
    Dim myPen As New System.Drawing.Pen(System.Drawing.Color.Red)
    Dim formGraphics As System.Drawing.Graphics
    If e.Button = Windows.Forms.MouseButtons.Left Then
      formGraphics = Me.CreateGraphics()
      formGraphics.DrawLine(myPen, startX, startY, e.X, e.Y)
      myPen.Dispose()
      formGraphics.Dispose()
    End If
  End Sub
これで、とりあえずフォームに直線が描画できました。
これを足がかりにヘルプやネットなどでいろいろ調べてみてください。
それでは、またいつでもどうぞ。

Re: 済みません。再度質問...  くりーむぱん - 2008/10/16(Thu) 23:16 No.243

どうもありがとうございました。動きました。完璧です。

自分も最初myPenをネットで見つけましたが、
宣言のエラーから先に進めず、
また記述が正しいかどうかも自信が無くて
ネットで探し回って書き直しを繰り返して
ほんのさっきまでもう何がなんだかわからない状態でした。
本当にどうもありがとうございました。

課題は、これが最後です。
人に頼まれていたので放り出すわけにいかず、
ひとつのバージョンの違いで
こんなに大変になるとは思いもよりませんでした。
ありがとうございました。

VB6とVB2005の違いについて  くりーむぱん - 2008/10/07(Tue) 11:12 No.238

こんにちは、先日から勉強させていただいてお世話になっております。

今、VB6用に書かれた課題を
無料のVB2005で試しているのですが、
ほんの最初のところで躓いています。
内容は、これです。VB6用に書かれた課題↓

Private Sub Form_Click()

End Sub

Private Sub Form_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
If Button = 1 Then
Label1.Left = X
Label1.Top = Y
End If
End Sub

エクセル2003のマクロでは、動作しました。
VB2005では、MousDownの右側の記述が全く違ったものが表示されて
書き直してもだめでした。
VB2005では、どのように書くのでしょうか?
済みませんが、よろしくお願いします。

Re: VB6とVB2005の違いに...  Hiroshi - 2008/10/08(Wed) 03:10 No.239

ようこそ、くりーむぱん さん
VB2005でFormのMouseDownイベントを処理するメソッドを用意します。
コードウィンドウで「クラス名」を「(Form1 イベント)」、「メソッド名」を「MouseDown」にするとメソッドの定義部が表示されます。
Private Sub Form1_MouseDown(ByVal sender As Object, _
 ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
この引数(( )内のデータsenderとe)の中に必要なデータが格納されています。このうち、引数eが
System.Windows.Forms.MouseEventArgsデータ型でマウスのイベントに関するデータが格納されています。
「MouseEventArgs」の部分にカーソルを移動して、[F1]キーを押すとこのデータ型のメンバを
調べることができます。
それによると、操作したボタンに関しては「Button」プロパティ、座標に関しては「X」と「Y」プロパティで
参照できることがわかります。

 コードウィンドウで「If e.」とドットまで入力すると候補リストが表示されます。この中から
「Button」を選択して、「If e.Button=」と'='まで入力するとまた候補リストが表示されます。
ボタンの種類が表示されているようです。この中から「Windows.Forms.MouseButtons.Left」を
選択します。
 このように、コードウィンドウで表示される候補リストを活用するといろいろとヒントが見つかるかもしれません。
私もよく利用しています。

ということで、できあがったリストは次のようになります。(注意:空白は全角)

Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
  If e.Button = Windows.Forms.MouseButtons.Left Then
    Label1.Left = e.X
    Label1.Top = e.Y
  End If
End Sub

それでは、またいつでもどうぞ。



Re: VB6とVB2005の違いに...  くりーむぱん - 2008/10/14(Tue) 22:04 No.240

ありがとうございました。
動きました。

宣言がどうのとエラーが出ていたので
そちらのほうの問題と思っていました。
1行目にAs Integerは無いし
2005は、変数の宣言は要らないのかな?
疑問は残りますが動いてくれて助かりました。

とても解り易い解説でした。
どうもありがとうございました。


HSPのページに書かれているstr_comp関数について  ふにゃふにゃ - 2008/06/18(Wed) 02:50 No.236

こんにちは。

検索サイトから「HSP3 プログラミングの基礎W」の「(5) 文字列の比較」を見つけ、
http://masudahp.web.fc2.com/hsp3/kiso/hspk039.html 勉強させて戴きました。

このページには
>文字列のソートについては、拡張プラグインの「HSPDA.DLL」(HSP3に同梱)にsortstr命令として用意されている。
という記述が有りますが、HSPDA.DLLやsortstrには既知のバグが有り、使えないのでご報告します。
HSP3掲示板(新ではない方)の「過去ログ2」のおにたまさんのコメント979及び、この前後の書込みをご覧下さい。
簡単なスクリで実験すると、時々は動くのですが、実際に使い始めるとコンパイル中にsortstrの所でエラーが出ます。

それで、このサイトのstr_comp関数を研究させて頂いたのですが、一点お伺いしたい事が有ります。

if mc1 = 0 : cnvstow mc1, strmid(mj1, pm1, 2) : pm1 += 1

のところですが、この「pm1 += 1」は、「if mc1 = 0」の結果に関わらず
実行されてしまうのでは、ないでしょうか。

つまり
パターン1

if (mc1 = 0){ ;もし2バイト文字なら実行
cnvstow mc1, strmid(mj1, pm1, 2)
pm1 += 1
}

ではなくて
パターン2

if (mc1 = 0){ ;もし2バイト文字なら実行
cnvstow mc1, strmid(mj1, pm1, 2)
}
pm1 += 1 ;ifの結果に関わらず実行。

になっているのでは、ないでしょうか。
パターン2になってしまうと、スクリの中で判断している文字が1バイト文字でも
強制的にインデックスがずれてしまいます。

そう思って、自分で両方のパターンを実験したところ、
どちらの場合も、1バイト文字と2バイト文字が混在した文字列を正しく判断できてしまいました。
何故、こうなるのか、よくわかりません。
処理の流れについて、私は何か勘違いしているのでしょうか。

Re: HSPのページに書かれ・..  Hiroshi - 2008/06/22(Sun) 10:38 No.237

ようこそ、ふにゃふにゃ さん
「if mc1 = 0 : cnvstow mc1, strmid(mj1, pm1, 2) : pm1 += 1」 の件ですが、
命令はコロン(:)で区切られるので、条件が真のときはC言語のように続く1つの命令だけが処理されるように思われますが、HSPの仕様で条件が真のとき、
同じ行に続く命令すべてが処理されるようです。C言語と混同されたようですね。実際、私も読んだとき、書かれているとおりと思いました。
簡単な例で確認できます。

a = 1
if a=1 : mes "abc" : mes "xyz" : else : mes "ABC" : mes "XYZ"
stop

a=1のときは"abc"と"xyz"が出力されます。a=2のときは"ABC"と"XYZ"が出力されます。

「拡張プラグインのHSPDA.DLL」の件ですが、HSPがVer3に変わったとき、HSPDA.DLLがVer2のときのままで配列の仕様が異なっていたためのバグのようです。
今はHSPDA.DLLもVer3.1になっていますので大丈夫だと思います。新しい掲示板でも話題になっていないようですし。
それでは、またいつでもどうぞ。


C言語についてです。  trewq - 2008/05/27(Tue) 22:33 No.234

「逆ポーランド記法で書いた数式を入力すると、その計算結果を出力するプログラム」
のソースコードを作ったのですが、制限を加えないといけないのですが、
どうすればいいのでしょうか?



#include 
#include 

#define LIMIT 3 /* スタックに入る数の最大値 */

typedef int boolean ; /* 真偽値の型 */

int StackArray [LIMIT] ;
int top ; /* スタックの先頭を指す */

void push (int x) ; /* 関数のプロトタイプ宣言 */
int pop (void) ; /* 関数のプロトタイプ宣言 */

boolean push_dekiru (void) ; /* 関数のプロトタイプ宣言 */
boolean pop_dekiru (int n) ; /* 関数のプロトタイプ宣言 */

void error (void) { printf ("エラーです。\n") ;}

int main (int argc, char **argv)
... {
... int order, x, y ;
... top = 0 ;
... while (1)
....... {
....... printf ("\n現在のデータ数:%d\n", top) ;
....... printf ("現在のスタックの状態:") ; {int i ; for (i=0; i ....... 
....... if (push_dekiru ()) printf ("(1) push ") ;
....... if (pop_dekiru (1)) printf ("(2) pop ") ;
........................................ printf ("(3) finish ") ;
....... if (pop_dekiru (2)) printf ("(4) + (5) − (6) × (7) ÷ ") ;
........................................ printf (">") ;
....... 
....... scanf ("%d", &order) ;
....... 
....... switch (order)
........... {
........... case 1: if (push_dekiru ()) { printf ("input data: ") ; scanf ("%d", &x) ; push (x) ;} else error () ; break ;
........... case 2: if (pop_dekiru (1)) { printf ("%d\n", pop ()) ;} else error () ; break ;
........... case 3: return EXIT_SUCCESS ;
........... case 4: if (pop_dekiru (2)) {y=pop() ; x=pop() ; push (x+y) ;} else error () ; break ;
........... case 5: if (pop_dekiru (2)) {y=pop() ; x=pop() ; push (x-y) ;} else error () ; break ;
........... case 6: if (pop_dekiru (2)) {y=pop() ; x=pop() ; push (x*y) ;} else error () ; break ;
........... case 7: if (pop_dekiru (2)) {y=pop() ; x=pop() ; push (x/y) ;} else error () ; break ;
........... default: error () ;
........... }
....... }
... }

boolean push_dekiru (void) {return top < LIMIT ;}
void push (int x) { StackArray [top] = x ; top = top + 1 ; }

boolean pop_dekiru (int n) {return 0 <= top-n ;}
int pop (void) { top = top - 1 ; return StackArray [top] ; }




【制限】
・演算は+、−、×の3種類のみ
・数は1,2・・・9の9種類のみ
・入力には空白なし
・文字は半角英数
・入力文字列を配列に格納する
・各文字のAscil Codeを入れる

また、間違いなどがあれば訂正願います。
よろしくお願いいたします。

Re: C言語についてです。  hiroshi - 2008/05/28(Wed) 00:36 No.235

ようこそ、trewq さん
スタックの状況によって表示されるメニューが変わるようですね。
メニュー → (1)push (2)pop (3) finish (4)+ (5)- (6)* (7)/
例えば、5 7 + (5+7)は、
メニュー>1 → 5 → メニュー>1 → 7 → メニュー>4 → メニュー>2 → メニュー>3
と順に入力することになるのですね。
実行はしていないですが、基本的にこれでいいのではないかと思います。
次に、制限についてです。
・演算は+、−、×の3種類のみ
→メニューの(7)とcase 7を削除すればいいと思います。
・数は1,2・・・9の9種類のみ
→データはcase1のscanfで入力しているのですが、0のみ排除するには文字列として入力して
 1文字ずつチェックするしかないと思います。
・入力には空白なし
・文字は半角英数
→これは制限ですか?前提ですか?制限であれば、0の排除と同じ方法しかないと思います。
・入力文字列を配列に格納する
→スタックがあるのに配列に入れる意図が今ひとつわかりません。
・各文字のAscil Codeを入れる
→やはり、意味がよくわかりません。
それでは、またいつでもどうぞ。


MIDIのループ再生など  サトシ - 2008/04/29(Tue) 18:07 No.231

すみません(^^;
また来てしまいました。
HSPの事なのですが、BGMにMIDI(mid)を使おうとした場合、仕様?のせいで
2秒間ぐらい止まってしまいます。この無音部分をとり除いて再生&ループできるDLL
を使っているのですが、私のパソコン(vista&HSP3)に相性が悪いみたいで
このDLLを使うと、アプリが閉じられなくなってしまいます。(endで終わるとプロセス
が残ってしまいます。)
皆様はBGMを使う時はどのような方法で再生をしているのでしょうか?
HSPの標準機能だけではできないのでしょうか?
どうかご教授ください。
またもしその事が書いてあるサイトがあれば教えてください。m(_ _ )m

Re: MIDIのループ再生など  hiroshi - 2008/04/29(Tue) 23:45 No.232

ようこそ、サトシ さん
まず、使われているDLLがどのようなものかわかりませんので答えられません。
また、DLLの問題のように思えますので、そのDLLの作者に質問されるのが一番かと思います。
サウンドの再生について調べていましたら付属の「プログラミング・マニュアル」に
次のような説明がありました。(HSP3です。)

・マルチメディア再生
<中略>
ただし、MIDIのループ再生には問題があり完全なループ演奏にはなりません。 WindowsのMIDIシーケンサーが演奏開始まで時間がかかるのと、MIDIデータには最初に音源を初期化するコードや音色の指定などで時間がかかる場合が多いため演奏終了から、ループまでがうまくつながらないことが多いからです。 

ですから、この機能はあくまで簡易のループということをご了承ください。そもそもループポインタが指定できないので、前奏まで戻るのも変なんですが、ゲーム中にBGMが終わってしまうのが寂しいのを避けるためと割り切って使うことはできるかもしれません。 

MIDIのデバイスドライバによっては、MIDI演奏をストップした直後に、再びMIDI 演奏を開始するとWindowsがフリーズしたり演奏されないものがあるようです。 そのような場合には、MIDI演奏終了後に1〜2秒ほどのウエイト(wait 20など)を入れてから、次の演奏を開始するようにしてみてください。 

以上、MIDIの初期化に時間がかかるのでしかたないことのように思います。
それでは、またいつでもどうぞ。


Re: MIDIのループ再生など  サトシ - 2008/05/01(Thu) 08:32 No.233

返信ありがとうございました。今後ともこのサイトで勉強させていただきます。

ハイスコアについて  サトシ - 2008/04/26(Sat) 19:48 No.227

いつもこのサイトで勉強させていただいてます。
そして自作のゲームに、このサイトに書いてある
(HSPでの)ハイスコアの記録の仕方を参考に
させていただきました。
質問なのですが,このままだとハイスコアのテキストを
書き換えられたらそのままデータを改造されてしまいます。
それでpackfileでテキストをパックしても、
結果は中にあるハイスコアの記録には上書きされず
新しく外にテキストが保存されてしまいました。
(ハイスコアの結果が更新されませんでした)。
ハイスコアのテキストを改造されないようにするには
どうすればよいのでしょうか?

Re: ハイスコアについて  hiroshi - 2008/04/27(Sun) 04:19 No.228

ようこそ、サトシ さん
packfileを使ったり、いろいろと試されているようですね。いろいろとやってみる
ということは大事だと思います。
さて、「どのようにすればファイルの内容が書き換えられないか」という問題ですが、
他の人にわからない場所(フォルダ)に、また、内容が推測できないようなファイル名で
ファイルを作成する以外にはないと思います。この方法でも、プログラムが内容を
書き換えるとファイルの日付が変わるので、日付で検索して内容をすべて見ていけば
特定されてしまいます。
(1)内容を暗号化する。
  → 解読されない限り、書き換えると変な(無意味な)データになる。
ファイルの書き換えは可能ですが、内容がわからないので、でたらめな書き換えに
なってしまうでしょう。あまり強力でない暗号化でも一見して暗号化されていること
がわかると、解読してまで書き換えようとは思わなくなるかもしれません。
言語が違いますが、簡単な暗号化と復号化のプログラムです。
http://masudahp.web.fc2.com/js0/js108.html
(2)チェックサムを使う。
  → 書き換えられたかどうか判定できるので書き換えられたらデータを無効とする。
データのチェックサムのようなものを計算して、データとともに記録する。データを
書き換えるとチェックサムと一致しないので書き換えられたことが判明する。
チェックサム以外に、誤り訂正の手法を使うのも一つの手かもしれません。この場合も、
誤り(書き換え)だけが判明できればいいです。

それでは、またいつでもどうぞ。

Re: ハイスコアについて  hiroshi - 2008/04/27(Sun) 04:24 No.229

ちょっと、訂正
「チェックサム以外に、誤り訂正の……」
チェックサムも誤り訂正の方法の一つです。チェックサム以外の誤り訂正も
使えるということです。
失礼しました。

Re: ハイスコアについて  サトシ - 2008/04/27(Sun) 06:41 No.230

返信ありがとうございます!
やはり暗号化しかありませんか・・・(^^;
某サイトの掲示板でもハイスコアは暗号化などをしない限りはだめ
だという回答でした。
暗号化は全く分からないので勉強して使えるようになりたいとおもいます。orz
考え方としてはメモリノートパッド保存前にスコアや名前などを暗号化し、保存
ハイスコア読み込み時の時にそれを復合するという形でよいのでしょうか?
最初は隠しファイルにするのも手だと思ったのですが,隠しファイルを表示
する設定されたらあまり意味ないですものね(^^;;
いろいろとお世話になりました。
今後ともサイトでいろいろと勉強させていただきます。


C言語です。  りん - 2008/01/27(Sun) 00:48 No.225

おひさしぶりです。
またC言語に関する質問をしたく、書き込ませていただいてます。


C言語のコアイメージなどの問題についてです。
コアイメージの書き方として、

アドレスの型 アドレス|変数名 値|変数の型

を基本として教えていただきたいのと、
1問解いたやつが合っているかどうかの確認をお願いします。


問題1
int x *p;
p = &x;
*p = 10;

この問題は自分で解いてみました。

int* &x|x 10|int
int** &p|p &x|int*

合っていますでしょうか。。?


問題2
int arr[0] = 0, arr[1] = 1, arr[2] = 2, arr[3] = 3, *p;
p = arr;
for(i = 0; i <= 3; i++){
*(p + i) *= 2;
}

このコアイメージ。



問題3
char str{10} = {'t', 'e', 's', 't', '\0', '1', '0', '0','\0'}, *p;
p = (str + 1);
printf("%s", (p+1));

これのコアイメージ。



問題4
struct _SELL {
int x;
char y;
}
main() {
struct _SELL *p;
}

(1)100と'5'をセットする。
(2)セットしたコアイメージを書く。



問題5
int main (void) {
int x = 5, y = 10;
EX1(x, y);
EX2(&x, &y);
}

int EX1(int x, int y){
return(x + y);
}

yoid EX2(int* p, int* q){
int r;
r = *p;
*p = *q;
*q = *p;
}

これのコアイメージ。


問題6
int *p; sizeは4
(1)動的確保する方法を答える。
(2)開放する方法を答える。



問題7
char str[],p;
&str = *p;

このプログラムの間違いの指摘。


いっぱいあってごめんなさい。。

よろしくお願いします!!



Re: C言語です。  hiroshi - 2008/01/27(Sun) 02:22 No.226

ようこそ、りん さん
コアイメージがよくわかりません。
問題1から
アドレスの型 アドレス|【変数名(x)】 値|変数の型
アドレスの型 アドレス|【変数名(p)】 値|変数の型
 として、宣言した変数名を基準として、残りの
アドレスの型、アドレス、値、変数の型を答えると良いのでしょうか。

それでしたら次のようになると思います。
問題2
int* &arr[0]|arr[0] 0|int
int* &arr[1]|arr[1] 1|int
int* &arr[2]|arr[2] 2|int
int* &arr[3]|arr[3] 3|int
int** &p|p arr|int*
問題3
char* &str[0]|atr[0] 't'|char
char* &str[0]|atr[0] 'e'|char
char* &str[0]|atr[0] 's'|char
char* &str[0]|atr[0] 't'|char
char* &str[0]|atr[0] '\0'|char
char* &str[0]|atr[0] '1'|char
char* &str[0]|atr[0] '0'|char
char* &str[0]|atr[0] '0'|char
char* &str[0]|atr[0] '\0'|char
int** &p|p str|int*
問題4
int* &(p->x)|p->x 100|int
char &(p->y)|p->y '5'|char
問題5
int* &x|x 5|int
int* &y|y 10|int
int* &x|x 5|int
int* &y|y 10|int
int* &r|r 5|int
int** &p|p &x|int*
int** &q|q &y|int*
問題6
確保 p=(int *)malloc(4);
解放 free(p);
問題7
配列名strは配列の先頭アドレスを表す【定数】であるから値を代入することはできない。
変数pの値は不定であるから、不定のアドレスを値を*pで参照しても無意味である。

コアイメージの意味がよくわかりませんので考え違いしているかもしれません。
「とりあえず」、です。
またいつでもどうぞ。


k-means法サンプルコードを探しています  ぽっぷ - 2008/01/18(Fri) 19:09 No.223

はじめまして。
C、C++、PHPを多少かじった程度の初心者です。
画像の輝度差を画像間の距離として、k-means法により類似画像を分類しようと考えています。
クラスタリングを行ったことが無く、初心者にでも分かるようなサンプルコードを探しているのですが、中々理解できそうなHPが見つかりません。
もしご存知でしたら、初心者でも分かるようなk-means法の説明もしくはサンプルコードが記載されているHPを教えていただけないでしょうか?
ちなみに、開発環境は、動作確認のためVisual C++を使用していますが、最終的には、FreeBSD上で動かしたいと考えております。
よろしくお願いいたします。

Re: k-means法サンプルコ・..  hiroshi - 2008/01/19(Sat) 11:39 No.224

ようこそ、ぽっぷ さん
さて、次のサイトはどうでしょうか。
解説 http://www.ynk.ic.kanagawa-it.ac.jp/~kasuga/kmeans.html
サンプル http://opencv.jp/sample/misc.html#clustering
サイトの紹介だけですが、またどうぞ。

過去ログ
メニューに戻る




inserted by FC2 system