16. 可移植性

"C語言結(jié)合了匯編的強大功能和可移植性" -- 無名氏托酸,暗指比爾.薩克。

可移植代碼的好處是有目共睹的醉箕。這一節(jié)將闡述一些編寫可移植代碼的指導(dǎo)原則羽德。這里"可移植的"是指一個源碼文件能夠在不同機器上被編譯和執(zhí)行,其 前提僅僅是在不同平臺上可能包含不同的頭文件神郊,使用不同的編譯器開關(guān)選項罷了肴裙。頭文件包含的#define和typedef可能因機器而異。一般 來說涌乳,一個新"機器"是指一種不同的硬件蜻懦,一種不同的操作系統(tǒng),一個不同的編譯器夕晓,或者是這些的任意組合宛乃。參考1包含了很多關(guān)于風(fēng)格和可移植 性方面的有用信息。下面是一個隱患列表蒸辆,當(dāng)你設(shè)計可移植代碼時應(yīng)該考慮避免這些隱患:

  • 編寫可移植的代碼征炼。只有當(dāng)被證明是必要的情況下才考慮優(yōu)化的細節(jié)。優(yōu)化后的代碼往往是模糊不清躬贡、難以理解的谆奥。在一臺機器上經(jīng)過優(yōu)化后的代碼,在其他機器上 可能變得更加糟糕拂玻。將采用的性能優(yōu)化手段記錄下來并盡可能多地本地化酸些。文檔應(yīng)該解釋這些手段的工作原理以及引入它們的原因(例如:"循環(huán)執(zhí)行了無 數(shù)次")

  • 要意識到很多東西天生就是不可移植的。比如處理類似程序狀態(tài)字這樣的特定硬件寄存器的代碼檐蚜,以及被設(shè)計用于支持某特定硬件部件的代碼魄懂,諸如匯編器以及 I/O驅(qū)動。即使在這種情況下闯第,許多例程和數(shù)據(jù)仍然可以被設(shè)計成機器無關(guān)的逢渔。

  • 組織源文件時將機器無關(guān)與機器相關(guān)的代碼分別放在不同文件中。之后如果這個程序需要被移植到一個新機器上時乡括,我們就可以很容易判斷出來哪些需要被改變肃廓。為 一些文件的頭文件中機器依賴相關(guān)的代碼添加注釋智厌。

  • 任何"實現(xiàn)相關(guān)"的行為都應(yīng)該作為機器(編譯器)依賴對待。假設(shè)編譯器或硬件以一種十分古怪的方式實現(xiàn)它盲赊。

  • 注意機器字長铣鹏。對象的大小可能不直觀,指針大小也不總是與整型大小相同哀蘑,也不總是彼此大小相同诚卸,或者可相互自由轉(zhuǎn)換。下面的表中列舉了C語言基本類型在不 同機器和編譯器下的大小(以bit為單位)绘迁。

    type    pdp11    VAX/11    68000    Cray-2    Unisys    Harris    80386
    series        family        1100    H800   
    char    8    8    8    8    9    8    8
    short    16    16    8/16    64(32)    18    24    8/16
    int    16    32    16/32    64(32)    36    24    16/32
    long    32    32    32    64    36    48    32
    char*    16    32    32    64    72    24    16/32/48
    int*    16    32    32    64(24)    72    24    16/32/48
    int(*)()    16    32    32    64    576    24    16/32/48
    

有些機器針對某一類型可能有不止一個大小合溺。其類型大小取決于編譯器和不同的編譯期標(biāo)志。下面表展示了大多數(shù)系統(tǒng)的"安全"類型大小缀台。無符號與帶符 號數(shù)具有相同的大小(單位:bit)棠赛。

