位元詩人 [Objective-C] 程式設計教學:Objective-C 和 C 語言的異同

Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

前言

扣掉 GNUstep 這種寫興趣的小眾平台外,Objective-C 在實務上就是用來寫 iOS 和 Mac 應用程式的程式語言,不太適合做為通用型語言來學。如果讀者真的是程式設計的新手,建議先學過一門通用型程式語言後再來學 Objective-C。

除了學習程式設計的共通概念外,我們建議還沒學過 C 語言的讀者先學完 C 之後再來學 Objective-C。因為 Objective-C 是 C 的嚴格超集,學 C 比學 C++、Java 或其他程式語言對 Objective-C 更有直接助益。

在本文中,我們假定讀者已經看過 C 的基本語法,會以比較的方式來介紹 Objective-C 的特性。如果讀者還沒學 C,可以看一下筆者寫的教學文件,或者自己找尋其他的教材。

變數 (Variable) 和資料型別 (Data Type)

Objective-C 沿用 C 語言的變數命名和宣告規則,原有的觀念可繼續使用。但 Objective-C 引入新的型別,像是 Objective-C 自訂的 BOOL 型別或是代表任意 Objective-C 物件的 id 型別。此外,Cocoa 或 GNUstep 引入了一整套的物件庫,這些物件可視為新的型別。

比起 C 標準函式庫,Cocoa 或 GNUstep 的物件庫更為龐大,我們可藉由這些現成的物件節省程式人的時間。

我們在這篇文章介紹 C 語言的變數,另外在這篇文章介紹 Objective-C 的資料型別,有興趣的讀者可參考一下。

運算子 (Operator)

Objective-C 沒有引入新的運算子,沿用原本 C 語言的概念即可。我們在這裡介紹 C 的運算子,有興趣的讀者可以看一下。

控制流程 (Control Flow)

控制流程用來改變指令執行的順序。分別選擇結構 (selection structure) 和迭代結構 (iteration structure) 兩種。C 語言沒有引入新的選擇結構,原來的 ifswitch 敘述可繼續使用。但 Objective-C 則在原有的 while 迴圈及 for 迴圈外引入新的迭代結構。像是用於迭代器的 for ... in ... 迴圈。

我們在這裡介紹 C 的控制流程。由於 Objective-C 大部分的控制流程是沿用 C 的,仍具有參考價值。

指標 (Pointer) 和記憶體管理 (Memory Management)

雖然 Objective-C 沿用 C 語言的指標和記憶體管理函式庫,但 Objective-C 的物件有自己的記憶體管理模式,故不建議繼續使用 C 語言的記憶體管理模式。

隨著編譯 Objective-C 程式碼所用的編譯器不同,會支援不同的記憶體管理方式。蘋果在新版的 Clang 加入了新的記憶體管理方式,但 GCC 沒有跟上來。如果很在意編譯器間的相容性的話,就得刻意使用舊式的記憶體管理方式。

容器 (Collections)

C 語言唯一的內建容器是陣列 (array)。Objective-C 除了繼續沿用 C 陣列外,Cocoa 或 GNUstep 也提供 NSArray 物件。

除了陣列外,Cocoa 或 GNUstep 提供數種容器,像是代表集合的 NSSet 物件,相當於映射或字典的 NSDictionary 物件等。所以寫 Objective-C 時會比寫純 C 輕鬆一些。

如果仍想用 C 陣列的話,可參考這篇文章

字串 (String)

C 語言並沒有真正的字串型態,使用以零結尾的字元陣列來儲存字串。相對來說,Cocoa 或 GNUstep 提供 NSString 物件。

如果為了相容性等因素需要使用 C 字串,可參考這篇文章

結構體 (Structure) 和聯合體 (Union)

結構體和聯合體是兩種 C 語言的複合型別,主要用來宣告新的型別。在撰寫純 C 程式時,使用結構體模擬物件導向程式的 this 指針在函式間傳遞是相當常見的手法。但 Objective-C 有真正的物件系統,故不建議再採用這種手法。

