天正建筑lisp编程接口_编程思想|面向过程的结构化、面向对象的抽象化、泛型编程...
程序總是因而解決問題而生,如何組合描述數據、算法的模塊,就形成了各種編程思路的分類。
1 控制結構語句產生之前
20世紀60年代初,在提倡通過規則讓讀寫程序更輕松的時代潮流中,結構化程序設計應運而生。時至今日,大家對if、while、for這樣的結構控制語句早已習以為常。結構化程序設計的初衷正是通過導入這些語句使代碼結構理解變得簡單。
在沒有if、while或for語句之前,通過goto語句和標簽語句(實現一個語句入口)進行跳轉實現分支和重復。
void use_while(int x){ printf("use_while/n");start_loop: if(!(x > 0)) goto end_loop; printf("%d/n", x) ; x--; goto start_loop;end_loop: return;}goto語句仍然是高級語言的語法范疇,而跳轉的原始實現可以追溯到機器語言和匯編語言的跳轉指令。
匯編語言有無條件跳轉指令jmp和有條件跳轉指令族(以j打頭)。對于比較操作,其底層是通過減法運算實現的,通過減法運算的結果改變標志寄存器,根據標志寄存器的狀態控制跳轉。
6: int a=-3;00401268 mov dword ptr [ebp-4],0FFFFFFFDh7: if(a<0)0040126F cmp dword ptr [ebp-4],000401273 jge main+2Dh (0040127d)8: a=-a;00401275 mov eax,dword ptr [ebp-4]00401278 neg eax0040127A mov dword ptr [ebp-4],eax9: a++;0040127D mov ecx,dword ptr [ebp-4]00401280 add ecx,100401283 mov dword ptr [ebp-4],ecx2 結構化程序設計
相對于匯編語言的跳轉指令和高級語言的goto誡勉,使用if、while或for等控制結構語句,可以讓程序更易寫、易讀、更容易維護。
while語句,可以讓反復執行的if語句更簡潔:
void use_while2(int x){ printf("use_while/n"); while(x > 0){ printf("%d/n", x) ; x--; }}for語句,可以讓數值漸增的while語句更簡潔:
int i = 0;int n = 10;while(i < n){ printf("%d", i); i++;}for (i = 0; i < n; i++){ printf("%d", i);}3 面向對象
面向過程編程只是將函數封裝為一個函數模塊,數據和操作數據的函數處于分離的一個狀態。
類是數據抽象、封裝的最佳實踐,如一個數組封裝為類后,通過提供一個排序的接口sort(),其內部實現由類設計者完成,類使用者只需使用這個類接口即可,至于是使用冒泡排序還是快速排序,可由類設計者完成,即使內部實現不同的排序算法也不會影響到使用類接口的代碼,這就是接口設計與使用分離的思想。
如complex、string類:
面向過程與面向對象:
面向過程與面向對象各自優、劣勢:
當然,面向過程編程也稱為面向函數編程,函數也有接口設計和使用的概念:
函數的內部觀點:關心函數的定義,1 采用什么計算方法;2 采用什么實現結構;3 實際參數如何使用;4 怎樣得到所需要的返回值;
函數的外部觀點:關心函數的使用,1 實現了什么功能;2 名字是什么;3 要求幾個參數,各參數的意義和作用;4 返回什么值;
4 泛型編程
如果數據和操作這些數據的函數二者之間是一種緊密結合的關系,那封裝確實是一個最佳的選擇,如數據結構的一些封裝,如封裝動態數組、鏈表、棧、隊列,及這些數據結構的構造、增、刪元素的操作。但是,考慮到一些如排序、查找等操作能夠以較相似的接口來操作各類數據結構,便要將這些算法從各類數據結構的封裝中獨立起來,這便是泛型編程(Generic Programming,GP)的思想,C++的STL(Standard Template Library)便是GP的一個杰作。在STL中,在算法和作為數據結構的容器之間,以iterator_traits和iterator作為中間層,但實現了兩者的獨立性和結合性。
面向過程、面向對象、泛型:
5 命令式、聲明式、動態式、函數式編程
不同的領域需要不同的語言,不同的語言有各自擅長的領域。選擇一種語言和平臺以滿足解決全部問題的需要,這種方式已經一去不復返了。有時不同的釘子需要不同的錘子。
編程語言廣義上可以分為命令式、聲明式、動態式、函數式編程語言,體現的是提出問題、分析問題、描述問題和解決問題的思路的各個階段中編譯器所協助程序員完成的工作,這是另一種編程思想分類的體現。
5.1 命令式語言
傳統的命令式語言描述了執行的方式,而不是執行的內容。命令式語言從一開始就設計為提供機器碼的抽象級別。
命令式語言的語句主要是操作程序的狀態。面向對象的語言就是經典的狀態操作器,因為它們一直在創建和改變對象。VB、C、C++、C#都是命令式語言。
這些語言都非常擅長利用類型系統和對象描述現實世界中的情形。它們都非常嚴格-即編譯器要進行許多安全檢查。安全檢查(或類型合理性)表示,不能輕易地把Cow類型變成Sheep類型,所以如果在方法的簽名中聲明需要一個Cow類型,編譯器(和運行時)就要保證不會給方法傳送Sheep類型。這些語言通常有奇異的重用機制-用多態性原則編寫的代碼很容易抽象出來。這樣其他地方的代碼,從同一模塊到完全不同的項目,就可以利用已編寫好的代碼。
5.2 聲明式語言
聲明式語言描述了執行的內容,而不是執行方式(這與命令式語言相反,命令式語言描述了如何通過程序語句操作狀態)。為人所熟知的聲明式語言是HTML,它描述了頁面的布局、需要的字體、文本和修飾,以及在哪里顯示圖像。另一個經典的聲明式語言是SQL,它描述了要從關系數據庫提取的內容。最近的一個聲明式語言例子是XAML(eXtensible Application Markup Language),它引出了一大串基于XML的聲明式語言。
聲明式語言擅長描述和轉換數據。多年來,我們從命令式語言中調用它們來檢索和操作數據。
5.3 動態語言
動態語言包括具有“動態”特性的所有語言,如后期綁定和調用、REPL(Read Eval Print Loops)、鴨子類型化(不嚴格的類型化,即如果對象看起來像一只鴨子,行走起來也像一只鴨子,它就一定是一只鴨子)等。
動態語言一般會盡可能把編譯的操作推遲到運行時執行。
像這樣的方法編譯有一些有趣副作用。如果類型不需要事先完全定義(因為類型系統非常靈活),就可以編寫使用嚴格接口(例如,COM或者其他.NET程序集)代碼,使這些代碼在遇到該接口的失敗時有很大的靈活性。
動態語言非常適合于快速建立原型,不必事先定義類型,就可以把注意力集中在解決問題的代碼上,而不是集中在實現過程中的類型約束。REPL允許逐行編寫原型代碼,程序中的變化會立即反映出來,而不需要把時間浪費在編譯-運行-調試循環上。
Python語言是一個經典的動態語言,Ruby也是。
5.4 函數式語言
"函數式編程"屬于"結構化編程"的一種,主要思想是把運算過程盡量寫成一系列嵌套的函數調用。
函數式語言把計算看成數學函數,它們努力避免狀態操作,而主要考慮函數的結果,以此作為解決問題的基礎。如果你做過微積分,那么就會很熟悉函數式編程的理論。
因為函數式編程語言一般不操作狀態,所以程序中生成的副作用就小很多。這意味著這類語言一直在執行并行算法。高度并行系統的圣杯是避免重疊“無意中”的狀態操作。死鎖、竟態條件以及被破壞的不變量都是沒有同步狀態操作代碼的經典問題。通過線程、共享內存以及鎖來并行編程和同步都非常困難,所以為什么不一起避免?因為函數式編程語言鼓勵程序員編寫無狀態的算法,這樣編譯器就可以推斷出代碼的自行并行性。這意味著可以利用多核處理器的強大能力,而沒有管理線程、鎖和共享內存的巨大負擔。
函數式程序是很簡潔的,與命令式語言相比,函數式語言通常需要較少的代碼就可以解決問題。代碼較少一般意味著bug較少,要測試的區域也較少。
在語言中把每個類別的特性集混合起來是目前的一個趨勢,這對程序員有好處,程序員喜歡使用的語言常會從每個類別中選擇最佳特性。當前的趨勢是應用程序開發人員使用命令式/動態語言,而函數式語言擅長解決特定領域的問題。
和指令式編程相比,函數式編程強調函數的計算比指令的執行重要。
和過程化編程相比,函數式編程里函數的計算可隨時調用。
函數式編程中最古老的例子莫過于1958年被創造出來的LISP了,以及Haskell、Clean、Erlang和Miranda等。
-End-
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的天正建筑lisp编程接口_编程思想|面向过程的结构化、面向对象的抽象化、泛型编程...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关闭 启动_离心泵启动时为什么要关闭阀门
- 下一篇: 第三次握手为什么没有序列号_图解TCP三