變數的內部儲存 值和型別

2022-07-26 05:00:18 字數 1263 閱讀 9644

php是一種弱型別的指令碼語言,弱型別不表示php的變數沒有型別區分,php變數有8種原始型別:

四種標量型別:

兩種復合型別:

兩種特殊型別:

乙個變數能在執行期間從一種型別轉換為另一種型別,那麼php是如何實現這種變數的型別戲法的呢?

在引擎內部,變數都是用乙個結構體來表示,這個結構體可以在/zend/zend.h中找到:

這裡我們暫時只關心 value和type兩個成員,其中value是乙個聯合, 也就是變數的實際值,type是變數的動態型別,根據型別的不同,value使用不同的成員。

type的各種型別都被定義成了巨集,同樣在此檔案中定義了這些巨集:

value的型別zvalue_value同樣定義在此檔案中:

1.布林型別變數

type=is_bool,value中的lval欄位為值,lval取值為(0,1)

在/zend/zend_operators.h中定義了取乙個zval的布林值的巨集:

#define z_bval(zval)   ((zend_bool)(zval).value.lval)

2.整形變數

type=is_long, value中的lval欄位為值

#define z_lval(zval)   (zval).value.lval

3.浮點型變數

type=is_double, value中的dval欄位為值

#define z_dval(zval)   (zval).value.dval

4.字串變數

type=is_string,   value中的str結構有效,該結構中var為字串的指標,len為字串的長度

#define z_strval(zval)   (zval).value.str.val    //取字串指標

#define z_strlen(zval)   (zval).value.str.len    //取字串長度

另外的複雜型別這裡暫不詳細介紹,對於陣列型別,ht欄位生效,ht是乙個雜湊表的指標,陣列都是雜湊表的形式存在,對於物件型別變數,obj儲存這物件的資訊,對於資源型別變數,用lval間接儲存這資源得乙個識別符號。

這樣引擎就用乙個zval型別來實現了所有的php變數型別,知道以上原理之後,變數的型別轉換就容易實現了,在/zend/zend_operators.c中定義了各種型別轉換的巨集,比如轉換成布林型別的巨集zendi_convert_to_boolean,主要的思路就是先把type變成is_bool,然後根據原變數的不同型別的值按照一定規則轉換成lval的0或則1。

型別 儲存和變數

c 程式是一種型別宣告。型別是一種建立資料結構的模板,描述了該模板創造物件的特徵。型別由以下元素定義 型別模板建立的物件。資料成員 屬性 函式成員 執行 無需定義,c 自帶的型別 型別通過型別宣告建立,型別宣告包括資訊 宣告了型別就可以用了 使用堆和棧這兩個記憶體區域來儲存資料 棧是乙個記憶體陣列,...

值型別變數和引用型別變數的區別

主要區別在於 系統在記憶體空間中為兩者分配儲存空間的方式不同。記憶體空間分為棧空間和堆空間。值型別資料的儲存空間在棧空間中分配,引用型別資料則在堆空間分配。由系統管理棧空間的所有操作,包括進棧和出棧。當乙個資料出棧後,其所分配到的儲存空間由系統自動 堆空間由clr負責管理。c 中的值型別變數和c c...

值型別和引用型別的儲存

本文主要是討論棧和堆的含義,也就是討論 c 的兩種類據型別 值型別和引用型別 雖然我們在.net中的框架類庫中,大多是引用型別,但是我們程式設計師用得最多的還是值型別。引用型別如 string,object,class等總是在從託管堆上分配的,c 中new操作符返回物件的記憶體位址 也就是指向物件資...