web-dev-qa-db-ja.com

引用によって作成されたリストと、Schemeのconsによって作成されたリストの違いは何ですか?

(define ls1 '((1 . 2) 1 . 2))
(set-car! (car ls1) 6)
ls1
(define ls2 (cons '(1 . 2) '(1 . 2)))
(set-car! (car ls2) 6)
ls2

set-car!ingの後、ls1は((6 . 2) 1 . 2)およびls2 ((6 . 2) 6 . 2)になります。 ls1ls2のストレージモデルは異なるようですが、誰かがx is bound to a listと言った場合、どういう意味ですか? xはstarting addressまたはlocationを表しますか。aはCのa [10]の開始アドレスです。

7
Lucas Li

見積もり

見積もりは、あなたがnot修正すべきデータを返し、mayはそれらの間で構造を共有します。例えば。あなたが含むファイルがある場合

(define l1 '(1 2 3))
(define l2 '(4 2 3))

次に、コンパイラは、l1l2を、それらの共通テール(cdr l1)(cdr l2)を共有する方法で、または読み取り専用メモリに割り当てることができます。

そのようなリストの変更はndefined behaviorです。行うしない行う。

list

listおよびcons create freshオブジェクト(すでに存在するすべてのものとは異なります)は、メモリを割り当てて設定します。あなたはそれらを所有しています-あなたは好きなだけそれらを修正できます。

あなたの場合

両方set-car!の呼び出しは間違った-読み取り専用データを変更してトリガーするndefined behavior(つまり、幸運ですあなたのコンピュータはあなたの顔に爆発しませんでした:-)。

具体的には、最初のケースls1では、正しいことを実行した場合に得られるもの、つまり、

(define ls1
  (cons (cons 1 2)
        (cons 1 2)))

一方、2番目のケースでは、実装はoneコンスセル(1 . 2)のみを割り当て、ls2の作成に再利用しました。 (法的)コード:

(define ls2
  (let ((l (cons 1 2)))
    (cons l l)))

print-circle in scheme があった場合、データの再利用を確認できます。

[1]> (let ((l (cons 1 2)))
        (cons l l)) 
((1 . 2) 1 . 2)
[2]> (setq *print-circle* t)
T
[3]> (let ((l (cons 1 2)))
        (cons l l)) 
(#1=(1 . 2) . #1#)

バインド

x is a bound to a valueは、xという名前がオブジェクトを参照することを意味します。これは、すべての言語で同じです。

LISP/Schemeの違いは、オブジェクトが何であるかです。

これはリストの最初のコンスセルです-おそらく seen 何度もあり、(リンクされた)リストはコンスセルのチェーンです。ここで、carには値が含まれ、cdrには次のコンスセルが含まれますリストにあります。

12
sds