Freebsic是一門(mén)沒(méi)有任何特點(diǎn)的開(kāi)源語(yǔ)言,非常平庸。它是披著VB的語(yǔ)法羊皮,長(zhǎng)著一顆c語(yǔ)言的心,懷著c++的情懷,卻生在一個(gè)托管語(yǔ)言橫行的世界。所以本系列文章,謹(jǐn)此獻(xiàn)給極其少數(shù)幾個(gè)喜歡Freebasic的人。
freebasic的語(yǔ)法和vb是極其相似的,所以如果你有vb6或vba的基礎(chǔ)的話,那么你用Freebasic寫(xiě)代碼幾乎沒(méi)有任何障礙,非常熟悉,如果你有點(diǎn)c語(yǔ)言基礎(chǔ)的話,你馬上就可以使用Freebasic,F(xiàn)reebasic和c是高度兼容的,而且可以使用gcc或LLvm編譯。本系列適用于有點(diǎn)VB基礎(chǔ)的人看,而且我也只是把c語(yǔ)言的入門(mén)教程作一個(gè)極其簡(jiǎn)單的改編而已。
本部分內(nèi)容改編自c語(yǔ)言中文網(wǎng)中的c語(yǔ)言入門(mén),這個(gè)入門(mén)教程寫(xiě)得很不錯(cuò),你也可以隨意找一本c語(yǔ)言入門(mén),只看vb沒(méi)有的那部分章節(jié)。
'冬瓜湯改編自c語(yǔ)言中文網(wǎng)的c語(yǔ)言入門(mén)
一、1分鐘徹底理解指針的概念:
計(jì)算機(jī)中所有的數(shù)據(jù)都必須放在內(nèi)存中,不同類型的數(shù)據(jù)占用的字節(jié)數(shù)不一樣,例如 long 占用4個(gè)字節(jié),boolean 占用1個(gè)字節(jié)。為了正確地訪問(wèn)這些數(shù)據(jù),必須為每個(gè)字節(jié)都編上號(hào)碼,就像門(mén)牌號(hào)、身份證號(hào)一樣,每個(gè)字節(jié)的編號(hào)是唯一的,根據(jù)編號(hào)可以準(zhǔn)確地找到某個(gè)字節(jié)。
下圖是 4G 內(nèi)存中每個(gè)字節(jié)的編號(hào)(以十六進(jìn)制表示):

我們將內(nèi)存中字節(jié)的編號(hào)稱為
地址(Address)或
指針(Pointer)。地址從 0 開(kāi)始依次增加,對(duì)于 32 位環(huán)境,程序能夠使用的內(nèi)存為 4GB,最小的地址為 0,最大的地址為 0XFFFFFFFF。
下面的代碼演示了如何輸出一個(gè)地址:
dim as long a =100
dim as String myStr ="這是一個(gè)FB入門(mén)教程"
print "a的地址:" & varptr(a)
print "myStr的地址:" & strptr(mystr)
sleep
運(yùn)行結(jié)果:
a的地址:1310384
mystr的地址:6164384
FB語(yǔ)言用變量來(lái)存儲(chǔ)數(shù)據(jù),用函數(shù)來(lái)定義一段可以重復(fù)使用的代碼,它們最終都要放到內(nèi)存中才能供 CPU 使用。
數(shù)據(jù)和代碼都以二進(jìn)制的形式存儲(chǔ)在內(nèi)存中,計(jì)算機(jī)無(wú)法從格式上區(qū)分某塊內(nèi)存到底存儲(chǔ)的是數(shù)據(jù)還是代碼。當(dāng)程序被加載到內(nèi)存后,操作系統(tǒng)會(huì)給不同的內(nèi)存塊指定不同的權(quán)限,擁有讀取和執(zhí)行權(quán)限的內(nèi)存塊就是代碼,而擁有讀取和寫(xiě)入權(quán)限(也可能只有讀取權(quán)限)的內(nèi)存塊就是數(shù)據(jù)。
CPU 只能通過(guò)地址來(lái)取得內(nèi)存中的代碼和數(shù)據(jù),程序在執(zhí)行過(guò)程中會(huì)告知 CPU 要執(zhí)行的代碼以及要讀寫(xiě)的數(shù)據(jù)的地址。如果程序不小心出錯(cuò),或者開(kāi)發(fā)者有意為之,在 CPU 要寫(xiě)入數(shù)據(jù)時(shí)給它一個(gè)代碼區(qū)域的地址,就會(huì)發(fā)生內(nèi)存訪問(wèn)錯(cuò)誤。這種內(nèi)存訪問(wèn)錯(cuò)誤會(huì)被硬件和操作系統(tǒng)攔截,強(qiáng)制程序崩潰,程序員沒(méi)有挽救的機(jī)會(huì)。
CPU 訪問(wèn)內(nèi)存時(shí)需要的是地址,而不是變量名和函數(shù)名!變量名和函數(shù)名只是地址的一種助記符,當(dāng)源文件被編譯和鏈接成可執(zhí)行程序后,它們都會(huì)被替換成地址。編譯和鏈接過(guò)程的一項(xiàng)重要任務(wù)就是找到這些名稱所對(duì)應(yīng)的地址。 假設(shè)變量 a、b、c 在內(nèi)存中的地址分別是 0X1000、0X2000、0X3000,那么加法運(yùn)算c = a + b;將會(huì)被轉(zhuǎn)換成類似下面的形式:
0X3000 = (0X1000) + (0X2000);
( )表示取值操作,整個(gè)表達(dá)式的意思是,取出地址 0X1000 和 0X2000 上的值,將它們相加,把相加的結(jié)果賦值給地址為 0X3000 的內(nèi)存
變量名和函數(shù)名為我們提供了方便,讓我們?cè)诰帉?xiě)代碼的過(guò)程中可以使用易于閱讀和理解的英文字符串,不用直接面對(duì)二進(jìn)制地址,那場(chǎng)景簡(jiǎn)直讓人崩潰。
需要注意的是,雖然變量名、函數(shù)名、字符串名和數(shù)組名在本質(zhì)上是一樣的,它們都是地址的助記符,但在編寫(xiě)代碼的過(guò)程中,我們認(rèn)為變量名表示的是數(shù)據(jù)本身,而函數(shù)名、字符串名和數(shù)組名表示的是代碼塊或數(shù)據(jù)塊的首地址。