投稿

ラベル(C)が付いた投稿を表示しています

N88-BASIC,Cでハノイの塔 (7回目)

イメージ
202 5 / 1 /22 (水 ) N88-BASIC ,C で ハノイの塔  ( 7 回目 )   途中経過の移動の分離と表示の分離 (hanoi) Cで書く   ■ 前提 ▼ 参照 https://ulprojectmail.blogspot.com/2024/12/hanoi-3.html ハノイの塔  ( 3 回目 )   ▼   前提 3本(A,B,C)の棒とn枚の円盤(小さい順に1~nとする)がある Aに1~nの円盤が上から順に積まれている   ▼   目標 1~nの円盤全てをCに移動させる   ▼   ルール 小さい円盤の上に大きい円盤は置けない 1度に動かせる円盤は1枚のみ   ▼   定義 A,B,Cの一番上の円盤をpA, pB, pCとし、円盤が無い時は最大値とする 円盤を AからCに移動する事をA->Cと書くことにする   ▼   円盤の移動回数 N(n) = 2 n  - 1   ▼   分離 hより小さい円盤の移動はhの移動からhの移動まで N(h-1) = 2 (h-1)  - 1回続く この塊を別の関数で一括処理することで表示判定を省略できる 更に N(a)を一括処理すると更に速くなる 実際の実装は han007.cを参照して下さい   ■   動作 変数名など内部では A,B,Cを(pole)1,2,3と表現しています   nを入力し 1:A->Cの様に円盤の番号1~n(小~大)と棒A,B,C間の移動を表示する 今回の手順は再帰を使用していません h以上の円盤の移動のみ表示   VL,NL,XL-BASICとdlg~.zip( han 00 7 . c )は このブログ (以下のリンク)から ダウンロードできます https://ulprojectmail.blogspot.com Readme.txtを読んで遊んで下さい  

N88-BASIC,Cでハノイの塔 (6回目)

イメージ
202 5 / 1 / 18 (土 ) N88-BASIC ,C で ハノイの塔  ( 6 回目 )   途中経過の移動と表示の分離 (hanoi) Cで書く   ■ 前提 ▼ 参照 https://ulprojectmail.blogspot.com/2024/12/hanoi-3.html ハノイの塔  ( 3 回目 ) より   ▼   前提 3本(A,B,C)の棒とn枚の円盤(小さい順に1~nとする)がある Aに1~nの円盤が上から順に積まれている   ▼   目標 1~nの円盤全てをCに移動させる   ▼   ルール 小さい円盤の上に大きい円盤は置けない 1度に動かせる円盤は1枚のみ   ▼   定義 A,B,Cの一番上の円盤をpA, pB, pCとし、円盤が無い時は最大値とする 円盤を AからCに移動する事をA->Cと書くことにする   ▼   円盤の移動回数 N(n) = 2 n  - 1   ▼   分離 hより小さい円盤の移動はhの移動からhの移動まで N(h-1) = 2 (h-1)  - 1回続く この塊を別の関数で一括処理することで表示判定を省略できる 実際の実装は han006.cを参照して下さい   ■   動作 変数名など内部では A,B,Cを(pole)1,2,3と表現しています   nを入力し 1:A->Cの様に円盤の番号1~n(小~大)と棒A,B,C間の移動を表示する 今回の手順は再帰を使用していません h以上の円盤の移動のみ表示   VL,NL,XL-BASICとdlg~.zip( han 00 6 . c )は このブログ (以下のリンク)から ダウンロードできます https://ulprojectmail.blogspot.com Readme.txtを読んで遊んで下さい  

N88-BASIC,Cでハノイの塔 (5回目)

イメージ
202 5 / 1 /8 (水 ) N88-BASIC ,C で ハノイの塔  ( 5 回目 )   再帰を使用しない手順 (hanoi) Cで書く   ■ 前提 ▼ 参照 https://ulprojectmail.blogspot.com/2024/12/hanoi-3.html ハノイの塔  ( 3 回目 ) より   ▼   前提 3本(A,B,C)の棒とn枚の円盤(小さい順に1~nとする)がある Aに1~nの円盤が上から順に積まれている   ▼   目標 1~nの円盤全てをCに移動させる   ▼   ルール 小さい円盤の上に大きい円盤は置けない 1度に動かせる円盤は1枚のみ   ▼   定義 A,B,Cの一番上の円盤をpA, pB, pCとし、円盤が無い時は最大値とする 円盤を AからCに移動する事をA->Cと書くことにする   ▼   nの場合 nが奇数の時   A = Aのtop, pB = Bのtop, pC = Cのtop   pAB = A->B, pBC = B->C, pCA = C->A   pBA = B->A, pCB = C->B, pAC = A->C nが偶数の時(A⇔B)   pA = Bのtop, pB = Bのtop, pC = Cのtop   pAB = B->A, pBC = A->C, pCA = C->B   pBA = A->B, pCB = C->A, pAC = B->C と定義する つまり以下偶数の時は (A⇔B)と読み替える   nが偶数の時のみ以下の2行を追加   pBA   pB < pC なら pBC 違うなら pCB   pAC pA ≠ pBの間以下を繰り返す   pA < pB なら pAB 違うなら pBA   pCB   pC < pA なら pCA 違うなら pAC   pBA   pB < pC なら pBC 違うなら pCB   pAC   ■   動作 変数名など内部では A,B,Cを(pole)1,2,3と...

