1.1.2 指針變量的引用
既然在指針變量中只能存放地址,因此,在使用中不要將一個整數賦給一指針變量。下面的賦值是不合法的:
int *ip;
ip=100;
假設
int i=200, x;
int *ip;
我們定義了兩個整型變量i, x,還定義了一個指向整型數的指針變量ip。i, x中可存放整數,而ip中只能存放整型變量的地址。我們可以把i的地址賦給ip:
ip=&i;
此時指針變量ip指向整型變量i,假設變量i的地址為1800,這個賦值可形象理解為下圖所示的聯系。
ip i
┏━━━┓ ┏━━━┓
┃ 1800 ╂──→ ┃ 200 ┃
┗━━━┛ ┗━━━┛
圖1. 給指針變量賦值
以後我們便可以通過指針變量ip間接訪問變量i,例如:
x=*ip;
運算符*訪問以ip為地址的存貯區域,而ip中存放的是變量i的地址,因此,*ip訪問的是地址為1800的存貯區域(因為是整數,實際上是從1800開始的兩個字節),它就是i所占用的存貯區域,所以上面的賦值表達式等價於x=i;
另外,指針變量和一般變量一樣,存放在它們之中的值是可以改變的,也就是說可以改變它們的指向,假設
int i, j, *p1, *p2;
i='a';
j='b';
p1=&i;
p2=&j;
則建立如下圖所示的聯系:
p1 i
┏━━━┓ ┏━━━┓
┃ ╂──→ ┃ 'a' ┃
┗━━━┛ ┗━━━┛
p2 i
┏━━━┓ ┏━━━┓
┃ ╂──→ ┃ 'b' ┃
┗━━━┛ ┗━━━┛
圖2. 賦值運算結果
這時賦值表達式:
p2=p1
就使p2與p1指向同一對象i,此時*p2就等價於i,而不是j,圖2.就變成圖3.所示:
p1 i
┏━━━┓ ┏━━━┓
┃ ╂──→ ┃ 'a' ┃
┗━━━┛ ┌→ ┗━━━┛
p2 │ j
┏━━━┓ │ ┏━━━┓
┃ ╂─┘ ┃ 'b' ┃
┗━━━┛ ┗━━━┛
圖3. p2=p1時的情形
如果執行如下表達式:
*p2=*p1;
則表示把p1指向的內容賦給p2所指的區域,此時圖2.就變成圖4.所示
p1 i
┏━━━┓ ┏━━━┓
┃ ╂──→ ┃ 'a' ┃
┗━━━┛ ┗━━━┛
p2 j
┏━━━┓ ┏━━━┓
┃ ╂──→ ┃ 'a' ┃
┗━━━┛ ┗━━━┛
圖4. *p2=*p1時的情形
通過指針訪問它所指向的一個變量是以間接訪問的形式進行的,所以比直接訪問一個變量要費時間,而且不直觀,因為通過指針要訪問哪一個變量,取決於指針的值(即指向),例如"*p2=*p1;"實際上就是"j=i;",前者不僅速度慢而且目的不明。但由於指針是變量, 我們可以通過改變它們的指向,以間接訪問不同的變量,這給程序員帶來靈活性,也使程序代碼編寫得更為簡潔和有效。
指針變量可出現在表達式中,設int x, y *px=&x;
指針變量px指向整數x,則*px可出現在x能出現的任何地方。例如:
y=*px+5; /*表示把x的內容加5並賦給y*/
y=++*px; /*px的內容加上1之後賦給y [++*px相當於++(px)]*/
y=*px++; /*相當於y=*px; px++*/