2014年3月11日 星期二

C 語言 指標:宣告、存取、配置與釋放記憶體 / C language pointer : declare, access, allocate and free memory

C 語言 指標:宣告、存取、配置與釋放記憶體

作者:許裕永 Darban

指標 (pointer) 也是變數,是用來儲存記憶體位址的變數。
在電腦啟動的時候,作業系統會替所有可用的記憶體以 byte 為單位配給每一單位的記憶體一個編號,這個編號稱之為記憶體位址 (memory address)
C 語言可以用指標來儲存記憶體位址,再透過指標去存取指標中儲存的記憶體位址指向的記憶體空間。
所以,指標和一般變數的差異為:
) 一般變數中儲存一個值,設計師可以存取該變數中的值。
|)指標中儲存一個記憶體位址,設計師除了可以存取該指標中的記憶體位址;而且還可以存取指標中儲存的記憶體位址所指向的記憶體空間

>_< 宣告
指標的宣告敍述是在型別後方加一個 ‘*’ 。例:
int* pointer_a;
int* pointer_a = 記憶體位址來源 ;
請注意pointer_a 前方並沒有 ‘*’ ,敍述中的 ‘*’ 置於型別 int 的後面,是型別的一部份。代表現在要宣告的是一個指標

為了宣告方便宣告一個以上的相同型別的指標,也接受把 ‘*’ 置於指標名稱前方。例:
int *pointer_a, *pointer_b, *pointer_c;
但因為存取時,指標前方是否有 ‘*’ ,代表的意思並不一樣,建議初學者先不要使用這種方式宣告,避免混淆

>_< 存取
1.          存取指標
pointer_a =
記憶位址來源 ;
//
指標前方沒有 ‘*’ 代表存取指標。

記憶位址來源有三種:
A.         另一個變數的記憶體位址。例:
int student_age =
;
int* pointer_a = &student_age;
’&’
為取址運算符號,用來取得變數 student_age 的記憶體位址。在這個敍述之後, pointer_a student_age 都可以存取 student_age 的值。
B.         另一個指標儲存的記憶體位址。例:
int* pointer_a =
記憶體位址來源 ;
int* pointer_b;
pointer_b = pointer_a;

請注意pointer_b pointer_a 前方都沒有 ‘*’ ,代表要取得的是儲存在 pointer_a 中的記憶體位址,再把取得的記憶體位址指派給 pointer_b。在此敍述之後,pointer_a pointer_b 中儲存的是同一個記憶體位址;也就是說 *pointer_a *pointer_b 可以存取同一個記憶體空間

在同一個 function 中宣告一個變數或指標,再把記憶體位址指派給另一個指標,是不合邏輯的。它運用的時機是參數的指派, function_a 把某一個記憶體位址當參數,指派給 function_b 的指標,讓 function_b 可以存取 function_a 中的區域變數的值。相關用法筆者將另闢章節討論
C.         配置新的記憶體空間
下面另外用一個獨立的小節說明。
2.          存取指標中儲存的記憶位址指向的記憶體空間
*pointer_a =
;
//
指標前方沒有 ‘*’ 代表存取指標中儲存的記憶位址指向的記憶體空間。

Example:

        int a=10;
        int* b;
        b = &a;
        printf("The memory address of a is : %d\n", &a);
        printf("The memory address store in b is : %d\n", b);
       
        printf("------------------------------------------\n");
        printf("The value assess from a before change by *b is : %d\n", a);
        *b = 100;
        printf("The value assess from a change change by *b is : %d\n", a);

上述的 Example 在同一個 function 宣告指標去存取另一個變數的作法,是不合邏輯的,只是單純示範指標的存取。在 function 中宣告一個指標,會配置新的記憶體空間給它,而不是去搶其他變數的控制權。

>_< 配置記憶體空間
標頭檔: stdlib.h
函式原式: void* malloc(int size)

Example:

        int* a;
        a = (int*)malloc(sizeof(int));
        *a = 100;
        printf("The memory address store in a is : %d\n", a);
        printf("The value assess by *a is: %d\n", *a);

|) 因為 malloc() return type void* ,所以必須用 (type*) 轉型。
|) sizeof(type) 可以取得小括號中的型別需要的記憶體空間的容量。

>_< 釋放記憶體空間
標頭檔: stdlib.h
函式原式: void free(void*)

Example:

        int* a;
        a = (int*)malloc(sizeof(int));
        *a = 100;
        free(a);
        printf("The memory address store in a is : %d\n", a);
        printf("The value assess by *a is: %d\n", *a);

配置的記憶體空間,可以在不使用時,呼叫 free() 釋放,讓作業系統再利用。
呼叫 free() 是切斷這個指標和目前配置的記憶體空間的關聯,若有必要可以再配置新的記憶體位址給這個指標。


沒有留言:

張貼留言