Type    Minimum    No Smaller
# Bits    Than
char    8   
short    16    char
int    16    short
long    32    int
float    24   
double    38    float
any *    14   
char *    15    any *
void *    15    any *
  • void類型可以保證有足夠位精度來表示一個指向任意數(shù)據(jù)對象的指針。void()()類型可以保證表示一個指向任意函數(shù)的指針膛腐。當(dāng)你需要通用指針時 可以使用這些類型(在一些舊的編譯器里睛约,分別用char和char()()表示)。確保在使用這些指針類型之前將其轉(zhuǎn)換回正確的類型哲身。

  • 即使說一個int和一個char類型大小相同辩涝,它們?nèi)钥赡芫哂胁煌母袷健@缈碧欤旅胬釉谝恍﹕izeof(int)等于 sizeof(char)的機器上可能失敗怔揩。其原因在與free函數(shù)期望一個char,但卻傳入了一個int脯丝。

    int *p = (int *) malloc (sizeof(int));
    free (p);
    
  • 注意商膊,一個對象的大小不能保證這個對象的精度。Cray-2可能使用64位來存儲一個整型巾钉,但一個長整型轉(zhuǎn)換為一個整型并且再轉(zhuǎn)換回長整型后可能會被截斷 為32位翘狱。

  • 整型常量0可以強制轉(zhuǎn)型為任何指針類型。轉(zhuǎn)換后的指針稱為對應(yīng)那個類型的空指針砰苍,并且與那個類型的其他指針不同潦匈。空指針比較總是與常量0相當(dāng)赚导〔缢酰空指針不應(yīng) 該與一個值為0的變量比較『鹁桑空指針不總是使用全0的位模式表示凰锡。兩個不同類型的空指針有些時候可能不同。某個類型的空指針被強制轉(zhuǎn)換為另外一個類 型的指針,其結(jié)果是該指針轉(zhuǎn)換為第二個類型的空指針掂为。

  • 對于ANSI編譯器裕膀,當(dāng)兩個類型相同的指針訪問同一塊存儲區(qū)時,則它們比較是相等的勇哗。當(dāng)一個非0整型常量被轉(zhuǎn)換為指針類型時昼扛,它們可能與其他指針相等。對 于非ANSI編譯器欲诺,訪問同一塊存儲區(qū)的兩個指針比較可能并不相同抄谐。例如,下面兩個指針比較可能相等或不相等扰法,并且他們可能或可能沒有訪問同一塊 存儲區(qū)域蛹含。

    ((int *) 2 )
    ((int *) 3 )
    

如果你需要'magic'指針而不是NULL,要么分配一些內(nèi)存塞颁,要么將指針視為機器相關(guān)的浦箱。

