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**
引數來儲存可能的錯誤的資訊。舉例來說:我們用nsfilemanager
的contentofdirectoryatpath(_: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
方法讓兩個陣列a
和b
相加,並將結果寫入第三個陣列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...