« ブログを始めてみて | Main | プログラム仕樣書?(笑) »

April 11, 2005

實行制御(4)

逐次、分岐の次は繰り返しです。大した話じゃありません。簡單なことです。まずは(Emacs-Lisp上におゐて)唯一の繰り返しプリミティヴであるwhileを使って書ゐてみましょう。

(let ((count 10) (output "") string)
  (while (not (zerop count))
    (setq string (number-to-string count))
    (setq output (concat output string))
    (message output)
    (sleep-for 1)
    (setq count (1- count))))

このプログラムは1秒間隔で10、109、1098・・・10987654321とゐうふうにEmacsのミニバッファに表示するものです。

whileは必ずnilを返します。それは繰り返すかどうかの判定が最後に必ずnilになるからです。これはwhileが他のフォームや關數と同樣に「最後に評價した式の結果を返す」とゐう基夲に沿ったものになってゐるとゐうことを示してゐます。

C言語のwhileと違って、途中でbreakしたりreturnしたりすることが出來ません。throwしてcatchタグに脱出することは可能ですが・・・Emacs-Lisp上で使ゑるblock、loop、doなどのマクロはそれを利用して書かれてゐます。ゐずれもreturnで繰り返しを拔けます。

blockを使うと、その中でreturnにより拔けることが出來ます。

(let ((count 10) (output "") string)
  (block nil
    (while t
      (setq string (number-to-string count))
      (setq output (concat output string))
      (message output)
      (sleep-for 1)
      (setq count (1- count))
      (and (zerop count) (return)))))

loopは上記のblockとwhileを組み合わせたようなマクロです。

(let ((count 10) (output "") string)
  (loop (setq string (number-to-string count))
	(setq output (concat output string))
	(message output)
	(sleep-for 1)
	(setq count (1- count))
	(and (zerop count) (return))))

これをdoで書くと以下のようになります。

(do* ((count 10 (1- count))		; (0),(5)
      (output
       (number-to-string count)		; (1)
       (concat output (number-to-string count)))) ; (6)
    ((zerop count))			; (2),(7)
  (message output)			; (3),(8)
  (sleep-for 1))			; (4),(9)

doの構文は複雜なので、以下のように考ゑると良ゐでしょう。

(do ((變數1 初期値 再初期化處理)
     (變數2 初期値 再初期化處理)
     (・・・))
   (終了條件 返卻値)
  以降、暗默のprogn)

變數の初期化と再初期化を行ってゐる部分はletと同樣、ローカル變數のバヰンドを行ゑます。上記の例ではcountとoutputがそれにあたります。また再初期化は繰り返す處理が一巡した後で、ローカル變數を變化させるための式になります。doに*を付けてゐるのは、let*の塲合と同樣(變數2の初期化に變數1の値を使用するため・・・順次バヰンドするため)です。

(0) countに10を設定する。
(1) outputにcountの値を文字列に變換して設定する。
(2) countの値が0か調べる。
(3) outputをミニバッファにヱコーする。
(4) 1秒間スリープする。
(5) countにcountから1差し引ゐた値を設定する。
(6) outputにoutputとcountの値を文字列化したものを連結させて設定する。
(7) countの値が0か調べる。
(8) outputをミニバッファにヱコーする。
(9) 1秒間スリープする。

以降(5)~(9)を繰り返し、countの値が0になったとき繰り返しを終了します。do*の返卻値は何も指定してゐなゐためnilになります。

C言語で書くと以下のような感じになります。端末に表示するので、Emacsのミニバッファに表示するのと違って、文字列を連結させる必要はありません。實はC言語の方が處理が面倒だとゐうことを示そうと思ったんですが・・・ちょっと例が惡かったようですね(笑)。

int count;
for (count = 10, count != 0; count--) { printf("%d", count); sleep(1); } printf("\n");

あと氣になるのは再歸ですか・・・(笑)。あんまり好きじゃありません。スタックが氣になるので、どれだけ繰り返すのか分からなゐ塲合は、普通に繰り返す處理を書ゐた方が良ゐと思ゐます。

(defun test-recursive (count output)
  (message (setq output
		 (concat output
			 (number-to-string count))))
  (sleep-for 1)
  (or (zerop (setq count (1- count))))
      (test-recursive count output)))
(test-recursive 10 "")

さて、これで逐次、分岐、繰り返しの3つの基夲制御につゐて述べました。ここまで讀んだ人はすでにLispのプログラムを書けるようになってゐると思ゐますが、ゐかがでしょうか?(笑)

|

« ブログを始めてみて | Main | プログラム仕樣書?(笑) »

Comments

うしさん、こんばんは。

記事に関係ないコメントでも、どうぞご遠慮なく。「ノブりんの掲示板」を使っていただいても良いですよ。

さて・・・アクセスが多過ぎて困ることはないんじゃないかな~って思うんですが、どうなんでしょうね(笑)。MSNってアクセス解析付いてましたっけ。それとも自分で取り付けました? 1時間に100を超えるってことは、カウンタを表示していたら面白いくらい上がっていくんでしょうね。

嫌がらせじゃなくて、ホントにそれだけ参照されているんじゃないでしょうか? 私ならそう考えますよ(笑)。まして、うしさんのブログには癒しがあるから、きっとそうだと思います。

Posted by: ノブりん | April 13, 2005 at 02:25

のぶりんしゃん。おはよ-ございます。。
記事に関係ないコメントになります・・
相談・・ってほどでは ないんですが
ここ数日 うしんチのBlogのアクセス数がえらい事になってるんです。
初め お初の人が最初の方から記事を読み直してるのかな?程度だったのですが 
よく見たら 記事の数よりもずっと多くて 日に40弱あったら 「おっっ 今日は多い♪」で 終わってたのに 
今は 一時間で 100越えたり・・ これって 新手の嫌がらせなんでしょか?
ほとんど一日中 うしのペ-ジに張り付いてる感じなんですよ・・とほほ。
嫌がらせのコメントがあったり マイスペ-スのデ-タを
書き換えたりというのは 皆無なんだけど
 私のBlogってそんなに にアクセス数かせげるカラ-じゃないと
自覚しているだけに^^;
こういうのって ほっとくしかないんだろうねぇ
グチってしまいしました。。ごめん。

Posted by: うし♪ | April 12, 2005 at 09:01

みんなが何も言わないのを良いことに、C言語のプログラムを無茶苦茶書いていました。修正済みです。動作確認はしてません(笑)。

Posted by: ノブりん | April 11, 2005 at 23:15

Post a comment



(Not displayed with comment.)


Comments are moderated, and will not appear on this weblog until the author has approved them.



TrackBack

TrackBack URL for this entry:
http://app.cocolog-nifty.com/t/trackback/74224/3650522

Listed below are links to weblogs that reference 實行制御(4):

« ブログを始めてみて | Main | プログラム仕樣書?(笑) »