iT邦幫忙

2021 iThome 鐵人賽

DAY 5
0
自我挑戰組

iOS 菜鳥工程師的30天 objective-C系列 第 10

Day 10 - Pointer(指標)

Objective-C中的變數分為儲存基本資料型態的數值(value)以及指標(pointer)

Pointer 其實就是一個變數而其值代表數值的位置,有點類似地址的概念。要想取得指標可以使用符號(&),它表示內存中的地址訪問。

ex.

int a = 10;
NSLog(@"a的值:%i",a);
NSLog(@"a的pointer: %p",&a);

結果:

2021-10-01 17:13:41.847800+0800 TestOC[33699:577420] a的值:10
2021-10-01 17:13:41.847858+0800 TestOC[33699:577420] a的pointer: 0x16d847fcc

Pointer本身是一個characters字串的記憶體位置,ex. 0x16b1bffcc,也就是不管 Pointer 指向的 object 多大,Pointer 的大小都是固定的,大大節省記憶體空間。

聲明形式

用來聲明指針的是 星號(*)

type *var-name;

ex.

int a = 20;
int *ip;
    
ip = &a;
    
NSLog(@"a的pointer: %p",&a);
    
NSLog(@"儲存ip值的地址: %p",ip);
    
NSLog(@"*ip的value值: %d",*ip);

結果:

2021-10-01 17:24:11.709216+0800 TestOC[33825:583275] a的pointer: 0x16d717fcc
2021-10-01 17:24:11.709264+0800 TestOC[33825:583275] 儲存ip值的地址: 0x16d717fcc
2021-10-01 17:24:11.709299+0800 TestOC[33825:583275] *ip2的value值: 20

我們嘗試把一個值傳入方法,然後修改其值,返回後再傳回原本的值,來比較看看他們的差異。

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    int i = 5;
    NSLog(@"i address is %p",&i);
    i = [self addOne:i];
    NSLog(@"i address is %p",&i);
}


- (int) addOne: (int) x {
    x += 1;
    NSLog(@"x is %i",x);
    NSLog(@"x address is %p",&x);
    return x;
}
2021-10-01 17:27:12.611427+0800 TestOC[33861:585111] i address is 0x16d6f7fcc
2021-10-01 17:27:12.611473+0800 TestOC[33861:585111] x is 6
2021-10-01 17:27:12.611500+0800 TestOC[33861:585111] x address is 0x16d6f7f8c
2021-10-01 17:27:12.611532+0800 TestOC[33861:585111] i address is 0x16d6f7fcc

可以發現到 x 與 i 的位置不同,這代表 x又多開了一個記憶體位置

如果不傳入"值",改成 pointer 的話

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    int i = 5;
    NSLog(@"i address is %p",&i);
    i = [self addOne:&i];
    NSLog(@"i address is %p",&i);
}


- (int) addOne: (int *) x {
    *x += 1;
    NSLog(@"x is %i",*x);
    NSLog(@"x address is %p",x);
    return *x;
}

結果:

21-10-01 17:35:31.573388+0800 TestOC[34045:590438] i address is 0x16b27ffcc
2021-10-01 17:35:31.573437+0800 TestOC[34045:590438] x is 6
2021-10-01 17:35:31.573474+0800 TestOC[34045:590438] x address is 0x16b27ffcc
2021-10-01 17:35:31.573506+0800 TestOC[34045:590438] i address is 0x16b27ffcc

可以發現記憶體位置都相同,指標都指向同一個位置


討論

總結下來

int ip
int *ip

兩種的差異感覺像是value typereference type的差別,使用指針帶入其他參數中,從頭到尾修改的值都是在同一個完成(前面的例子,x 跟 i 的位置都一樣,沒有生成新的值)


參考資料

https://codebbkaf.blogspot.com/2017/07/objective-c-pointer.html
http://tw.gitbook.net/objective_c/objective_c_pointers.html


上一篇
Day 09 - Array
系列文
iOS 菜鳥工程師的30天 objective-C10

尚未有邦友留言

立即登入留言