在開始學習Pointer時要先記住兩件事:
1. All arguments in C are“pass-by-value (call-by-value)".
- 在 C 的世界裡所有的變數皆是“傳值呼叫"。
2. Pointers enable programs to simulate“pass-by-reference (call-by-reference)".
- pointer 是用來“模擬"“傳址呼叫"的方法。
“&"Address Operation(取址運算子)
“&"當做“取址"運算子時,用來表示(或取得)一變數的記憶體位址,例如:
#include <stdio.h> #include <stdlib.h> int main() { int A; //變數宣告 A = 7; printf( "The address of A: %p\n", &a ); A = 10; printf( " The address of A: %p\n", &a ); A = 77; printf( " The address of A: %p\n", &a ); }
“%p"是“printf"的Conversion Specification,以16進制的方式輸出。參附表於文章結尾。
C 的所有變數皆是“傳值呼叫",所以變數 A 只有值會改變,而“位址"不變。
甚麼是 Pointer(指標)?
當一個變數被宣告後通常具有一些特性:
1. 位址(Address): 表示該變數的所在位址
2. 名稱(Name): 表示該變數的名稱
3. 內容(Content): 表示該變數所內含的資料值
4. 屬性(Attribute): 該變數的資料型態
5. 有效範圍(Scope): 該變數的生命週期
Pointer are variables whose values are memory address.
說穿了,pointer 其實還是變數,只是這種變數存的是記憶體位址。
既然內容物是記憶體位址,指標便能代表其他變數,甚至也能代表指標,使用方法與範圍十分彈性。
如何運用指標?
1. 指標宣告:宣告一個指向該資料型態的指標變數。
格式一:Data_Type *Data_Name;
格式二:Data_Type* Data_Name;
格式三:Data_Type * Data_Name;
宣告指標時需要“*"符號。
原則上這三種命名格式是一樣的,命名時就依個人習慣囉!
EX:
int *aPtr;
int* aPtr;
int * aPtr;
2. 位址計算:將一個一般變數的記憶體位址傳遞給一個指標變數。
格式:指標變數 = &一般變數;
int a = 10;
int *aPtr;
aPtr = &a;
aPtr | >> | a | |
Address | 0028FF18 | 0028FF1C | |
Content | 0028FF1C | 10 |
#include <stdio.h> #include <stdlib.h> int main() { int a = 10; int *aPtr; aPtr = &a; printf( "The address of a is %p\n" "The content of aPtr is %p\n\n", &a, aPtr ); printf( "The content of a is %d\n" "The content of *aPtr is %d\n\n", a, *aPtr ); printf( "The address of aPtr is %p\n", &aPtr ); }
輸出:
3. 指向指標的指標:雙重指標。
格式一:Data_Type **Data_Name;
格式二:Data_Type** Data_Name;
格式三:Data_Type ** Data_Name;
三者效果皆同,命名時依個人習慣。
指向指標的指標依然是指標,內容同樣是記憶體位址,只是這次存的是某個指標的記憶體位置。
EX:
int a = 2;
int *aPtr, **aPPtr;
aPtr = &a;
aPPtr = &aPtr;
aPPtr | >> | aPtr | >> | a | |
Address | 0028FF14 | 0028FF18 | 0028FF1C | ||
Content | 0028FF18 | 0028FF1C | 2 |
#include #include int main() { int a = 2; int *aPtr; int **aPPtr; aPtr = &a; aPPtr = &aPtr; printf( "The address of a is %p\n" "The content of aPtr is %p\n" "The content of aPPtr is %p\n\n", &a, aPtr, aPPtr ); printf( "The content of a is %d\n" "The content of *aPtr is %d\n" "The content of *aPPtr is %p\n" "The content of **aPPtr is %d\n\n", a, *aPtr, *aPPtr, **aPPtr ); printf( "The address of aPtr is %p\n" "The address of aPPtr is %p", &aPtr, &aPPtr ); }
輸出:
“*"Asterisk Notation
學習指標的過程中最麻煩的在於對“*"的解釋。
“*"在指標變數的宣告和運用時的解釋不太一樣。
當宣告一個指標變數時“*"可以視作對指標變數的識別;
一但開始使用指標變數“*"則是指標變數內容(address)指到的值。
int a = 10;
int *aPtr;
aPtr = &a;
*附表:
Conversion Specification | Output |
%c |
Character |
%s |
String of characters |
%d or %i | Decimal integer |
%e | Floating point number in e-notation |
%f | Floating point number in decimal notation |
%g | Uses %f or %e whichever is shorter |
%p | Pointer |
%u | Unsigned decimal integer |
%o | Octal integer |
%x | Hexadecimal integer, using lower case |
%X | Hexadecimal integer, using upper case |
%% | Prints a % sign |
參考資料:
C How to Program 7/e PEARSON Paul Deitel.Harvey Deitel
算是這陣子被指標操出來的小結論吧!
是說我也沒有全弄懂,這裡是我目前碰過的指標運用,如果有錯還多見諒~~
2014/12/14 多雲
留言列表