extern int x_int_dummy;        /* in x.c */
#define X_FAIL    (NULL)
#define X_BUSY    (&x_int_dummy)
#define X_FAIL    (NULL)
#define X_BUSY    MD_PTR1        /* MD_PTR1 from "machdep.h" */
  • 浮點數(shù)字既包含精度也包含范圍。這些都是數(shù)據(jù)對象大小無關(guān)的殴边。但是憎茂,一個32位浮點數(shù)在不同機器上溢出時的值有所不同珍语。同時锤岸,4.9乘以5.1在不同的機 器上可能產(chǎn)生兩個不同的數(shù)字。在圓整(rounding)和截斷方面的差異將給出特別不同的答案板乙。

  • 在一些機器上是偷,一個雙精度浮點數(shù)在精度或范圍方面可能比一個單精度浮點數(shù)還要低。

  • 在一些機器上募逞,double值的前半部分可能是一個具有相同值的float類型蛋铆。千萬不要依賴于此。

  • 提防帶符號字符放接。例如刺啦,在某些VAX系統(tǒng)上,用在表達式中的字符是符號擴展的纠脾,但在其他一些機器上并非如此玛瘸。對有符號和無符號有依賴的代碼是不可移植的。 例如苟蹈,如果假設(shè)c是正值糊渊,arrayc在c為有符號且為負值時將無法正常工作。如果你一定要假設(shè)signed或unsigned字符的話慧脱,請 用SIGNED或UNSIGNED為其加上注釋渺绒。無符號字符的行為可由unsigned char保證。

  • 避免對ASCII做假設(shè)。如果你必須假設(shè)宗兼,那么請將其記錄下來并本地化躏鱼。請記住字符很可能用不止8位表示。

  • 大多數(shù)機器采用2的補碼表示數(shù)殷绍,但我們在代碼中不應(yīng)該利用這一特點挠他。使用等價移位操作替代算術(shù)運算的優(yōu)化尤其值得懷疑。如果必須這么做篡帕,那么機器相關(guān)的代 碼應(yīng)該用#ifdef定義殖侵,或者操作應(yīng)該在#ifdef宏判定下執(zhí)行。你應(yīng)該衡量一下使用這種難以理解的代碼所節(jié)省的時間與做代碼移植時找bug 所花費的時間相比孰多孰少镰烧。

  • 一般情況下拢军,如果字長或值范圍非常重要,應(yīng)該使用typedef定義具有特定大小的類型怔鳖。大型程序應(yīng)該具有一個統(tǒng)一的頭文件用于提供通用的茉唉、大小 (size)敏感的類型的typedef定義,這樣更加便于修改以及在緊急修復(fù)時查找大小敏感的代碼结执。無符號類型比有符號整型更加編譯器無關(guān)度陆。如 果既可以用16bit也可以用32bit標(biāo)識一個簡單for循環(huán)的計數(shù)器,我們應(yīng)該使用int献幔。因為對于當(dāng)前機器來說懂傀,通過整型可以獲取更高效 (自然)的存儲單元。

  • 數(shù)據(jù)對齊也很重要蜡感。例如蹬蚁,在不同的機器上,一個四字節(jié)的整型數(shù)的可能以任意地址作為起始地址郑兴,也可能只允許以偶數(shù)地址作為起始地址犀斋,或者只能以4的整數(shù)倍 的地址作為起始地址。因此情连,一個特定的結(jié)構(gòu)體的各個元素在不同的機器上的偏移量有不同叽粹,即使給定的這些元素在所有機器上的大小相同。事實上却舀,一個 包含一個32位指針和一個8位字符的結(jié)構(gòu)提在三個不同的機器上可能有三個不同的大小虫几。作為一個推論,對象指針可能無法自由互換禁筏;通過一個指向起始 地址為奇數(shù)地址長度為4個字節(jié)的指針保存一個整型數(shù)有時可以正常工作持钉,但有時則會導(dǎo)致產(chǎn)生core,有些時候靜悄悄地失敗了(在這個過程中會破壞 其他數(shù)據(jù))篱昔。在那些不按字節(jié)尋址的機器上每强,字符指針更是"事故高發(fā)地區(qū)"始腾。對齊考慮以及加載器的特殊性使得很容易輕率地認為兩個連續(xù)聲明的變量在 內(nèi)存中也是連在一起的,或者某個類型的變量已經(jīng)被適當(dāng)對齊并可以用作其他類型變量使用了空执。

  • 在一些機器上浪箭,諸如VAX(小端),一個字的字節(jié)隨著地址的增加辨绊,其重要性提高奶栖;而另外一些機器上,諸如68000(大端)门坷,隨著地址的增加宣鄙,其重要性降 低。字或更大數(shù)據(jù)對象(諸如一個雙精度字)的字節(jié)順序可能并不相同默蚌。因此冻晤,任何依賴對象內(nèi)從左到右方向位模式的代碼都值得特別細致的審查。只有當(dāng) 結(jié)構(gòu)體中兩個不同的位字段不被連接以及不被當(dāng)作一個單元時绸吸,這些位字段才具備可移植性鼻弧。事實上,連接任意兩個變量都是不可移植的行為锦茁。

  • 結(jié)構(gòu)體中有一些未使用的空洞攘轩。猜想聯(lián)合體用于類型欺騙。尤其是码俩,一個值不應(yīng)該在存儲時使用一個類型度帮,而在讀取時使用另外一種類型。對聯(lián)合體來說握玛,一個顯式 的標(biāo)簽(tag)字段可能會很有用够傍。

  • 不同的編譯器在返回結(jié)構(gòu)體時使用不同的約定甫菠。這就會導(dǎo)致代碼在接受從不同編譯器編譯的庫代碼中返回的結(jié)構(gòu)體值時會出現(xiàn)錯誤挠铲。結(jié)構(gòu)體指針不是問題。

  • 不要假設(shè)參數(shù)傳遞機制寂诱。特別是指針大小以及參數(shù)求值順序拂苹,大小等。例如痰洒,下面的代碼就不具備可移植性瓢棒。

    c = foo (getchar(), getchar());
    
    char
    foo (c1, c2, c3)
    char c1, c2, c3;
    {
        char bar = *(&c1 + 1);
        return (bar);            /* often won't return c2 */
    }
    
  • 上面的例子有諸多問題。椙鹩鳎可能向上增長脯宿,也可能向下增長(事實上,甚至都不需要一個棧)泉粉。參數(shù)在傳入時可能被擴大连霉,例如一個char可能以int型被傳 入榴芳。參數(shù)可能以從左到右,從右到左跺撼,或以任意順序壓入棧窟感,或直接放在寄存器中(根本無需壓棧)。參數(shù)求值的順序也可能與壓棧的次序有所不同歉井。一個 編譯器可能使用多種(不兼容的)調(diào)用約定柿祈。

  • 在某些機器上,空字符指針((char *)0)常被當(dāng)作指向空字符串的指針對待哩至。不要依賴于此躏嚎。

  • 不要修改字符串常量。下面就是一個臭名昭著的例子

    s = "/dev/tty??";
    strcpy (&s[8], ttychars);
    
  • 地址空間可能有空洞菩貌。簡單計算一個數(shù)組中未分配空間的元素(在數(shù)組實際存儲區(qū)域之前或之后)的地址可能會導(dǎo)致程序崩潰紧索。如果這個地址被用于比較,有時程序 可以運行菜谣,但會破壞數(shù)據(jù)珠漂,報錯,或陷入死循環(huán)尾膊。在ANSI C中媳危,指向一個對象數(shù)組的指針指向數(shù)組結(jié)尾后的第一個元素是合法的,這在一些老編譯器上通常是安全的冈敛。不過這個"在外邊"不可以被解引用待笑。

  • 只有==和!=比較可用于某給定類型的所有指針。當(dāng)兩個指針指向同一個數(shù)組內(nèi)的元素(或數(shù)組后第一個元素)時抓谴,使用<<暮蹂、<=、& gt;或>=對兩個指針進行比較是可移植的癌压。同樣仰泻,僅僅對指向同一個數(shù)組內(nèi)的元素(或數(shù)組后第一個元素)的兩個指針使用算術(shù)操作符才是可移 植的。

  • 字長(word size)也影響移位和掩碼滩届。下面代碼在一些68000機器上只會將一個整型數(shù)的最右三個位清0集侯,而在其他機器上它還會將高地址的兩個字節(jié)清零。x &= 0177770 使用 x &= ~07可以在所有機器上正常工作帜消。位字段(bitfield)沒有這些問題棠枉。

  • 表達式內(nèi)的副作用可能導(dǎo)致代碼語義是編譯器相關(guān)的,因為在大多數(shù)情況下C語言的求值順序是沒有顯式定義的泡挺。下面是一個臭名昭著的例子:

    a[i] = b[i++];
    

    在上面的例子中辈讶,我們只知道b的下標(biāo)值沒有被增加。a的下標(biāo)i值可能是自增后的值也可能是自增前的值娄猫。

    struct bar_t { struct bar_t *next; } bar;
    bar->next = bar = tmp;
    