N88-BASIC,Cでハノイの塔 (4回目)

イメージ
    202 5 / 1 / 1 ( 水 ) N88-BASIC ,C で ハノイの塔  ( 4 回目 )   再帰を使用した手順 (hanoi) Cで書く   ■ 前提 ▼ 参照 https://ulprojectmail.blogspot.com/2024/12/hanoi-1.html ハノイの塔   ( 1 回目 ) より   ▼   ルール 3本(A,B,C)の棒とn枚の円盤(小さい順に1~nとする)がある Aに1~nの円盤が上から順に積まれている 小さい円盤の上に大きい円盤は置けない 1度に動かせる円盤は1枚のみ   ▼   目標 1~nの円盤全てをCに移動させる   ▼   Cの一部 #include <stdio.h> static void hanoi1(int n, int h, char p1, char p2, char p3) {     if (n >  1) hanoi1(n - 1, h, p1, p3, p2);     if (n >= h) printf(" %2d:%c->%c", n, p1, p3);     if (n >  1) hanoi1(n - 1, h, p2, p1, p3); } void main(void) {     int n = 3;     int h = 1;       hanoi1(n, h, 'A', 'B', 'C'); }   ▼   nの時の手順 A,B,Cを(pole)p1,p2,p3と表現しています   if (n >  1) hanoi1(n - 1, h, p1, p3, p2); 1~n-1の円盤をA->B (p1->p2)   if (n >= h) printf(" %2d:%c->%c", n, p1, p3); nの円盤をA->C (p1->p3)   if (n...

N88-BASIC、アセンブラ、Cでポインター (6回目)

イメージ
2023/1/31(火) N88-BASIC、アセンブラ、Cでポインター (6回目)   C言語にポインターが存在する意味が   文字列中のアルファベットの小文字を 大文字に変換するプログラムを作ることで   何となく分かるようにするシリーズです     今回はアセンブラ(8086系)の プログラムの紹介です   前回のポインターを使用したCからの変換です   プログラムと解説はコメント(/* … */)を見て下さい   blg~.zip中のptr006asm.cです   #include   <stdio.h>       /* printf等使用の為 */ void  main( void )        /* mainから実行     */ {   c har * p;         /* p = a (aは&a[0]) */    char   a[256];       /* 255文字+終端'\0' */     printf( "? " );   gets_s(a, 256);      /* 文字列入力      */   printf( "%s\n" , a);    /* 文字列表示       */     p = a;        /* mov ebx,aがerrorの為 */    __asm           /* 次の{}内がアセンブラ */   {     mov ebx,p;   ; ebxレジスタ(32bit) = p   L1:     mov al,[ebx]  ; alレジスタ(8bit) = *ebx     test al,al   ; al & al (0のチェック)     je L3      ; if  (al == 0 ) goto  L3     cmp al, 'a'     ; if  (al < 'a...

N88-BASIC、アセンブラ、Cでポインター (5回目)

イメージ
2023/1/25(水) N88-BASIC、アセンブラ、Cでポインター (5回目)   C言語にポインターが存在する意味が   文字列中のアルファベットの小文字を 大文字に変換するプログラムを作ることで   何となく分かるようにするシリーズです     今回はC(言語)で ポインターを使ったプログラムの紹介です プログラムと解説はコメント(/* … */)を見て下さい BASICのアドレス(POKE,PEEK,VARPTRなど) を使ったプログラムや アセンブラを理解していれば より簡単に理解できると思います blg~.zip中のptr005.cです   #include   <stdio.h>       /* printf等使用の為 */ void  main( void )        /* mainから実行     */ {   c har * p;         /* p = a (aは&a[0]) */    char   a[256];       /* 255文字+終端'\0' */     printf( "? " );   gets_s(a, 256);      /* 文字列入力      */   printf( "%s\n" , a);    /* 文字列表示       */    for  (p = a; *p; p++)   /* *p != '\0'繰返し */   {      if  ( 'a'  <= *p && *p <= 'z' )     {       *p -= 'a'  - 'A' ;     }   }   printf( "%s\n" , a);    /* 文字列表示        */    gets_s(a, 256);      /* キー入力待ち ...

N88-BASIC、アセンブラ、Cでポインター (4回目)

