謝謝邀請。

其實,「面向過程」和「面向對象」只是程序開發中的一種方法,或者說一種思想,大多數現代高級編程語言都能使用這兩種編程思想,C語言當然也不例外。

只不過,有些編程語言在語法上支持「對象」,而C語言則沒有原生的「對象」語法。不過藉助於靈活的指針和結構體語法,在C語言程序開發中使用「面向對象」思想也是很簡單的。

malloc() 和 free() 函數

鑒於題主可能是C語言初學者,在開始討論如何使用C語言進行「面向對象」開發之前,先介紹兩個新函數——malloc() 和 free() 。

如果題主看過我之前文章的話,應該明白C語言程序每調用一次函數,系統就會在棧中分配一塊棧幀給被調用函數,當函數執行完畢後,這部分棧幀就自動被系統收回了。

malloc() 函數的作用是申請一塊指定大小的內存,它的C語言原型如下,成功時返回這塊內存的首地址,失敗時返回 NULL。

C語言程序中函數的局部變數佔用的內存,是函數運行時,自動在其所屬棧幀中分配的,所以局部變數會隨著函數結束釋放。不過,malloc() 向系統申請的內存在堆區裏,這部分內存不會隨著函數的退出自動釋放,需要程序員自己使用 free() 函數釋放:

以上這幾行C語言代碼的意思是向系統申請 5 位元組的內存,如果申請成功,就把它釋放。

如果在C語言程序退出之前,只 malloc() 而不 free(),程序佔用的內存會越來越多,直到最後崩潰退出。這種情況,程序員習慣稱為「內存泄漏」。

使用C語言進行「面向對象」編程

相當一部分程序員看不起C語言是因為他們覺得C語言沒有「對象」。現在,我們嘗試給C語言找一個「對象」。請看:

因為C語言不支持原生的「類」語法,所以我們使用結構體模擬了一個 class,定義了一個「FATHER 類」,它有成員函數 hello()。

上述C語言代碼又定義了一個「SON 類」,它有成員函數 hello(),也有成員變數 count(),還有一個「父類」father。接下來,定義「FATHER類」和「SON類」的 hello 函數,相關C語言代碼如下:

如何讓這兩個函數與我們定義的「類」產生聯繫呢?我們定義「構造函數」:

上述C語言代碼首先使用 malloc() 為 son 在堆中申請一塊內存,這保證了 son 在程序結束之前都不會被釋放。同樣的,為 father 也申請了一塊內存。

接著,把它們各自的函數傳遞給結構體裡面定義的函數指針,這樣便定義好了「類」son。有了構造函數,再來定義「析構函數」,相關C語言代碼如下:

析構函數的主要作用就是釋放 malloc() 的內存,防止內存泄漏。至此,我們就使用C語言實現了「類」的封裝,測試一下:

上述C語言代碼是典型的「面向對象」風格:程序使用 SON 類實例化了一個 son 對象,son 調用了自己的成員函數,也調用了從「父類」繼承而來的函數。編譯並執行這段C語言代碼,發現輸出與預期一致。

應該注意的是,從表達式 son->hello(son) 可以看出,C語言沒有類的支持,所以需要顯式的把 son 指針傳給 hello。但是,「father類」和「son類」裏都可以使用 hello 做函數名,這說明C語言的「類」也對封裝有很好的效果。

歡迎在評論區一起討論,質疑。文章都是手打原創,每天最淺顯的介紹C語言、linux等嵌入式開發,喜歡我的文章就關注一波吧,可以看到最新更新和之前的文章哦。


可以在一定程度上模擬,但不完全,比如不能繼承。在封裝上可以的,不過在大多數情況下,面向對象主要也是用封裝的居多。


沒class語句,可以用struct語句定義個類,然後用指向函數的指針方式定義類成員函數。

但是玩繼承、多態、重載、公共私有等方面就不行了。


C是面向過程的,在語言這一層面上並沒有支持類和對象的概念,C++才支持的。但是,面向對象,本質上是一種編程和設計的思想。即使用純C,仍然不妨礙人應用面向對象的編程思想。倘若研究過Linux的源代碼就應該有點印象,它是純C寫的,但是裡面很多函數指針,本質上是模塊之間互相松耦合,體現的就是面向對象的設計思想。


完全可以。準確的說,C語言是被設計成面向過程的語言。但不影響你用什麼思想來運用它。就像高跟鞋最初是被設計成男人穿的鞋,但不影響女人穿它一樣!


c語言最多隻能模擬一個類似,類的東西只有不完整的形,沒有最重要的神,正真類的繼承,派生等特性能是怎麼也無法模擬的。


可以。面向對象是設計思想,語言本身不存在面向過程和麪向對象,只是說c++的多態、繼承等特性更容易實現面向對象的設計思想。


當然可以,面向對象只是一種編程的思想而已.c這種底層語言當然可以用。


當然可以 整個c++面向對象的功能可以用c實現


你老師收了學費不教你怎麼用c面向對象?那先問老師討回學費啊


推薦閱讀:
相關文章