1. <dd id="erndk"></dd>
                1. Swift和C語言混合編程教程

                  2019/7/9 22:22:23

                  這篇文章主要介紹了Swift和C語言混合編程教程,介紹基本數據類型對比、指針、常量等內容,需要的朋友可以參考下

                  作為一種可與 Objective-C 相互調用的語言,Swift 也具有一些與 C 語言的類型和特性,如果你的代碼有需要,Swift 也提供了和常見的 C 代碼結構混合編程的編程方式。

                  基本數據類型

                  Swift 提供了一些和 C 語言的基本類型如char,int,float,double等價的 Swift 基本數據類型。然而,這些 Swift 的核心基本類型之間并不能隱式的相互轉換,如 Int。因此,只有你的代碼明確要求它們時再使用這些類型,而 Int 可以在任何你想使用它的時候使用。


                  C 類型Swift 類型
                  boolCBool
                  char, signed charCChar
                  unsigned charCUnsignedChar
                  shortCShort
                  unsigned shortCUnsignedShort
                  intCInt
                  unsigned intCUnsignedInt
                  longCLong
                  unsigned longCUnsignedLong
                  long longCLongLong
                  unsigned long longCUnsignedLongLong
                  wchar_tCWideChar
                  char16_tCChar16
                  char32_tCChar32
                  floatCFloat
                  doubleCDouble

                  枚舉

                  Swift 引進了用宏NS_ENUM來標記的任何 C 風格的枚舉類型。這意味著無論枚舉值是在系統框架還是在自定義的代碼中定義的,當他們導入到 Swift 時,他們的前綴名稱將被截斷。例如,看這個 Objective-C 枚舉:

                  復制代碼 代碼如下:

                  //Objective-C
                  typedef NS_ENUM(NSInteger, UITableViewCellStyle) {
                      UITableViewCellStyleDefault,
                      UITableViewCellStyleValue1,
                      UITableViewCellStyleValue2,
                      UITableViewCellStyleSubtitle
                  };

                  在 Swift 中這樣來實現:
                  復制代碼 代碼如下:

                  //Swift
                  enum UITableViewCellStyle: Int {
                      case Default
                      case Value1
                      case Value2
                      case Subtitle
                  }

                  當您需要指向一個枚舉值時,使用以點(.)開頭的枚舉名稱:


                  復制代碼 代碼如下:

                  //Swift
                  let cellStyle: UITableViewCellStyle = .Default

                  Swift 也引進了標有NS_OPTIONS宏選項。而選項的行為類似于引進的枚舉,選項還可以支持一些位操作,如 &,| 和 ~。在 Objective-C 中,你用一個空的選項設置標示恒為零(0)。在 Swift 中,使用 nil代表沒有任何選項。

                  指針

                  Swift 盡可能避免讓您直接訪問指針。然而,當您需要直接操作內存的時候,Swift 也為您提供了多種指針類型。下面的表使用 Type 作為占位符類型名稱來表示語法的映射。
                  對于參數,使用以下映射:


                  C 句法Swift 句法
                  const void *CConstVoidPointer
                  void *CMutableVoidPointer
                  const Type *CConstPointer<Type>
                  Type *CMutablePointer<Type>


                  對于返回類型,變量和參數類型的多層次指針,使用以下映射:


                  C 句法Swift 句法
                  void *COpaquePointer
                  Type *UnsafePointer<Type>


                  對于類(class)類型,使用以下映射:


                  C 句法Swift 句法
                  Type * const *CConstPointer<Type>
                  Type * __strong *CMutablePointer<Type>
                  Type **AutoreleasingUnsafePointer<Type>

                  C 可變指針

                  當一個函數被聲明為接受CMutablePointer<Type>參數時,這個函數可以接受下列任何一個類型作為參數:

                  ?nil,作為空指針傳入
                  ?一個CMutablePointer<Type>類型的值
                  ?一個操作數是 Type 類型的左值的輸入輸出表達式,作為這個左值的內存地址傳入
                  ?一個輸入輸出 Type[] 值,作為一個數組的起始指針傳入,并且它的生命周期將在這個調用期間被延長

                  如果您像這樣聲明了一個函數:


                  復制代碼 代碼如下:

                  //Swift
                  func takesAMutablePointer(x: CMutablePointer<Float>) { /*...*/ }

                  那么您可以使用以下任何一種方式來調用這個函數:

                  復制代碼 代碼如下:

                  //Swift
                  var x: Float = 0.0
                  var p: CMutablePointer<Float> = nil
                  var a: Float[] = [1.0, 2.0, 3.0]

                  takesAMutablePointer(nil)
                  takesAMutablePointer(p)
                  takesAMutablePointer(&x)
                  takesAMutablePointer(&a)

                  當函數被聲明使用一個CMutableVoidPointer參數,那么這個函數接受任何和CMutablePointer<Type>相似類型的Type操作數。

                  如果您這樣定義了一個函數:


                  復制代碼 代碼如下:

                  //Swift
                  func takesAMutableVoidPointer(x: CMutableVoidPointer) { /* ... */ }

                  那么您可以使用以下任何一種方式來調用這個函數:

                  復制代碼 代碼如下:
                  //Swift
                  var x: Float = 0.0, y: Int = 0
                  var p: CMutablePointer<Float> = nil, q: CMutablePointer<Int> = nil
                  var a: Float[] = [1.0, 2.0, 3.0], b: Int = [1, 2, 3]

                  takesAMutableVoidPointer(nil)
                  takesAMutableVoidPointer(p)
                  takesAMutableVoidPointer(q)
                  takesAMutableVoidPointer(&x)
                  takesAMutableVoidPointer(&y)
                  takesAMutableVoidPointer(&a)
                  takesAMutableVoidPointer(&b)

                  C 常指針

                  當一個函數被聲明為接受CConstPointer<Type>參數時,這個函數可以接受下列任何一個類型作為參數:

                  ?nil,作為空指針傳入
                  ?一個CMutablePointer<Type>, CMutableVoidPointer, CConstPointer<Type>, CConstVoidPointer, 或者在必要情況下轉換成CConstPointer<Type>的AutoreleasingUnsafePointer<Type>值
                  ?一個操作數是 Type 類型的左值的輸入輸出表達式,作為這個左值的內存地址傳入
                  ?一個Type[]數組值,作為一個數組的起始指針傳入,并且它的生命周期將在這個調用期間被延長

                  復制代碼 代碼如下:

                  //Swift
                  func takesAConstPointer(x: CConstPointer<Float>) { /*...*/ }

                  那么您可以使用以下任何一種方式來調用這個函數:

                  復制代碼 代碼如下:

                  //Swift
                  var x: Float = 0.0
                  var p: CConstPointer<Float> = nil

                  takesAConstPointer(nil)
                  takesAConstPointer(p)
                  takesAConstPointer(&x)
                  takesAConstPointer([1.0, 2.0, 3.0])

                  當函數被聲明使用一個CConstVoidPointer參數,那么這個函數接受任何和CConstPointer<Type> 相似類型的Type操作數。 ? 如果您這樣定義了一個函數:


                  復制代碼 代碼如下:

                  //Swift ???
                  func takesAConstVoidPointer(x: CConstVoidPointer) { /* ... */ }

                  那么您可以使用以下任何一種方式來調用這個函數:


                  復制代碼 代碼如下:

                  //Swift
                  var x: Float = 0.0, y: Int = 0
                  var p: CConstPointer<Float> = nil, q: CConstPointer<Int> = nil

                  takesAConstVoidPointer(nil)
                  takesAConstVoidPointer(p)
                  takesAConstVoidPointer(q)
                  takesAConstVoidPointer(&x)
                  takesAConstVoidPointer(&y)
                  takesAConstVoidPointer([1.0, 2.0, 3.0])
                  takesAConstVoidPointer([1, 2, 3])

                  自動釋放不安全指針

                  當一個函數被聲明為接受AutoreleasingUnsafePointer<Type>參數時,這個函數可以接受下列任何一個類型作為參數:

                  ?nil,作為空指針傳入
                  ?一個AutoreleasingUnsafePointer<Type>值
                  ?其操作數是原始的,復制到一個臨時的沒有所有者的緩沖區的一個輸入輸出表達式,該緩沖區的地址傳遞給調用,并返回時,緩沖區中的值加載,保存,并重新分配到操作數。

                  注意:這個列表沒有包含數組。

                  如果您這樣定義了一個函數:


                  復制代碼 代碼如下:

                  //Swift
                  func takesAnAutoreleasingPointer(x: AutoreleasingUnsafePointer<NSDate?>) { /* ... */ }


                  那么您可以使用以下任何一種方式來調用這個函數:

                  復制代碼 代碼如下:

                  //Swift
                  var x: NSDate? = nil
                  var p: AutoreleasingUnsafePointer<NSDate?> = nil
                  ?????
                  takesAnAutoreleasingPointer(nil)
                  takesAnAutoreleasingPointer(p)
                  takesAnAutoreleasingPointer(&x)

                  注意:C 語言函數指針沒有被 Swift 引進。

                  全局常量

                  在 C 和 Objective-C 語言源文件中定義的全局常量會自動地被 Swift 編譯引進并做為 Swift 的全局常量。

                  預處理指令

                  Swift 編譯器不包含預處理器。取而代之的是,它充分利用了編譯時屬性,生成配置,和語言特性來完成相同的功能。因此,Swift 沒有引進預處理指令。

                  簡單宏

                  在 C 和 Objective-C,您通常使用的#define指令定義的一個宏常數,在 Swift,您可以使用全局常量來代替。例如:一個全局定義#define FADE_ANIMATION_DURATION 0.35,在 Swift 可以使用let FADE_ANIMATION_DURATION = 0.35來更好的表述。由于簡單的用于定義常量的宏會被直接被映射成 Swift 全局量,Swift 編譯器會自動引進在 C 或 Objective-C 源文件中定義的簡單宏。

                  復雜宏

                  在 C 和 Objective-C 中使用的復雜宏在 Swift 中并沒有與之對應的定義。復雜宏是那些不用來定義常量的宏,而是用來定義包含小括號(),函數的宏。您在 C 和 Objective-C 使用復雜的宏是用來避免類型檢查的限制和相同代碼的重復勞動。然而,宏也會產生Bug和重構的困難。在 Swift 中你可以直接使用函數和泛型來達到同樣的效果。因此,在 C 和 Objective-C 源文件中定義的復雜宏在 Swift 是不能使用的。

                  編譯配置

                  Swift 代碼和 Objective-C 代碼以不同的方式進行條件編譯。Swift 代碼可以根據生成配置的評價配進行有條件的編譯。生成配置包括 true 和 false 字面值,命令行標志,和下表中的平臺測試函數。您可以使用-D <#Flag#>指定命令行標志。


                  函數有效參數
                  os()OSX, iOS
                  arch()x86_64, arm, arm64, i386

                  注意:arch(arm) 的生成配置不會為64位 arm 設備返回true,當代碼運行在為32位的 ios 模擬器器時,arch(i386) 的生成配置返回true。

                  一個簡單的條件編譯需要以下代碼格式:


                  復制代碼 代碼如下:

                  #if build configuration
                      statements
                  #else
                      statements
                  #endif

                  一個由零個或多個有效的 Swift 語句聲明的statements,可以包括表達式,語句和控制流語句。您可以添加額外的構建配置要求,條件編譯說明用 && 和 | | 操作符以及 ! 操作符,添加條件控制塊用 #elseif:

                  復制代碼 代碼如下:

                  #if build configuration && !build configuration
                      statements
                  #elseif build configuration
                      statements
                  #else
                      statements
                  #endif

                  與 C 語言編譯器的條件編譯相反,Swift 條件編譯語句必須完全是自包含和語法有效的代碼塊。這是因為 Swift 代碼即使沒有被編譯,也要全部進行語法檢查。

                  隨時隨地學軟件編程-關注百度小程序和微信小程序
                  關于找一找教程網

                  本站文章僅代表作者觀點,不代表本站立場,所有文章非營利性免費分享。
                  本站提供了軟件編程、網站開發技術、服務器運維、人工智能等等IT技術文章,希望廣大程序員努力學習,讓我們用科技改變世界。
                  [Swift和C語言混合編程教程]http://www.yachtsalesaustralia.com/tech/detail-64261.html

                  贊(0)
                  關注微信小程序
                  程序員編程王-隨時隨地學編程

                  掃描二維碼或查找【程序員編程王】

                  可以隨時隨地學編程啦!

                  技術文章導航 更多>
                  国产在线拍揄自揄视频菠萝

                        1. <dd id="erndk"></dd>