Swift Swift與C語言指標友好合作

2021-07-14 02:49:40 字數 2166 閱讀 7337

objective-c和c的api常常會需要用到指標。swift中的資料型別都原生支援基於指標的cocoa api,不僅如此,swift會自動處理部分最常用的將指標作為引數傳遞的情況。這篇文章中,我們將著眼於在swift中讓c語言指標與變數、陣列和字串共同工作。

用以輸入/輸出的引數指標

c和objective-c並不支援多返回值,所以cocoa api中常常將指標作為一種在方法間傳遞額外資料的方式。swift允許指標被當作inout引數使用,所以你可以用符號&將對乙個變數的引用作為指標引數傳遞。舉例來說:uicolor中的getred(_:green:blue:alpha:)方法需要四個cgfloat*指標來接收顏色的組成資訊,我們使用&來將這些組成資訊捕獲為本地變數:

var r: cgfloat = 0, g: cgfloat = 0, b: cgfloat = 0, a: cgfloat = 0

color.getred(&r, green: &g, blue: &b, alpha: &a)

另一種常見的情況是cocoa中nserror的習慣用法。許多方法會使用乙個nserror**引數來儲存可能的錯誤的資訊。舉例來說:我們用nsfilemanagercontentofdirectoryatpath(_:error:)方法來將目錄下的內容列表,並將潛在的錯誤指向乙個nserror?變數:

var maybeerror: nserror?

iflet contents = nsfilemanager.defaultmanager()

.contentsofdirectoryatpath("/usr/bin", error: &maybeerror) else

iflet error = maybeerror

為了安全性,swift要求被使用&傳遞的變數已經初始化。因為無法確定這個方法會不會在寫入資料前嘗試從指標中讀取資料。

作為陣列使用的引數指標

在c語言中,陣列和指標的聯絡十分緊密,而swift允許陣列能夠作為指標使用,從而與基於陣列的c語言api協同工作更加簡單。乙個固定的陣列可以使用乙個常量指標直接傳遞,乙個變化的陣列可以用&運算子將乙個非常量指標傳遞。就和輸入/輸出引數指標一樣。舉例來說:我們可以用accelerate框架中的vdsp_vadd方法讓兩個陣列ab相加,並將結果寫入第三個陣列result

import accelerate

let a: [float] = [1, 2, 3, 4]

let b: [float] = [0.5, 0.25, 0.125, 0.0625]

var result: [float] = [0, 0, 0, 0]

vdsp_vadd(a, 1, b, 1, &result, 1, 4)

// result now contains [1.5, 2.25, 3.125, 4.0625]

c語言中用cont char*指標來作為傳遞字串的基本方式。swift中的string可以被當作乙個無限長度utf-8編碼的const char*指標來傳遞給方法。舉例來說:我們可以直接傳遞乙個字串給乙個標準c和posix庫方法

puts("hello from libc")

let fd = open("/tmp/scratch.txt", o_wronly|o_creat, 0o666)

if fd < 0 else

swift很努力地使與c語言指標的互動更加便利,因為它們廣泛地存在於cocoa之中,同時保持一定的安全性。然而,相比你的其他swift**與c語言的指標互動具有潛在的不安全性,所以務必要小心使用。其中特別要注意:

如果你需要使用基於指標的api時沒有遵守以上指導,或是你重寫了接受指標引數的cocoa方法,於是你可以在swift中直接用不安全的指標來使用未經處理的記憶體。在未來的文章中我們將著眼於更加高階的情況。

C語言(九) 指標(3)指標與const

表示一旦得到了某個變數的位址,不能再指向其他變數 int i 0 int const q i q是 const q 20 ok q error表示不能通過指標去修改這個變數 int i 0 int j const int p i const int p 等同於 int const p p 20 er...

c語言與指標 (一)指標與變數

寫在前面 指標是學習c語言時,最讓人頭痛的乙個難題。但是指標不僅是c語言的精髓,它還貫穿整個計算機底層儲存與訪問方式。指標實際上就是位址,指標變數用來存放指標 位址 指標變數也是一種變數,它和不同的變數同樣要佔一定的儲存空間。但指標變數與不同的變數不同之處在於,指標的儲存空間存放的不是不同的資料,而...

每天學點C語言 4 指標與函式

玩指標,玩指標,玩指標,玩指標,玩指標,玩指標。然後就被指標玩了 引數傳遞到函式裡作為區域性變數,其改變一般並不會影響到原本的資料,因為實際上操作的是原資料的副本,而讓指標作為引數傳入函式,可以直接操作原資料,如下 include include mm.c include swap.c void s...