在第二個例子中贱除,bar->next的地址很可能在bar被賦值之前被計算使用咳促。

bar = bar->next = tmp;

第三個例子中,bar可能在bar->next之前被賦值勘伺。雖然這可能有悖于"賦值從右到左處理"的規(guī)則跪腹,但這確是一個合法的解析》勺恚考慮下 面的例子:

long i;
short a[N];
i = old
i = a[i] = new;

賦給i的值必須是一個按照從右到左的處理順序進行賦值處理后的值冲茸。但是i可能在ai被賦值前而被賦值為"(long) (short)new"。不同編譯器作法不同缅帘。

  • 質(zhì)疑代碼中出現(xiàn)的數(shù)值(“魔數(shù)”)轴术。

  • 避免使用預(yù)處理器技巧。一些諸如使用/ /粘和字符串以及依賴參數(shù)字符串展開的宏會破壞代碼可靠性钦无。

    #define FOO(string)    (printf("string = %s",(string)))
    ...
    FOO(filename);
    

只是在有些時候會擴展為

 (printf("filename = %s",(filename)))

小心逗栽。詭異的預(yù)處理器在一些機器上可能導(dǎo)致宏異常中斷。下面是一個宏的兩種不同實現(xiàn)版本:

 #define LOOKUP(chr)    (a['c'+(chr)])    /* Works as intended. */
 #define LOOKUP(c)    (a['c'+(c)])        /* Sometimes breaks. */