對於 Objective-C 程式來說,保留結構體和聯合體的主要意義在於相容現有的 C 程式碼。

函式 (Function)

由於 Objective-C 程式是以操作物件為主,我們在撰寫 Objective-C 程式時多會以撰寫類別為主。C 函式多用於撰寫和物件關係不大的工具函式 (utility function)。讀者可到這裡看一下 C 函式的寫法。

類別 (Class) 和物件 (Object)

在寫純 C 程式時,我們只能用結構體等複合型別去模擬類別和物件,但結構體並非真正的類別或物件。相對來說,Objective-C 建立一整套源自 SmallTalk 的物件系統,這也是 Objective-C 的主要特色。

在這篇介紹性質的文章當然無法詳述 Objective-C 的物件系統,我們會在後面的文章中陸續介紹。

巨集 (Macro)

除了沿用 C 原本的巨集語法外,Objective-C 加入一些新的語法,像是用來引入函式庫的 #import 等。

我們在這篇文章介紹 C 巨集。由於 Objective-C 大部分的巨集語法是沿用 C 的,該文章仍具有一定參考價值。

函式庫 (Library)

Objective-C 的函式庫和 C 相仿,由標頭檔及二進位檔組成。但 Objective-C 的標頭檔含 Objective-C 特有的語法,像是物件的公開界面,所以 Objective-C 的函式庫無法給 C 使用。

在類 Unix 系統上,函式庫有特定的擺放位置,像是存放標頭檔的 /usr/include 目錄及存放二進位檔的 /usr/lib 目錄等。由於 Objective-C 在非 Apple 平台算是小眾語言,系統上真正存在的 Objective-C 函式庫甚少。

Apple 平台使用 framework 做為包裝函式庫的格式。注意這裡的 framework 並非我們在程式設計中會提到的軟體框架。Apple 的 framework 不限於包裝標頭檔和靜態二進位檔,還可以放入其他的系統資源。如果只在 Apple 生態圈上寫 Objective-C 程式,倒是可以學一下 framework 的使用和建立方式。

模組 (Module) 或套件 (Package)

模組或套件這兩個詞在程式設計中常交互使用,用來指稱可重覆使用、可分享的程式碼區塊。此外,模組或套件可透過套件管理程式自動地安裝、移除、處理相依性等。套件不一定是函式庫,也有可能是應用程式。

Objective-C 和 C 皆為有函式庫但沒有套件的語言。我們在類 Unix 系統上用來安裝 C 函式庫的套件是來自系統的功能,非 C 本身的特性。至於 Objective-C 相對小眾,在非 Apple 平台上,除了 GNUstep 和 ObjFW 外,幾乎沒有什麼可用的套件。

若要在非 Apple 平台上用 Objective-C,如果有在用 GNUstep,該專案所附的 GNUstep Make 勉強可當成套件管理軟體來用。除此之外就沒有可用的 Objective-C 套件格式。

在 Apple 平台上則有兩個社群發起的套件管理軟體,比較老牌的是 CocoaPods,而 Carthage 則是後起之秀。兩者除了套件格式相異外,前者以集中套件庫的方式來管理套件,後者則採分散式管理。由於 CocoaPods 起步較早,支援 CocoaPods 的 Objective-C 套件比較多一些。

結語

在本文中,我們用比較快的步調介紹 Objective-C 和 C 的異同。由於本文算是簡介,只看本文當然還不會寫 Objective-C 程式。我們會在後續的文章介紹 Objective-C 特有的特性。至於和 C 重疊的部分就不會重寫,請讀者自行觀看本網站有關 C 的部分,或是自行找尋其他的教材。

關於作者

身為資訊領域碩士,位元詩人 (ByteBard) 認為開發應用程式的目的是為社會帶來價值。如果在這個過程中該軟體能成為永續經營的項目,那就是開發者和使用者雙贏的局面。

位元詩人喜歡用開源技術來解決各式各樣的問題,但必要時對專有技術也不排斥。閒暇之餘,位元詩人將所學寫成文章,放在這個網站上和大家分享。