イメージ
2023/1/21(土) N88-BASIC、アセンブラ、Cでポインター (4回目)   C言語にポインターが存在する意味が   文字列中のアルファベットの小文字を 大文字に変換するプログラムを作ることで   何となく分かるようにするシリーズです     今回はC(言語)で 普通に作ったプログラムの紹介です プログラムと解説はコメント(/* … */)を見て下さい   blg~.zip中のptr004.cです   #include   <stdio.h>       /* printf等使用の為 */ void  main( void )        /* mainから実行     */ {    char  a[256];       /* 255文字+終端'\0' */    int   i;          /* 変数の定義       */     printf( "? " );   gets_s(a, 256);      /* 文字列入力      */   printf( "%s\n" , a);    /* 文字列表示       */    for  (i = 0; a[i]; i++)  /* a[i]!='\0'繰返し */   {      if  ( 'a'  <= a[i] && a[i] <= 'z' )     {      a[i] -= 'a'  - 'A' ;     }   }   printf( "%s\n" , a);    /* 文字列表示        */   gets_s(a, 256);      /* キー入力待ち     */ }   gets_s(a, 2...

N88-BASIC、アセンブラ、Cでポインター (3回目)

イメージ
2023/1/17(火) N88-BASIC、アセンブラ、Cでポインター (3回目)   C言語にポインターが存在する意味が   文字列中のアルファベットの小文字を 大文字に変換するプログラムを作ることで   何となく分かるようにするシリーズです     今回は N88-BASIC,Z80(XL-BASIC)で アセンブラ (Z80)を使用したプログラムの紹介です USR関数とCALLの2種類とも書いています   アセンブり言語をアセンブラで数値に変換したものが マシン語 (機械語)です 使い方が間違っているかもしれませんが ここではアセンブり言語をアセンブラと書いています   NL-BASIC,VL-BASICはアセンブラに対応していないので XL-BASIC(N88-BASIC(PC-8801)+Z80)のみで動きます   blg~.zip中のptr003.basです   150 CLEAR ,&HAFFF    BASIC使用領域は&HAFFFまで(マシン語は&HB000~) 160 ADDR = &HB000 170 GOSUB *ASSEMBLY   マシン語を ADDR番地から読込む 180 DEF USR0 = ADDR '--- USR0 190 STR0 = ADDR + 1 '--- CALL   マシン語呼び出しアドレスの設定 (USR0,CALL)   260 B$ = USR0(A$) 330 CALL ALPH(A$) それぞれの方法でマシン語を呼出しています A$自身が書変わります 書換えた後の A$の値がB$に入ります (文字列以外のB = USR0(A)などはAは変化しません)   以下、アセンブラの解説です   B$ = USR0(A$)では、DE = VARPTR(A$) CALL STR0(A$)では、HL = VARPTR(A$) の様に、 A$の情報が異なるレジスタに入りますので DEの時はDE,HLを入替えて(EX DE,HL) どちらも HL = VARPTR(A$)の状態で書いています   B000: EX DE,HL    ...

N88-BASIC、アセンブラ、Cでポインター (2回目)

イメージ
2023/1/14(土) N88-BASIC、アセンブラ、Cでポインター (2回目)   C言語にポインターが存在する意味が   文字列中のアルファベットの小文字を 大文字に変換するプログラムを作ることで   何となく分かるようにするシリーズです     今回はN88-BASIC(VL,XL,NL-BASIC)で アドレスを使用したプログラムの紹介です アセンブラでプログラムする足ががりです   PC-88(XL-BASIC),PC-98(NL-BASIC),VL-BASIC でメモリー内容が異なりますので その3パターンに対応しています   blg~.zip中のptr002.basです   200 ON N88 + 1 GOSUB *XL, *NL, *VL 240 FOR I=1 TO N 250   B = PEEK(P) 260   IF ASC("a") <= B AND B <= ASC("z") THEN POKE P, B - C 270   P = P + 1 280 NEXT   プログラムと解説を交互に書きました   200 ON N88 + 1 GOSUB *XL, *NL, *VL   各機種ごとに違う読み方で文字数N,アドレスPを設定 240 FOR I=1 TO N 250   B = PEEK(P)    アドレスPの内容をBに入れる 260   IF ASC("a") <= B AND B <= ASC("z") THEN POKE P, B - C    Bが"a"~"z"なら、アドレスP内にB-C("A"~"Z")を入れる 270   P = P + 1    Pを1増やす 280 NEXT   文字数N分繰返す   PEEK(P)はアドレスPのメモリーを読む POKE P,DはアドレスPのメモリーにDを書く という命令です(Dは0~&HFF) このアドレスを入れる変数Pを C言語ではポインターと呼んでいます 以下 メモリーのアドレス(16進数) (BASICでは16進数は...