第二個版本的LOOKUP可能以兩種不同的方式擴展失暂,并且會導(dǎo)致代碼異常中斷彼宠。

  • 熟悉現(xiàn)有的庫函數(shù)和定義(但不用太熟悉。與其外部接口相反弟塞,庫基礎(chǔ)設(shè)施的內(nèi)部細節(jié)常會改變并且沒有警告凭峡,這些細節(jié)常常也是不可移植的)。你不應(yīng)該再自己重 新編寫字符串比較例程决记、終端控制例程或為系統(tǒng)結(jié)構(gòu)編寫你自己的定義摧冀。自己動手實現(xiàn)既浪費你的時間,又使得你的代碼可讀性變差系宫,因為另外一個讀者需 要知道你是否在新的實現(xiàn)中做了什么特殊的事情索昂,并嘗試證實它們的存在。同時這樣做會使得你無法充分利用一些輔助的微代碼或其他有助于提高系統(tǒng)例程 性能的方法扩借。更進一步椒惨,它將是一個bug的高產(chǎn)源頭。如果可能的話往枷,要知道公共庫之間的差異(如ANSI框产、POSIX等等)。

  • 如果lint可用错洁,請使用lint。這個工具對于查找代碼中機器相關(guān)的構(gòu)造戒突、其他不一致性以及順利通過編譯器檢查的程序bug時具有很高價值屯碴。如果你的編 譯器具備打開警告的開關(guān),請打開它膊存。

  • 質(zhì)疑在代碼塊內(nèi)部的與代碼塊外部switch或goto有關(guān)聯(lián)的標(biāo)簽(Label)导而。

  • 無論類型在哪里忱叭,參數(shù)都應(yīng)該被轉(zhuǎn)換為適當(dāng)?shù)念愋汀.?dāng)NULL用在沒有原型的函數(shù)調(diào)用時今艺,請對NULL進行轉(zhuǎn)換韵丑。不要讓函數(shù)調(diào)用成為類型欺騙發(fā)生的地方。C 語言的類型提升規(guī)則很是讓人費解虚缎,所以盡量小心撵彻。例如,如果一個函數(shù)接受一個32位長的長整型做為參數(shù)实牡,但實際傳入的卻是一個16位長的整型數(shù)陌僵, 函數(shù)棧可能會無法對齊创坞,這個值也可能會被錯誤提升碗短。

  • 在混用有符號和無符號值的算術(shù)計算時請使用顯式類型轉(zhuǎn)換

  • 應(yīng)該謹慎使用跨程序的goto、longjmp题涨。很多實現(xiàn)"忘記"恢復(fù)寄存器中的值了偎谁。盡可能將關(guān)鍵的值聲明為volatile,或?qū)⑺鼈冏⑨尀?VOLATILE纲堵。

  • 一些鏈接器將名字轉(zhuǎn)換為小寫搭盾,并且一些鏈接器只識別前六個字母作為唯一標(biāo)識。在這些系統(tǒng)上程序可能會悄悄地中斷運行婉支。

  • 當(dāng)心編譯器擴展鸯隅。如果使用了編譯器擴展,請將他們視為機器依賴并用文檔記錄下來向挖。

  • 通常程序無法在數(shù)據(jù)段執(zhí)行代碼或者無法將數(shù)據(jù)寫入代碼段蝌以。即使程序可以這么做,也無法保證這么做是可靠的何之。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末跟畅,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子溶推,更是在濱河造成了極大的恐慌徊件,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蒜危,死亡現(xiàn)場離奇詭異虱痕,居然都是意外死亡,警方通過查閱死者的電腦和手機辐赞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進店門部翘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人响委,你說我怎么就攤上這事新思〗蚜海” “怎么了?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵夹囚,是天一觀的道長纵刘。 經(jīng)常有香客問我,道長荸哟,這世上最難降的妖魔是什么假哎? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮敲茄,結(jié)果婚禮上位谋,老公的妹妹穿的比我還像新娘。我一直安慰自己堰燎,他們只是感情好掏父,可當(dāng)我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著秆剪,像睡著了一般赊淑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上仅讽,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天陶缺,我揣著相機與錄音,去河邊找鬼洁灵。 笑死饱岸,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的徽千。 我是一名探鬼主播苫费,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼双抽!你這毒婦竟也來了百框?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤牍汹,失蹤者是張志新(化名)和其女友劉穎铐维,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年酒朵,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片棠众。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖有决,靈堂內(nèi)的尸體忽然破棺而出闸拿,到底是詐尸還是另有隱情,我是刑警寧澤书幕,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布新荤,位于F島的核電站,受9級特大地震影響台汇,放射性物質(zhì)發(fā)生泄漏苛骨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一苟呐、第九天 我趴在偏房一處隱蔽的房頂上張望痒芝。 院中可真熱鬧,春花似錦牵素、人聲如沸严衬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽请琳。三九已至,卻和暖如春赠幕,著一層夾襖步出監(jiān)牢的瞬間俄精,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工榕堰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留竖慧,地道東北人。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓逆屡,卻偏偏與公主長得像圾旨,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子康二,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,834評論 2 345

推薦閱讀更多精彩內(nèi)容

  • *面試心聲:其實這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,125評論 29 470
  • 原文地址:C語言函數(shù)調(diào)用棧(一)C語言函數(shù)調(diào)用棧(二) 0 引言 程序的執(zhí)行過程可看作連續(xù)的函數(shù)調(diào)用碳胳。當(dāng)一個函數(shù)執(zhí)...
    小豬啊嗚閱讀 4,590評論 1 19
  • 本節(jié)內(nèi)容 Python介紹 發(fā)展史 Python 2 or 3? 安裝 Hello World程序 變量 用戶輸入...
    小小不懂11閱讀 3,406評論 2 30
  • 散亂書篇塵未老,哪樣心思沫勿,可向文中找挨约。落羽驚飛行陣渺,失群正覽云天浩产雹。 綠柳秋風(fēng)還多少诫惭,自顧凝眸,鏡水花開早蔓挖。偶覓...
    糊涂印象閱讀 180評論 0 2
  • 這樣
    angel_xbt閱讀 169評論 1 0