C in ObjC系列(3) 陣列與指標

C in ObjC系列(3) 陣列與指標

C in ObjC系列為Objective-C中保留C語言語法的系列介紹。

陣列

陣列有個非常容易使用的索引值方式取得內容,利用此特性來完成連續性的動作時就能用迴圈與索引值來完成,一般程式語言都能接受1維、2維這兩種維度的陣列,3維就必需注意看看程式語言的編譯器是否能支援了。

1維陣列

//-----------start-----------
    NSInteger integer_array[4];
    integer_array [0] = 0;
    integer_array [1] = 1;
    integer_array [2] = 2;
    integer_array [3] = 3;
    NSLog(@"integer_array");
    for (NSInteger m = 3; m >= 0; m --) {
        NSLog(@"%ld",integer_array[m]);
    }
//------------end------------

輸出結果:

2014-08-17 20:19:38.114 LoopDemo[68436:303] integer_array
2014-08-17 20:19:38.115 LoopDemo[68436:303] 3
2014-08-17 20:19:38.115 LoopDemo[68436:303] 2
2014-08-17 20:19:38.115 LoopDemo[68436:303] 1
2014-08-17 20:19:38.115 LoopDemo[68436:303] 0

//-----------start-----------
    NSInteger integer_array1[] = {0,1,2,3};

    NSLog(@"integer_array1");
    for (NSInteger m = 3; m >= 0; m --) {
        NSLog(@"%ld",integer_array1[m]);
    }
//------------end------------

輸出結果:

2014-08-17 20:19:38.116 LoopDemo[68436:303] integer_array1
2014-08-17 20:19:38.116 LoopDemo[68436:303] 3
2014-08-17 20:19:38.117 LoopDemo[68436:303] 2
2014-08-17 20:19:38.117 LoopDemo[68436:303] 1
2014-08-17 20:19:38.117 LoopDemo[68436:303] 0

2維陣列

2維陣列最常被使用在棋盤式的查表座標,例如:(3,2),陣列中就會以變數名[3][2](假定座標從0開始,索引值從0開始)。

//-----------start-----------
    NSInteger integer_2_dim_array[4][4] = {
        {0,0,0,0},
        {1,1,1,1},
        {2,2,2,2},
        {3,3,3,3}
    };

    for (NSInteger m = 3; m >= 0; m --) {
        for (NSInteger n = 3; n >= 0; n --) {
            NSLog(@"row:%ld column:%ld value %ld",m,n,integer_2_dim_array[m][n]);
        }
    }
//------------end------------

輸出結果:

2014-08-17 22:58:49.008 LoopDemo[70342:303] row:3 column:3 value 3
2014-08-17 22:58:49.009 LoopDemo[70342:303] row:3 column:2 value 3
2014-08-17 22:58:49.010 LoopDemo[70342:303] row:3 column:1 value 3
2014-08-17 22:58:49.010 LoopDemo[70342:303] row:3 column:0 value 3
2014-08-17 22:58:49.010 LoopDemo[70342:303] row:2 column:3 value 2
2014-08-17 22:58:49.011 LoopDemo[70342:303] row:2 column:2 value 2
2014-08-17 22:58:49.011 LoopDemo[70342:303] row:2 column:1 value 2
2014-08-17 22:58:49.011 LoopDemo[70342:303] row:2 column:0 value 2
2014-08-17 22:58:49.011 LoopDemo[70342:303] row:1 column:3 value 1
2014-08-17 22:58:49.012 LoopDemo[70342:303] row:1 column:2 value 1
2014-08-17 22:58:49.012 LoopDemo[70342:303] row:1 column:1 value 1
2014-08-17 22:58:49.013 LoopDemo[70342:303] row:1 column:0 value 1
2014-08-17 22:58:49.013 LoopDemo[70342:303] row:0 column:3 value 0
2014-08-17 22:58:49.013 LoopDemo[70342:303] row:0 column:2 value 0
2014-08-17 22:58:49.013 LoopDemo[70342:303] row:0 column:1 value 0
2014-08-17 22:58:49.014 LoopDemo[70342:303] row:0 column:0 value 0

指標

指標的定義是在於宣告的變數名稱前有*號為指標變數,例如:

//-----------start-----------
//資料型態 *指標名稱
    int *ptrInt;
//------------end------------

指標變數名稱宣告後它存放的只是記憶體的參考位址,所這樣的宣告下,必需要配置佔用的記憶體與指標變數做連結才能將它當做一般變數使用:

//-----------start-----------
//資料型態 *指標名稱
    int *ptrInt = malloc(sizeof(int));
    *ptrInt = 3;

    NSLog(@"%x",*ptrInt);
//------------end------------

輸出結果:

2014-08-17 23:22:55.414 LoopDemo[70825:303] 3

如果宣告指標變數後,未配置佔用的記憶體,那你宣告的指標變數只能利用現有的變數將該變數的記憶體位址指定至宣告的指標變數,要取得該變數的存放位址時需要在變數前加上&

//-----------start-----------
    int *ptrInt;
    int val;
    val = 4;
    ptrInt = &val;//取得val記憶體位址並傳至ptrInt
    *ptrInt = 5;//設定新的內容為5

    NSLog(@"*ptrInt %x val:%x",*ptrInt,val);
//------------end------------

val與ptrInt所指定相官的記憶體位址,所以我們變更ptrInt內容後,印出val值的結果會是相同。

輸出結果:

2014-08-18 10:13:21.706 LoopDemo[73047:303] *ptrInt 5 val:5

當你宣告指標變數後,想要知道該指標變數的記憶體位址時將*拿掉:

//-----------start-----------
    int *ptrInt = malloc(sizeof(int));
    *ptrInt = 3;

    NSLog(@"%x,address:%x",*ptrInt,(uint)ptrInt);
//------------end------------

輸出結果:

2014-08-17 23:26:37.376 LoopDemo[70897:303] 3,address:17be0

陣列與指標

陣列在宣告時使用連續的記憶體當陣列的空間,所以在使用上也可以利用指標的方式來存取,一般陣列宣告及將陣列印出來:

//-----------start-----------
    int arrayInt[4]={0,1,2,3};

    for (int i=0; i<4; i++) {
        NSLog(@"%i",arrayInt[i]);
    }

//------------end------------

輸出結果:

2014-08-17 23:44:11.089 LoopDemo[71098:303] 0
2014-08-17 23:44:11.090 LoopDemo[71098:303] 1
2014-08-17 23:44:11.090 LoopDemo[71098:303] 2
2014-08-17 23:44:11.090 LoopDemo[71098:303] 3

使用指標的方式將陣列的內容印出之前,其宣告的指標變數的資料型態必需與陣列的資料型態相同:

//-----------start-----------
    int arrayInt[4]={0,1,2,3};
    int *ptrInt;
    ptrInt = &arrayInt[0];//取得陣列一開始的位址

    for (int i=0; i<4; i++) {
        NSLog(@"%i",*(ptrInt + i));
    }
//------------end------------

如此一來,在位址計算時所移動的指標才會符合陣列所宣告的資料型態,位址確認好後,使用*號取得其內容,像*(ptrInt + 1)所代表的是arrayInt[1]

輸出結果:

2014-08-17 23:44:11.090 LoopDemo[71098:303] 0
2014-08-17 23:44:11.091 LoopDemo[71098:303] 1
2014-08-17 23:44:11.091 LoopDemo[71098:303] 2
2014-08-17 23:44:11.091 LoopDemo[71098:303] 3