設(shè)為首頁收藏本站Access中國

Office中國論壇/Access中國論壇

 找回密碼
 注冊

QQ登錄

只需一步,快速開始

tag 標(biāo)簽: FreeBasic

相關(guān)帖子

版塊 作者 回復(fù)/查看 最后發(fā)表

沒有相關(guān)內(nèi)容

相關(guān)日志

分享 Freebasic菜鳥初學(xué)Freebasic基礎(chǔ)教程五:宏參數(shù)的字符串化#和宏參數(shù)的連接##符號
ganlinlao 2017-5-8 18:44
關(guān)于#和## 在C語言的宏中,#的功能是將其后面的宏參數(shù)進行字符串化操作(Stringfication),簡單說就是在對它所引用的宏變量 通過替換后在其左右各加上一個雙引號。比如下面代碼中的宏: #define WARN_IF(EXP) do{ if (EXP) fprintf(stderr, "Warning: " #EXP "/n"); } while(0) 那么實際使用中會出現(xiàn)下面所示的替換過程: WARN_IF (divider == 0); 被替換為 do { if (divider == 0) fprintf(stderr, "Warning" "divider == 0" "/n"); } while(0); 這樣每次divider(除數(shù))為0的時候便會在標(biāo)準(zhǔn)錯誤流上輸出一個提示信息。 而##被稱為連接符(concatenator),用來將兩個Token連接為一個Token。注意這里連接的對象是Token就行,而不一定 是宏的變量。比如你要做一個菜單項命令名和函數(shù)指針組成的結(jié)構(gòu)體的數(shù)組,并且希望在函數(shù)名和菜單項命令名之間有直觀的、名字上的關(guān)系。那么下面的代碼就非常實用: struct command { char * name; void (*function) (void); }; #define COMMAND(NAME) { NAME, NAME ## _command } // 然后你就用一些預(yù)先定義好的命令來方便的初始化一個command結(jié)構(gòu)的數(shù)組了: struct command commands[] = { COMMAND(quit), COMMAND(help), ... } COMMAND宏在這里充當(dāng)一個代碼生成器的作用,這樣可以在一定程度上減少代碼密度,間接地也可以減少不留心所造成的錯誤。我們還可以n個##符號連接 n+1個Token,這個特性也是#符號所不具備的。比如: #define LINK_MULTIPLE(a,b,c,d) a##_##b##_##c##_##d typedef struct _record_type LINK_MULTIPLE(name,company,position,salary); // 這里這個語句將展開為: // typedef struct _record_type name_company_position_salary; 關(guān)于...的使用 ...在C宏中稱為Variadic Macro,也就是變參宏。比如: #define myprintf(templt,...) fprintf(stderr,templt,__VA_ARGS__) // 或者 #define myprintf(templt,args...) fprintf(stderr,templt,args) 第一個宏中由于沒有對變參起名,我們用默認(rèn)的宏__VA_ARGS__來替代它。第二個宏 中,我們顯式地命名變參為args,那么我們在宏定義中就可以用args來代指變參了。同C語言的stdcall一樣,變參必須作為參數(shù)表的最有一項出 現(xiàn)。當(dāng)上面的宏中我們只能提供第一個參數(shù)templt時,C標(biāo)準(zhǔn)要求我們必須寫成: myprintf(templt,); 的形式。這時的替換過程為: myprintf("Error!/n",); 替換為: fprintf(stderr,"Error!/n",); 這是一個語法錯誤,不能正常編譯。這個問題一般有兩個解決方法。首先,GNU CPP提供的解決方法允許上面的宏調(diào)用寫成: myprintf(templt); 而它將會被通過替換變成: fprintf(stderr,"Error!/n",); 很明顯,這里仍然會產(chǎn)生編譯錯誤(非本例的某些情況下不會產(chǎn)生編譯錯誤)。除了這種方式外,c99和GNU CPP都支持下面的宏定義方式: #define myprintf(templt, ...) fprintf(stderr,templt, ##__VAR_ARGS__) 這時,##這個連接符號充當(dāng)?shù)淖饔镁褪钱?dāng)__VAR_ARGS__為空的時候,消除前面的那個逗號。那么此時的翻譯過程如下: myprintf(templt); 被轉(zhuǎn)化為: fprintf(stderr,templt); 這樣如果templt合法,將不會產(chǎn)生編譯錯誤。 這里列出了一些宏使用中容易出錯的地方,以及合適的使用方式。 錯誤的嵌套-Misnesting 宏的定義不一定要有完整的、配對的括號,但是為了避免出錯并且提高可讀性,最好避免這樣使用。 由操作符優(yōu)先級引起的問題-Operator Precedence Problem 由于宏只是簡單的替換,宏的參數(shù)如果是復(fù)合結(jié)構(gòu),那么通過替換之后可能由于各個參數(shù)之間的操作符優(yōu)先級高于單個參數(shù)內(nèi)部各部分之間相互作用的操作符優(yōu)先級,如果我們不用括號保護各個宏參數(shù),可能會產(chǎn)生預(yù)想不到的情形。比如: #define ceil_div(x, y) (x + y - 1) / y 那么 a = ceil_div( b c, sizeof(int) ); 將被轉(zhuǎn)化為: a = ( b c + sizeof(int) - 1) / sizeof(int); // 由于+/-的優(yōu)先級高于的優(yōu)先級,那么上面式子等同于: a = ( b (c + sizeof(int) - 1)) / sizeof(int); 這顯然不是調(diào)用者的初衷。為了避免這種情況發(fā)生,應(yīng)當(dāng)多寫幾個括號: #define ceil_div(x, y) (((x) + (y) - 1) / (y)) 消除多余的分號-Semicolon Swallowing 通常情況下,為了使函數(shù)模樣的宏在表面上看起來像一個通常的C語言調(diào)用一樣,通常情況下我們在宏的后面加上一個分號,比如下面的帶參宏: MY_MACRO(x); 但是如果是下面的情況: #define MY_MACRO(x) { /* line 1 */ /* line 2 */ /* line 3 */ } //... if (condition()) MY_MACRO(a); else {...} 這樣會由于多出的那個分號產(chǎn)生編譯錯誤。為了避免這種情況出現(xiàn)同時保持MY_MACRO(x);的這種寫法,我們需要把宏定義為這種形式: #define MY_MACRO(x) do { /* line 1 */ /* line 2 */ /* line 3 */ } while(0) 這樣只要保證總是使用分號,就不會有任何問題。 Duplication of Side Effects 這里的Side Effect是指宏在展開的時候?qū)ζ鋮?shù)可能進行多次Evaluation(也就是取值),但是如果這個宏參數(shù)是一個函數(shù),那么就有可能被調(diào)用多次從而達(dá)到不一致的結(jié)果,甚至?xí)l(fā)生更嚴(yán)重的錯誤。比如: #define min(X,Y) ((X) (Y) ? (Y) : (X)) //... c = min(a,foo(b)); 這時foo()函數(shù)就被調(diào)用了兩次。為了解決這個潛在的問題,我們應(yīng)當(dāng)這樣寫min(X,Y)這個宏: #define min(X,Y) ({ typeof (X) x_ = (X); typeof (Y) y_ = (Y); (x_ y_) ? x_ : y_; }) ({...})的作用是將內(nèi)部的幾條語句中最后一條的值返回,它也允許在內(nèi)部聲明變量(因為它通過大括號組成了一個局部Scope)。
個人分類: FreeBasic|3527 次閱讀|0 個評論
分享 Freebasic菜鳥初學(xué)Freebasic基礎(chǔ)教程四:了解條件編譯
ganlinlao 2017-5-8 18:25
這種能夠根據(jù)不同情況編譯不同代碼、產(chǎn)生不同目標(biāo)文件的機制,稱為條件編譯。條件編譯是預(yù)處理程序的功能,不是編譯器的功能。 條件編譯有多種形式,下面一一講解。 #if 命令 #if 命令的完整格式為: #if 整型常量表達(dá)式1 程序段1 #elseif 整型常量表達(dá)式2 程序段2 #elseif 整型常量表達(dá)式3 程序段3 #else 程序段4 #endif 它的意思是:如!氨磉_(dá)式1”的值為真(非0),就對“程序段1”進行編譯,否則就計算“表達(dá)式2”,結(jié)果為真的話就對“程序段2”進行編譯,為假的話就繼續(xù)往下匹配,直到遇到值為真的表達(dá)式,或者遇到 #else。這一點和 if else 非常類似。 需要注意的是,#if 命令要求判斷條件為“整型常量表達(dá)式”,也就是說,表達(dá)式中不能包含變量,而且結(jié)果必須是整數(shù);而 if 后面的表達(dá)式?jīng)]有限制,只要符合語法就行。這是 #if 和 if 的一個重要區(qū)別。 #elseif 和 #else 也可以省略,如下所示: #if __FB_WIN32__ print "This is Windows!\n" #else print("Unknown platform!\n" #endif #if __FB_LINUX__ printf("This is Linux!\n"); #endif #ifdef 命令 #ifdef 命令的格式為: #ifdef 宏名 程序段1 #else 程序段2 #endif 它的意思是,如果當(dāng)前的宏已被定義過,則對“程序段1”進行編譯,否則對“程序段2”進行編譯。 也可以省略 #else: #ifdef 宏名 程序段 #endif #ifdef __fb_debug__ print "正在使用 Debug 模式編譯程序..." #else print"正在使用 Release 模式編譯程序..." #endif 當(dāng)以 Debug 模式編譯程序時,宏 _DEBUG 會被定義,預(yù)處器會保留第 5 行代碼,刪除第 7 行代碼。反之會刪除第 5 行,保留第 7 行。 #ifndef 命令 #ifndef 命令的格式為: #ifndef 宏名 程序段1 #else 程序段2 #endif 與 #ifdef 相比,僅僅是將 #ifdef 改為了 #ifndef。它的意思是,如果當(dāng)前的宏未被定義,則對“程序段1”進行編譯,否則對“程序段2”進行編譯,這與 #ifdef 的功能正好相反。 區(qū)別 最后需要注意的是,#if 后面跟的是“整型常量表達(dá)式”,而 #ifdef 和 #ifndef 后面跟的只能是一個宏名,不能是其他的。 例如,下面的形式只能用于 #if: #define NUM 10 #if NUM = 10 or NUM = 20 print "NUM: " NUM #else print "NUM Error" #EndIf 運行結(jié)果: NUM: 10 再如,兩個宏都存在時編譯代碼A,否則編譯代碼B: #define NUM1 10 #define NUM2 20 #if Defined(NUM1) And Defined(NUM2) Print "NUM1:" NUM1 Chr(10) "NUM2: " NUM2 #else print "Error" #EndIf sleep 運行結(jié)果: NUM1: 10, NUM2: 20 #ifdef 可以認(rèn)為是 #if defined 的縮寫。
個人分類: FreeBasic|2753 次閱讀|0 個評論
分享 Freebasic菜鳥初學(xué)Freebasic基礎(chǔ)教程三:帶參數(shù)的宏定義
ganlinlao 2017-5-8 17:43
FB語言允許宏帶有參數(shù)。在宏定義中的參數(shù)稱為形式參數(shù),在宏調(diào)用中的參數(shù)稱為實際參數(shù),這點和函數(shù)有些類似。 '冬瓜湯改編自c語言中文網(wǎng)c語言基礎(chǔ)入門 對帶參數(shù)的宏,在調(diào)用中,不僅要宏展開,而且要用實參去代換形參。 帶參宏定義的一般形式為: #define 宏名(形參列表) 字符串 在字符串中含有各個形參。 帶參宏調(diào)用的一般形式為: 宏名(實參列表); 例如: #define M(y) y*y+3*y '宏定義 '// Code k=M(5); //宏調(diào)用 在宏調(diào)用時,用實參5去代替形參y,經(jīng)預(yù)處理宏展開后的語句為k=5*5+3*5。 【示例】輸出兩個數(shù)中較大的數(shù)。 #define MAX(a,b) iif(ab, a , b) Dim As long x,y,myMax input "請輸入一個數(shù)字: " ,x Input "請輸入另一個數(shù)字:" ,y myMax = MAX(x, y) print myMax sleep 運行結(jié)果: 輸入兩個數(shù)字: 10 20 max=20 程序第2行進行了帶參宏定義,用宏名MAX表示條件表達(dá)式iif(ab, a , b),形參a、b均出現(xiàn)在條件表達(dá)式中。程序第7行myMax=MAX(x, y)為宏調(diào)用,實參 x、y 將代換形參a、b。宏展開后該語句為: max=iif(xy, x , y) 對帶參宏定義的說明 1) 帶參宏定義中,形參之間可以出現(xiàn)空格,但是宏名和形參列表之間不能有空格出現(xiàn)。例如把: #define MAX(a,b) iif(ab, a , b) 寫為: #define MAX (a,b) iif(ab, a , b) 將被認(rèn)為是無參宏定義,宏名MAX代表字符串(a,b) iif(ab, a , b)。宏展開時,宏調(diào)用語句: max=MAX(x,y); 將變?yōu)椋?max=(a,b)iif(ab, a , b)(x,y) 這顯然是錯誤的。 2) 在帶參宏定義中,不會為形式參數(shù)分配內(nèi)存,因此不必指明數(shù)據(jù)類型。而在宏調(diào)用中,實參包含了具體的數(shù)據(jù),要用它們?nèi)ゴ鷵Q形參,因此必須指明數(shù)據(jù)類型。 這一點和函數(shù)是不同的:在函數(shù)中,形參和實參是兩個不同的變量,都有自己的作用域,調(diào)用時要把實參的值傳遞給形參;而在帶參數(shù)的宏中,只是符號的替換,不存在值傳遞的問題。 【示例】輸入 n,輸出 (n+1)^2 的值。 #define SQ(y) (y)*(y) Dim As Long a, sq; input "input a number: ",a sq = SQ(a+1); print "sq=" + sq 運行結(jié)果: input a number: 9 sq=100 第2行為宏定義,形參為 y。第7行宏調(diào)用中實參為 a+1,是一個表達(dá)式,在宏展開時,用 a+1 代換 y,再用 (y)*(y) 代換 SQ,得到如下語句: sq=(a+1)*(a+1); 這與函數(shù)的調(diào)用是不同的,函數(shù)調(diào)用時要把實參表達(dá)式的值求出來再傳遞給形參,而宏展開中對實參表達(dá)式不作計算,直接按照原樣替換。 3) 在宏定義中,字符串內(nèi)的形參通常要用括號括起來以避免出錯。例如上面的宏定義中 (y)*(y) 表達(dá)式的 y 都用括號括起來,因此結(jié)果是正確的。如果去掉括號,把程序改為以下形式: #define SQ(y) y*y Dim As Long a, sq; input "input a number: ",a sq = SQ(a+1); print "sq=" + sq 運行結(jié)果為: input a number: 9 sq=19 同樣輸入9,但結(jié)果卻是不一樣的。問題在哪里呢?這是由于替換只作符號替換而不作其它處理而造成的。宏替換后將得到以下語句: sq=a+1*a+1; 由于a為9故sq的值為19。這顯然與題意相違,因此參數(shù)兩邊的括號是不能少的。即使在參數(shù)兩邊加括號還是不夠的,請看下面程序: #define SQ(y) (y)*(y) Dim As Long a, sq; input "input a number: ",a sq = 200/SQ(a+1); print "sq=" + sq 與前面的代碼相比,只是把宏調(diào)用語句改為: sq=200/SQ(a+1); 運行程序后,如果仍然輸入 9,那么我們希望的結(jié)果為 2。但實際情況并非如此: input a number: 9 sq=200 為什么會得這樣的結(jié)果呢?分析宏調(diào)用語句,在宏展開之后變?yōu)椋?sq=200/(a+1)*(a+1); a 為 9 時,由于“/”和“*”運算符優(yōu)先級和結(jié)合性相同,所以先計算 200/(9+1),結(jié)果為 20,再計算 20*(9+1),最后得到 200。 為了得到正確答案,應(yīng)該在宏定義中的整個字符串外加括號: #define SQ(y) ((y)*(y)) Dim As Long a, sq; input "input a number: ",a sq = 200/SQ(a+1); print "sq=" + sq 由此可見, 對于帶參宏定義不僅要在參數(shù)兩側(cè)加括號,還應(yīng)該在整個字符串外加括號。 帶參數(shù)的宏和函數(shù)很相似,但有本質(zhì)上的區(qū)別: 宏展開僅僅是字符串的替換,不會對表達(dá)式進行計算;宏在編譯之前就被處理掉了,它沒有機會參與編譯,也不會占用內(nèi)存。而函數(shù)是一段可以重復(fù)使用的代碼,會被編譯,會給它分配內(nèi)存,每次調(diào)用函數(shù),就是執(zhí)行這塊內(nèi)存中的代碼。
個人分類: FreeBasic|2699 次閱讀|0 個評論
分享 Freebasic菜鳥初學(xué)Freebasic基礎(chǔ)教程二:宏定義和預(yù)處理命令
ganlinlao 2017-5-8 11:09
'冬瓜湯改編自c語言中文網(wǎng)的c語言基礎(chǔ)入門 宏定義是預(yù)處理命令的一種,它允許用一個標(biāo)識符來表示一個字符串。 先看一個例子: #define N 100 dim sum as long sum=20 +N print Sum 運行結(jié)果: 120 該示例中的語句 sum = 20 + N;,N被100代替了。 #define N 100就是宏定義,N為宏名,100是宏的內(nèi)容。 在編譯預(yù)處理時,對程序中所有出現(xiàn)的“宏名”,都用宏定義中的字符串去代換,這稱為“宏代換”或“宏展開”。 宏定義是由源程序中的宏定義命令#define完成的,宏代換是由預(yù)處理程序完成的。 宏定義的一般形式為: #define 宏名 字符串 #表示這是一條預(yù)處理命令,所有的預(yù)處理命令都以#開頭。define是預(yù)處理命令。宏名是標(biāo)識符的一種,命名規(guī)則和標(biāo)識符相同。字符串可以是常數(shù)、表達(dá)式等。 這里所說的字符串是一般意義上的字符序列,不要和FB語言中的字符串等同,它不需要雙引號。 程序中反復(fù)使用的表達(dá)式就可以使用宏定義,例如: #define M (n*n+3*n) 它的作用是指定標(biāo)識符M來代替表達(dá)式(y*y+3*y)。 在編寫源程序時,所有的(y*y+3*y)都可由M代替,而對源程序編譯時,將先由預(yù)處理程序進行宏代換, 即用(y*y+3*y)表達(dá)式去替換所有的宏名M,然后再進行編譯。 將上面的例子補充完整: 上面的程序中首先進行宏定義,定義M來替代表達(dá)式(n*n+3*n),在sum=3*M+4*M+5*M中作了宏調(diào)用。在預(yù)處理時經(jīng)宏展開后該語句變?yōu)椋?sum=3*(n*n+3*n)+4*(n*n+3*n)+5*(n*n+3*n); 需要注意的是,在宏定義中表達(dá)式(n*n+3*n)兩邊的括號不能少,否則會發(fā)生錯誤。 如當(dāng)作以下定義后: #difine M n*n+3*n在宏展開時將得到下述語句: s=3*n*n+3*n+4*n*n+3*n+5*n*n+3*n;這相當(dāng)于: 3n2+3n+4n2+3n+5n2+3n 這顯然是不正確的。所以進行宏定義時要注意,應(yīng)該保證在宏代換之后不發(fā)生錯誤。 對宏定義的幾點說明 1) 宏定義是用宏名來表示一個字符串,在宏展開時又以該字符串取代宏名,這只是一種簡單的替換。 字符串中可以含任何字符,可以是常數(shù),也可以是表達(dá)式,預(yù)處理程序?qū)λ蛔魅魏螜z查, 如有錯誤,只能在編譯已被宏展開后的源程序時發(fā)現(xiàn)。 2) 宏定義不是說明或語句,在行末不必加分號,如加上分號則連分號也一起替換。 3) 宏定義必須寫在函數(shù)之外,其作用域為宏定義命令起到源程序結(jié)束。如要終止其作用域可使用#undef命令。例如: #define PI 3.14159 Sub main () ' Code return 0 ; end Sub #undef PI Function func () 'Code end Function '========================= 表示PI只在main函數(shù)中有效,在func中無效。 4) 宏名在源程序中若用引號括起來,則預(yù)處理程序不對其作宏代換,例如: #define OK 100 print "OK " 運行結(jié)果: OK 該例中定義宏名OK表示100,但在 print 語句中 OK 被引號括起來,因此不作宏代換,而作為字符串處理。 5) 宏定義允許嵌套,在宏定義的字符串中可以使用已經(jīng)定義的宏名,在宏展開時由預(yù)處理程序?qū)訉哟鷵Q。例如: #define PI 3.1415926 #define S PI*y*y /* PI是已定義的宏名*/ 對語句: print S在宏代換后變?yōu)椋? print 3.1415926*y*y 6) 習(xí)慣上宏名用大寫字母表示,以便于與變量區(qū)別。但也允許用小寫字母。 7) 可用宏定義表示數(shù)據(jù)類型,使書寫方便。例如: #define UINT ULong 在程序中可用UINT作變量說明: dim as uint a, b 應(yīng)注意用宏定義表示數(shù)據(jù)類型和用type…… As定義數(shù)據(jù)說明符的區(qū)別。 宏定義只是簡單的字符串代換,是在預(yù)處理完成的,而type… As是在編譯時處理的,它不是作簡單的代換,而是對類型說明符重新命名。被命名的標(biāo)識符具有類型定義說明的功能。 宏定義雖然也可表示數(shù)據(jù)類型, 但畢竟是作字符代換。在使用時要分外小心,以避出錯。
個人分類: FreeBasic|2774 次閱讀|0 個評論
分享 Freebasic菜鳥初學(xué)Freebasic基礎(chǔ)教程一:一分鐘理解指針
ganlinlao 2017-5-8 10:04
Freebasic菜鳥初學(xué)Freebasic基礎(chǔ)教程一:一分鐘理解指針
Freebsic是一門沒有任何特點的開源語言,非常平庸。它是披著VB的語法羊皮,長著一顆c語言的心,懷著c++的情懷,卻生在一個托管語言橫行的世界。所以本系列文章,謹(jǐn)此獻(xiàn)給極其少數(shù)幾個喜歡Freebasic的人。 freebasic的語法和vb是極其相似的,所以如果你有vb6或vba的基礎(chǔ)的話,那么你用Freebasic寫代碼幾乎沒有任何障礙,非常熟悉,如果你有點c語言基礎(chǔ)的話,你馬上就可以使用Freebasic,F(xiàn)reebasic和c是高度兼容的,而且可以使用gcc或LLvm編譯。本系列適用于有點VB基礎(chǔ)的人看,而且我也只是把c語言的入門教程作一個極其簡單的改編而已。 本部分內(nèi)容改編自c語言中文網(wǎng)中的c語言入門,這個入門教程寫得很不錯,你也可以隨意找一本c語言入門,只看vb沒有的那部分章節(jié)。 '冬瓜湯改編自c語言中文網(wǎng)的c語言入門 一、1分鐘徹底理解指針的概念: 計算機中所有的數(shù)據(jù)都必須放在內(nèi)存中,不同類型的數(shù)據(jù)占用的字節(jié)數(shù)不一樣,例如 long 占用4個字節(jié),boolean 占用1個字節(jié)。為了正確地訪問這些數(shù)據(jù),必須為每個字節(jié)都編上號碼,就像門牌號、身份證號一樣,每個字節(jié)的編號是唯一的,根據(jù)編號可以準(zhǔn)確地找到某個字節(jié)。 下圖是 4G 內(nèi)存中每個字節(jié)的編號(以十六進制表示): 我們將內(nèi)存中字節(jié)的編號稱為 地址(Address) 或 指針(Pointer) 。地址從 0 開始依次增加,對于 32 位環(huán)境,程序能夠使用的內(nèi)存為 4GB,最小的地址為 0,最大的地址為 0XFFFFFFFF。 下面的代碼演示了如何輸出一個地址: dim as long a =100 dim as String myStr ="這是一個FB入門教程" print "a的地址:" varptr(a) print "myStr的地址:" strptr(mystr) sleep 運行結(jié)果: a的地址:1310384 mystr的地址:6164384 FB語言用變量來存儲數(shù)據(jù),用函數(shù)來定義一段可以重復(fù)使用的代碼,它們最終都要放到內(nèi)存中才能供 CPU 使用。 數(shù)據(jù)和代碼都以二進制的形式存儲在內(nèi)存中,計算機無法從格式上區(qū)分某塊內(nèi)存到底存儲的是數(shù)據(jù)還是代碼。當(dāng)程序被加載到內(nèi)存后,操作系統(tǒng)會給不同的內(nèi)存塊指定不同的權(quán)限,擁有讀取和執(zhí)行權(quán)限的內(nèi)存塊就是代碼,而擁有讀取和寫入權(quán)限(也可能只有讀取權(quán)限)的內(nèi)存塊就是數(shù)據(jù)。 CPU 只能通過地址來取得內(nèi)存中的代碼和數(shù)據(jù),程序在執(zhí)行過程中會告知 CPU 要執(zhí)行的代碼以及要讀寫的數(shù)據(jù)的地址。如果程序不小心出錯,或者開發(fā)者有意為之,在 CPU 要寫入數(shù)據(jù)時給它一個代碼區(qū)域的地址,就會發(fā)生內(nèi)存訪問錯誤。這種內(nèi)存訪問錯誤會被硬件和操作系統(tǒng)攔截,強制程序崩潰,程序員沒有挽救的機會。 CPU 訪問內(nèi)存時需要的是地址,而不是變量名和函數(shù)名!變量名和函數(shù)名只是地址的一種助記符,當(dāng)源文件被編譯和鏈接成可執(zhí)行程序后,它們都會被替換成地址。編譯和鏈接過程的一項重要任務(wù)就是找到這些名稱所對應(yīng)的地址。 假設(shè)變量 a、b、c 在內(nèi)存中的地址分別是 0X1000、0X2000、0X3000,那么加法運算c = a + b;將會被轉(zhuǎn)換成類似下面的形式: 0X3000 = (0X1000) + (0X2000); ( )表示取值操作,整個表達(dá)式的意思是,取出地址 0X1000 和 0X2000 上的值,將它們相加,把相加的結(jié)果賦值給地址為 0X3000 的內(nèi)存 變量名和函數(shù)名為我們提供了方便,讓我們在編寫代碼的過程中可以使用易于閱讀和理解的英文字符串,不用直接面對二進制地址,那場景簡直讓人崩潰。 需要注意的是,雖然變量名、函數(shù)名、字符串名和數(shù)組名在本質(zhì)上是一樣的,它們都是地址的助記符,但在編寫代碼的過程中,我們認(rèn)為變量名表示的是數(shù)據(jù)本身,而函數(shù)名、字符串名和數(shù)組名表示的是代碼塊或數(shù)據(jù)塊的首地址。
個人分類: FreeBasic|5749 次閱讀|0 個評論
分享 FreeBasic基礎(chǔ)入門2——冬瓜湯整理
ganlinlao 2014-9-25 21:19
三、FreeBasic常用的函數(shù)分類: 類型 函數(shù)或語句 說明 冬瓜湯備注 數(shù)組 Erase ReDim 及 preserve Option Base 語句 用來聲明數(shù)組下標(biāo)的缺省下界 0 或 1 LBound() 返回指定數(shù)組維可用的最小下標(biāo)。 注:FB沒有join函數(shù) UBound() 返回指定數(shù)組維可用的最大下標(biāo) 字符串 InStr() 返回數(shù)字,指定一字符串在另一字符串中最先出現(xiàn)的位置。 注意: instr 有一個 選項 InStrRev () 返回數(shù)字,指定一字符串在另一字符串中最后出現(xiàn)的位置。 LCase() 字母轉(zhuǎn)小寫 UCase() 字母轉(zhuǎn)大寫 Len() 包含字符串內(nèi)字符的數(shù)目,或是存儲一變量所需的字節(jié)數(shù)。 Left() Right() Lset() 左對齊 Rset() 右對齊 Ltrim() Rtrim() Mid() 兩種用法 , 一種替換,一種截取 Space() String() Trim() Wspace() 同 space() 用于 unicode Wstring() 同 string() 用于 unicode Format() 格式化 數(shù)學(xué)函數(shù) Abs() Acos() Asin() Atan2() Atn() Cos() Exp() Fix() Frac() 返回一個數(shù)字的小數(shù)部分 Int() Log() Randominze() Rnd() Sgn() Sin() Sqr() Tan() 日期 時間函數(shù) Now() Dateserial() Timeserial() Datevalue() Timevalue() Second() Minute() Hour() Day() Weekday() Month() Year() DatePart() DateAdd() DateDiff() isDate() MonthName WeekDayName Date() 返回 string ,表示當(dāng)前系統(tǒng)日期 Time() 返回 string ,表示當(dāng)前系統(tǒng)時間 SetDate() 設(shè)置系統(tǒng)日期, vb 用 date 語句 SetTime() 設(shè)置系統(tǒng)時間, vb 用 time 語句 Timer() 數(shù)據(jù)類型轉(zhuǎn)換 轉(zhuǎn)成數(shù)字 Cast() 將表達(dá)式強制轉(zhuǎn)成一個特定類型 Cbyte() CDbl() Cint() CLng() CLngInt() Cptr() CShort() CSign() CSng() CUbyte() CUint() CULng() CUlngInt() CUnsg() CUshort() 轉(zhuǎn)成字符串 Str() 數(shù)字轉(zhuǎn)成字符串,或 Unicode 字符串轉(zhuǎn)成 ansci 字符串 WStr() 數(shù)字轉(zhuǎn)成 unicode 字符串,或 ansci 字符串轉(zhuǎn)成 unicode 字符串 Val() 注意 Val() 在 FB 中返回的是浮點數(shù) Double 。如 val(“10”) 返回 10.0 ValInt() ValUint() ValLng() ValUlng() 其它轉(zhuǎn)換 Asc() Chr() Bin() 把數(shù)字轉(zhuǎn)成二進制 Oct() Hex() Wbin() Wchr() Whex() Woct() 錯誤處理 Erl() 返回錯誤行號。調(diào)試用的 Ern() 返回錯誤的函數(shù)。調(diào)試用的 Ermn() 返回錯誤的模塊。調(diào)試用的 Err Error On Error Goto 可以用 On error goto 0 resume 注: FB 處理錯誤和 VBA 是一樣的, Resume next 但 VBA 多了 Raise 和 clear 文件及 I/O 打開文件函數(shù) Freefile() Open Close Reset Open Com 打開設(shè)備端口輸入 / 輸出 文件 Open cons 打開 console 輸入 / 輸出 Open Lpt 打開打印機 輸入 / 輸出 Open Pipe Open scrn 讀 / 寫函數(shù) Input Output Append Binary Random 讀 / 寫模式 Access Write Read ReadWrite 編碼 Encoding 支持 utf-8,utf-16,utf-32,ascii( 默認(rèn) ) 讀寫 Input # Write # Input() Winput() Line input # Print # Put # Get # 位置及其它 Lof Loc Eof Seek 語句 Seek() Lock Unlock 用戶輸入函數(shù) Input Line input Input() Winput() inKey GetKey 操作系統(tǒng)相關(guān)函數(shù) Exec Chain Run Kill Name 操作目錄 CurDir ChDir Dir ExePath MkDir RmDir 文件屬性 FileAttr FileCopy FileDateTime FileExists FileLen 操作系統(tǒng) Fre Command Environ IsreDirected SetEnviron Shell System 說明:因為 VBA 是從 QB 發(fā)展過來的。 FB 也是兼容 QB 的。 所以從這一方面 可以看出 VB 與 FB 有很高的相似性。 四、 FreeBasic 特有的,而 VB 沒有的函數(shù) : 類型 函數(shù) 說明 冬瓜湯備注 內(nèi)存函數(shù) Allocate CAllocate Reallocate Deallocate Peek Poke Clear Swap Sadd 多線程函數(shù) ThreadCall ThreadCreate ThreadDetach ThreadWait CondCreate CondWait CondSignal CondBroadCast CondDestroy MutexCreate MutexLock MutexUnlock MultexDestroy
個人分類: FreeBasic|3448 次閱讀|0 個評論
分享 Freebasic基礎(chǔ)入門1——冬瓜湯整理
熱度 1 ganlinlao 2014-9-25 21:10
Freebasic能用來做什么? 仁都見仁,智者見智。以下是我個人膚淺的理解 1、Freebasic比vba更適合跟硬件打交道。 2、Freebasic的dll可以直接被python和aauto等動態(tài)語言調(diào)用。需要性能的地方用Freebasic,可以顯著提高 性能。當(dāng)然這只是針對不想學(xué)c/c++的人而言。 3、Freebasic可以編譯成原生的64位。如果使用office64位,那么可以用freebasic編寫64位的dll供vba調(diào)用。 注: Freebasic不易用。個人喜好,僅供參考,急于求成者,慎入 一、Freebasic的數(shù)據(jù)類型: 類型 范圍大小 冬瓜湯備注說明 指針類型 指針類型 Ptr,Pointer 數(shù)據(jù)指針 Integer 隨系統(tǒng) 32 位或 64 位變化而變化。 32 位中轉(zhuǎn)變成 long 大小 ,64 位中轉(zhuǎn)成 longint 大小。 相當(dāng)于 VBA 中的 longPtr UINTEGER 整型 字節(jié)型 BYTE -127 至 288 整型 SHORT -32768 至 32767 相當(dāng)于 VBA 中的 integer 長整型 LONG 或 integer -2147483648 至 2147483647 相當(dāng)于 VBA 中的 long 在 32 位的 FB 中 integer 等價 long 64 位長整型 LONGINT -9 223 372 036 854 775 808 至 9 223 372 036 854 775 807 相當(dāng)于 VBA 中的 LongLong 無符整型 字節(jié)型 UBYTE 0 至 255 相當(dāng)于 VBA 中的 Byte 無符整型 USHORT 0 至 65535 無符長整型 ULONG 0 至 4294967295 無符 64 位 ULONGINT 0 至 9 223 372 036 854 775 807 單精度 SINGLE 雙精度 DOUBLE 字符串 String 0 至 2147483647 個字節(jié) 定長字符串 String *N C 字符串 Zstring 同上 兼容 c 寬字符串 Wstring Wstring 主要用于 unicode 兼容 c++ 對象 Object 二、Freebasic操作符: 字符串操作符 + 拼接多個字符串,如果其中一個變量不是 string ,將返回錯誤 強制拼接多個字符串。如果其中一個變量不是 string ,將自動轉(zhuǎn)成 string 數(shù)學(xué)運算符 + - * \ / ^ mod - 取負(fù) SHL 將一個數(shù)值表達(dá)式的位左移 SHR 將一個數(shù)值表達(dá)式的位右移 比較運算符 = = = is 注意 :FB 沒有 like 這個關(guān)鍵字 索引符 () 用于數(shù)組索引 用于指針數(shù)組索引 邏輯及按位運算符 And Or Not Xor Eqv Imp Andalso orelse 指針操作符 @ 獲取地址 * 取值 成員操作符 . 訪問自定義類型或類的成員 - 訪問成員的指針 賦值操作符 = 賦值 = Str2 =str1 相當(dāng)于 str2=str2str1 += -= *= /= \= ^= Mod= And= Or= Xor= Eqv= Lmp= Shl= Shr= Let 賦值語句,基本不用 Let() 同上
個人分類: FreeBasic|10487 次閱讀|1 個評論
分享 FreeBasic—一個差點把我嚇尿的跨平臺,奇怪而雜亂到讓人絕望的Basic語言
熱度 2 ganlinlao 2014-6-10 22:07
FreeBasic—一個差點把我嚇尿的跨平臺,奇怪而雜亂到讓人絕望的Basic語言
FreeBasic簡介: - 幾乎支援所有QB的原指令,且有許多追加功能 - 產(chǎn)生快速高品質(zhì)的機器碼,不依靠VM等虛擬機器 - 開源的,完全免費,包含原始碼,編譯出的程式無授權(quán)問題 - 支援MS-DOS/Win32/Linux多平臺,也可以編譯GUI程序 - 擁有眾多第三方函式庫支援(Allegro/SDL..以及DirectX/Win32API) - Unicode支援,使用中文十分容易 - 編譯EXE/OBJ/LIB/DLL都很容易,以便和其他語言應(yīng)用 …… 它 居然支持 運算符重載,類和命名空間,帶構(gòu)造析構(gòu)和this指針的那種! 而且函數(shù)返回值居然可以直接Return語句. 還有完整的WINDOWS頭文件!!!API不用手工聲明!!! 面向?qū)ο,繼承、虛函數(shù)、內(nèi)嵌匯編、大數(shù)組、指針、跨平臺等功能都有 我真想說一句,看到FreeBasic時,我差點嚇尿…… 個人對FB的初始感觀: 優(yōu)點: 1、FB是從QuickBasic發(fā)展過來的,VB6也是在QuickBasic上重新Com包裝,語法上的相似度極高,高到你只需注意一些點上的細(xì)節(jié)差別。 2、FB可以編譯成標(biāo)準(zhǔn)的dll,這和VB只能編譯成Active的dll完全不同。 3、FB可直接使用全部的C庫和大部分的C++庫。 4、部分的面向?qū)ο,可繼承,支持指針 (這一點可以把FB理解成C版的Basic語言) 5、跨平臺。linux上要找一個簡單易懂的Basic進行編程,不容易啊。FB可被python直接調(diào)用。 缺點: 1、編輯工具很爛,特別是跟VB這樣的編輯工具比較,簡直讓人絕望。 2、沒有一個簡單、強大、兼容性好的GUI編輯工具。讓人無所適從。 3、對com支持很差,特別是Ocx的支持,所以界面是一個大問題。當(dāng)然用wxc這樣的界面庫是另一回事。 4、沒有中文教程,讓人望而卻步。 FreeBasic是一個開源的編程語言,相信隨著時間的流逝,各個方面的應(yīng)用庫,會越來越多。 編輯工具主要有: FBedit,這是一個相當(dāng)重要的freeBasic編輯工具,相當(dāng)于vb6的簡陋版。 FBIDE,這是freeBasic的官方編輯工具,功能過于簡單。 FireFly for freeBasic。這是一個界面設(shè)計工具,而且是從for PowerBasic移植過來的,潛力不錯,有待考察。
個人分類: FreeBasic|18151 次閱讀|2 個評論

QQ|站長郵箱|小黑屋|手機版|Office中國/Access中國 ( 粵ICP備10043721號-1 )  

GMT+8, 2025-7-17 00:25 , Processed in 0.088562 second(s), 20 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

返回頂部