php原始碼之路第四章第一節( 函式間的轉換)

2021-07-24 05:50:33 字數 1998 閱讀 6286

函式間的轉換

在函式呼叫的執行**中我們會看到這樣一些強制轉換:

ex(function_state).function = (zend_function *) op_array;

或者:eg(active_op_array) = (zend_op_array *) ex(function_state).function;

這些不同結構間的強制轉換是如何進行的呢?

首先我們來看zend_function的結構,在zend/zend_compile.h檔案中,其定義如下:

typedef

union _zend_function common;

zend_op_array op_array;

zend_internal_function internal_function;

} zend_function;

這是乙個聯合體,我們來溫習一下聯合體的一些特性。聯合體的所有成員變數共享記憶體中的一塊記憶體,在某個時刻只能有乙個成員使用這塊記憶體,並且當使用某乙個成員時,其僅能按照它的型別和記憶體大小修改對應的記憶體空間。我們來看看乙個例子:
#include 

#include

int main() utype;

utype a;

a.i = 10;

a.ch[0] = '1';

a.ch[1] = '1';

printf("a.i= %d a.ch=%s",a.i, a.ch);

getchar();

return (exit_success);

}

程式輸出:a.i= 12593 a.ch=11 當修改ch的值時,它會依據自己的規則覆蓋i欄位對應的記憶體空間。 '1'對應的ascii碼值是49,二進位制為00110001,當ch欄位的兩個元素都為'1'時,此時記憶體中儲存的二進位制為 00110001 00110001 轉成十進位制,其值為12593。

回過頭來看zend_function的結構,它也是乙個聯合體,第乙個欄位為type,在common中第乙個欄位也為type,並且其後面注釋為/* never used*/,此處的type欄位的作用就是為第乙個欄位的type留下記憶體空間。並且不讓其它字段干擾了第乙個字段。我們再看zend_op_array的結構:

struct _zend_op_array
這裡的字段集和common的一樣,於是在將zend_function轉化成zend_op_array時並不會產生影響,這種轉變是雙向的。

再看zend_internal_function的結構:

typedef

struct _zend_internal_function zend_internal_function;

同樣存在公共元素,和common結構體一樣,我們可以將zend_function結構強制轉化成zend_internal_function結構,並且這種轉變是雙向的。

總的來說zend_internal_function,zend_function,zend_op_array這三種結構在一定程式上存在公共的元素,於是這些元素以聯合體的形式共享記憶體,並且在執行過程中對於乙個函式,這三種結構對應的字段在值上都是一樣的,於是可以在一些結構間發生完美的強制型別轉換。可以轉換的列表如下:

zend_function可以與zend_op_array互換

zend_function可以與zend_internal_function互換

但是乙個zend_op_array結構轉換成zend_function是不能再次轉變成zend_internal_function結構的,反之亦然。

其實zend_function就是乙個混合的資料結構,這種結構在一定程式上節省了記憶體空間。

第四章 第一節

乙個組合語言程式從寫出到最終執行的簡要過程 編寫 編譯 連線 執行 編寫 使用文字編輯器 如記事本 nodepad ultraedit等 用組合語言編寫彙編源程式。編譯 使用組合語言編譯程式 masm.exe 對源程式檔案中的源程式進行編譯,產生目標檔案。連線 使用連線程式 link.exe 對目標...

第四章 第一節 效率本質

學習是投資回報率最高的行為 拒絕學習的原因總結有以下幾點 1 不知道學習後有什麼收穫 2 沒有收穫,就不知道收穫有多好 多大 3 既然不了解學習的好處,就沒有動力學習 得出結論 學習乙個新東西,首先需要了解學習後能給自己帶來什麼樣的改變,可激發自己的學習興趣,增強自己的學習動力 作者對學習帶來的收穫...

第四章 第一節 shel語句 3 21

一 算術運算 五種格式 兩邊不加空格,兩邊加空格 c expr a b c expr a b 反引號 兩邊不加空格,兩邊不加空格 let c a b c a b c a b 二 執行指令碼 1 chmod x 指令碼名 指令碼名 2 sh 指令碼名 1 2 執行指令碼前後,都不能執行指令碼變數 3 ...