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 = 記憶位址來源 ;
//指標前方沒有 ‘*’ 代表存取指標。
記憶位址來源有三種:
pointer_a = 記憶位址來源 ;
//指標前方沒有 ‘*’ 代表存取指標。
記憶位址來源有三種:
A.
另一個變數的記憶體位址。例:
int student_age = 值;
int* pointer_a = &student_age;
’&’ 為取址運算符號,用來取得變數 student_age 的記憶體位址。在這個敍述之後, pointer_a 及 student_age 都可以存取 student_age 的值。
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 中的區域變數的值。相關用法筆者將另闢章節討論。
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 = 值 ;
//指標前方沒有 ‘*’ 代表存取指標中儲存的記憶位址指向的記憶體空間。
*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() 是切斷這個指標和目前配置的記憶體空間的關聯,若有必要可以再配置新的記憶體位址給這個指標。
沒有留言:
張貼留言