c語言裏用結構體和指針函數實現面向對象思想

1、基礎研究

觀察以下兩個程序a.cb.cjava

A.c程序員

 

B.c算法

 

 

這兩個程序都是要實如今屏幕上第1040列打印一個綠色的字符c編程

 

這兩個程序的數據組織方式是同樣的,都是使用結構體,並且對共性和個性的分離的思路也是同樣的,都是將共性封裝在main函數裏,將個性實如今子函數裏。可是a.cb.c封裝和分離的角度是不同的,a.c沒有將字符和顏色的屬性賦值分離出來,而只是將顯示功能分離出來,b.c將字符、顏色的賦值和顯示功能都分離了出來,用三個子函數實現,並將相對應的函數指針封裝到結構體裏去。面向對象程序設計的一條基本原則是計算機程序是由單個可以起到子程序做用的單元或對象組合而成,也就是說咱們要儘可能把功能以子函數的形式實現。因此在這裏雖然ab的設計思想是相同的,可是b.c的封裝性要比a.c的封裝性更好。數組

再來看下一個程序:數據結構

 

如今要在?處添加語句,使程序可以實現功能。函數

這裏ch * a=new ch);的功能應該與ch a;相同,即定義一個struct c型的結構體變量a。可是咱們用ch a;是開闢了一個ch大小的空間並把它命名爲a,而這裏ch * a=?只是對一個指針進行了賦值,咱們通常對指針賦值只是把一個地址給它,並無開闢空間,可是咱們要實現ch a;的功能,必需要在這一句裏對該地址開闢空間。如今的問題就是:怎麼在給指針賦值時開闢內存空間?工具

咱們知道數組在定義時能夠開闢空間,可是數組定義須要單獨的一句,而這裏須要直接做爲右值使用,因此這裏須要動態地開闢空間。咱們最經常使用的動態內存分配方法就是使用malloc函數,這個函數有一個參數,是要開闢的空間字節數,在這裏咱們要開闢的空間大小是結構體a的大小,可是咱們不知道結構體a的大小,因此咱們要用sizeof得出它的大小。用malloc開闢空間後再將其轉換成結構體指針賦給a,程序以下:學習

 

咱們以前使用過宏定義,可是在程序中是宏名直接替換掉後面的東西的,而這裏宏有參數x,因此它是帶參宏定義,它的格式爲:#define 宏名(形參表字符串。這裏的x就是一個形參。因此咱們要在使用時在宏名後面傳入實參。spa

這裏的宏名是new,學過java咱們會發現java裏初始化對象也是使用new,這裏的new其實也是實現一個類似的功能。咱們能夠把結構體ch理解成一個類,用new對它進行實例化,這樣就能夠實現面向對象的程序設計思想。其實java裏實例化對象也是開闢一個內存空間並給這個空間取一個名字即對象名。結構體爲何能夠實現類的功能呢?咱們知道,類裏面能夠定義變量、數組、函數,並進行一些操做如賦值、調用函數之類的,只是在java中類裏面程序員不能定義和使用指針進行操做。而結構體裏面也能夠進行定義變量、數組、函數指針等的操做,因此若是咱們要用c語言編寫具備面向對象思想的程序,咱們能夠用結構體來實現相似「類」的功能,並用帶參宏定義來實現實例化的功能,或者能夠直接用malloc函數來實現實例化,只不過這樣語句比較重複。

雖然咱們能夠在c語言裏面用這種方法實現面向對象的程序設計,可是這樣畢竟不如用java之類的比較適合面向對象的語言來寫有面向對象思想的程序。由於java的類裏能夠進行賦值、調用函數等功能而c裏的結構體不能。java取消了程序員使用指針的權限,由於若是在這種高度封裝的語言裏使用指針極可能形成不少錯誤。

從這裏看,面向對象和麪向過程程序設計思想的區別在哪裏呢?面向對象的程序可能須要更多的封裝,它的每個對象都是爲執行特定的功能而封裝的,對象與對象之間相對比較獨立,關係清晰,便於程序的功能細化、管理維護,可是也會形成程序的代碼量增大。面向過程的程序封裝的主要是一些數據結構,一個函數、變量能夠被以多種角度來使用,這樣使程序變得十分精簡短小,可是不容易修改和補充。

咱們寫程序是用來解決問題的,並且要解決的是現實中的問題,因此咱們須要將現實問題轉化爲符號化的問題,而現實中的問題是由個體所組成的,因此咱們將數據和處理數據的方法封裝起來造成一個個體,這個個體在問題裏面有專門的功能,好比一張紙能夠摺疊,一支筆能夠寫,這樣有助於咱們以自身的角度進行思考分析,這就是面向對象。若是用面向過程的思路,會致使問題與程序之間的轉化很差處理,可能使解決問題出現誤差。

2、擴展研究

一、動態開闢內存空間的函數有哪些?

答:c語言有三個函數能夠動態開闢數組:malloc函數、calloc函數、realloc函數。

c語言提供了malloc函數和free函數用來執行動態內存分配和釋放,這些函數維護一個可用內存池,malloc函數能夠從內存池中提取一塊合適的內存,free函數用來釋放這塊內存以供別的程序使用。Malloc函數分配的是一塊連續的內存,返回值是一個指向被分配的內存塊起始位置的指針。Malloc實際分配的內存可能比你請求的的多一點,也可能不會,這是由編譯器決定的。可是malloc也可能分配失敗,若是操做系統沒法向malloc函數提供足夠的可用內存,那麼它會返回一個NULL指針。Malloc返回的指針類型爲void *型。Free的參數必需要麼是NULL,要麼是malloc函數、calloc函數、realloc函數返回的值。

Calloc函數的參數是所需元素的數量和每一個元素的字節數,而不是總的字節數。Calloc會把分配的內存都初始化爲0,而malloc不會初始化。

Realloc函數用於修改一個原先已分配的內存塊的大小,若是原先的內存塊大小沒法改變,那麼realloc會分配另外一塊正確大小的內存,並把原先那塊內存的內容複製到新的塊上。若是realloc的第一個參數爲NULL,那麼它的做用和malloc同樣。

3、研究總結

這一章裏咱們學習了動態分配內存的方法,以及怎麼使用宏定義,其實它們都是爲了更好地進行封裝。爲了對程序進行更好地封裝,人們使用了各類方式,甚至開發了封裝性更強的高級語言,這使咱們解決專門問題的能力更強了。這樣咱們編程只是將共性實現爲個性。由於語言只是工具,程序員應該更專一地研究算法而不是把時間花在語言上,因此如今的語言都是爲了簡化程序員的工做所形成的。

咱們封裝的過程,是對事物進行抽象的過程,也是對事物進行認識的過程,咱們從開始到如今,封裝的層次愈來愈深,處理的問題也愈來愈複雜。由於咱們須要理清複雜問題的內部規律,從而找出解決問題的辦法,而深層次的封裝使問題恢復成原本的樣子就是一種解決辦法,當封裝的程度達到了必定的水平,就是面向對象的程序設計思想。

相關文章
相關標籤/搜索