C程式設計 | 指標小結
指標小結
1、首先要準確理解指標的含義。“指標”是C語言中一個形象化的名詞,形象地表示“指向”的關係,其在物理上的實現是通過地址來完成的。
- &a是變數a的地址,也可稱為變數a的指標。
- 指標變數是存放地址的變數,也可以說,指標變數是存放指標的變數。
- 指標變數的值是一個地址,也可以說,指標變數的值是一個指標。
- 指標變數也可稱為地址變數,它的值是地址。
- &是取地址運算子,&a是a的地址,也可以說,&是取指標運算子。&a是變數a的指標(即指向變數a的指標)。
- 陣列名是一個地址,是陣列首元素的地址,也可以說,陣列名是一個指標,是陣列首元素的指標。
- 函式名是一個指標
- 函式的實參如果是陣列名,傳遞給形參的是一個地址,也可以說,傳遞給形參的是一個指標。
2、 一個地址型的資料實際上包含3個資訊:
① 表示記憶體編號的純地址。
② 它本身的型別,即指標型別。
③ 以它為標識的儲存單元中存放的是什麼型別的資料,即基型別。
如:int a; /* &a為a的地址,它就包括以上3個資訊,它代表的是一個整型資料的地址,int是&a的基型別(即它指向的是int型的儲存單元)。&a就是“指向整型資料的指標型別”或“基型別為整型的指標型別”,其型別可以表示為“int *”型
3、要區別指標和指標變數。指標就是地址,而指標變數是用來存放地址的變數。
注意:並不是任何型別資料的地址都可以存放在同一個指標變數中的,只有與指標變數的基型別相同的資料的地址才能存放在相應的指標變數中。
int a,*p; //p是int*型的指標變數,基型別是int型
float b;
p=&a; //a是int型,合法
p=&b; //b是float型,型別不匹配
4、什麼叫“指向”?地址就意味著指向,因為通過地址能找到具有該地址的物件。對於指標變數來說,把誰的地址存放在指標變數中,就說此指標變數指向誰。
注意:void *指標是一種特殊的指標,不指向任何型別的資料
5、要深入掌握在對陣列的操作中正確地使用指標,搞清楚指標的指向。
int *p, a[10]; //p是指向int型型別的指標變數
p=a; //p指向a陣列的首元素
6、有關指標變數的歸納比較
7、指標運算
① 指標變數加(減)一個整數。
p++; //將該指標變數的原值(是一個地址)和它指向的變數所佔用的儲存單元的位元組數相加
② 指標變數賦值。將一個變數地址賦給一個指標變數。 不應把一個整數賦給指標變數。
p=&a; //將變數a的地址賦給p
p=array; //將陣列array首元素地址賦給p
p=&array[i]; //將陣列array第i個元素的地址賦給p
p=max; //max為已定義的函式,將max的入口地址賦給p
p1=p2; //p1和p2是基型別相同指標變數,將p2的值賦給p1
③ 兩個指標變數可以相減。如果兩個指標變數都指向同一個陣列中的元素,則兩個指標變數值之差是兩個指標之間的元素個數。
④ 兩個指標變數比較。若兩個指標指向同一個陣列的元素,則可以進行比較。指向前面的元素的指標變數“小於”指向後面元素的指標變數。如果p1和p2不指向同一陣列則比較無意義。
8、指標變數可以有空值,即該指標變數不指向任何變數。
如:p=NULL; /*NULL是一個符號常量,代表整數0。在stdio.h標頭檔案中對NULL進行了定義:#define NULL 0 。它使p指向地址為0的單元。系統保證使該單元不作它用(不存放有效資料)。*/
注意:p的值為NULL與未對p賦值是兩個不同的概念。前者是有值的(值為0),不指向任何變數,後者雖未對p賦值但並不等於p無值,只是它的值是一個無法預料的值,也就是p可能指向一個事先未指定的單元。
任何指標變數或地址都可以與NULL作相等或不相等的比較。如:if(p==NULL)
9、指標的優點:
- 提高程式效率;
- 在呼叫函式時當指標指向的變數的值改變時,這些值能夠被主調函式所使用,即可以從函式呼叫得到多個可改變的值;
- 可以實現動態儲存分配。
如果使用指標不當,會出現隱蔽的、難以發現和排除的故障。因此,使用指標要十分小心謹慎。