erlang資料型別的c原始碼解析 2 list

2021-10-10 10:41:07 字數 1684 閱讀 3380

在erlang資料型別的c原始碼解析(1)-eterm講到,當eterm的低2位為01b時,就是list型別,剩餘的位數表示乙個指向列表的指標。

另外就是,先講結論,有助於理解,erlang中的list在c的層面上是乙個鍊錶

// cons用於構建乙個鍊錶節點

#define cons(hp, car, cdr) \

(car(hp)=(car), cdr(hp)=(cdr), make_list(hp))

// cad:取出鍊錶結點的資料部分

#define car(x) ((x)[0])

// cdr:取出鍊錶結點的next指標

#define cdr(x) ((x)[1])

// make_list最後會呼叫到_unchecked_make_list(x), 向eterm打上list的標籤,實質上是置eterm的低2位為10b

// compress_pointer為壓縮,與下面的expand_pointer對應

#define _unchecked_make_list(x) ((uint) compress_pointer(x) + tag_primary_list)

// list_val最後會呼叫到_unchecked_list_val(x), 將低2位的標籤去掉,再取對應位址的值

#define _unchecked_list_val(x) ((eterm*) expand_pointer((x) - tag_primary_list))

(這些蛋疼的命名**於lisp語言,有興趣可以查一下)

bif_rettype length_1

(bif_alist_1)

list = bif_arg_1;

// i為返回值,代表鍊錶長度

i =0;

// 迴圈取next,next不為空的話i自增,直到nil

while

(is_list

(list))if

(is_not_nil

(list)

)bif_ret

(make_small

(i))

;}

從這個函式和上述cons的定義,都可以得出list在c層面上是乙個鍊錶。

bif_rettype tuple_to_list_1

(bif_alist_1)

// 這裡相當於取得tuple的指標

tupleptr =

tuple_val

(bif_arg_1)

;// n為tuple的長度

n =arityval

(*tupleptr)

;// 將tuple看成乙個陣列,tupleptr[n]就是c語言層面的陣列

// 在程序堆上分配空間,由於乙個鍊錶節點要儲存資料和next指標,所以申請的空間大小為tuple長度的2倍

hp =

halloc

(bif_p,

2* n)

; tupleptr++

;// 從陣列的最後乙個元素開始迴圈

while

(n--

)bif_ret

(list)

;}

github上otp17**的erl_term.h和erl_bif_lists.c

erlang的強資料型別

在mailist中,一位朋友表示疑問,為什麼下面的語句提示出錯?erlang的執行時資料繫結有什麼特殊規則?file open test.file write,raw,提示badarg,引數錯誤。其實不是執行時繫結有什麼問題,而是math pow 2返回的資料型別為float,而file open ...

erlang的資料型別 (2)

繼續前面說列表。列表裡面的元素,第乙個成為head,head之後的都叫tail。用erlang的內建方法看一下 hd 1,2,3,4 1 tl 1,2,3,4 2,3,4 為什麼要這樣呢?因為列表的指標是在頭部的,對頭部進行操作是最快捷和高效的。使用豎線 能快速區分頭部和尾部 h t 1,2,3,4...

21 erlang資料型別

erlang資料型別可以分為以下7大類 1 數值number 包括整形,浮點型,還有 char 進製表示法base value.2 元組term 由 包含的各種資料結構,統稱元組 3 列表 和字串 term1,termn 當然字串也屬於列表的以一種,a a 97 ab a,b 97,98 注意字串的...