?? 教學--第19章 指針一 基本概念.htm
字號:
<P>
<P>第二步、基于前一題,再加上一個指針變量,叫<SPAN lang=en-us> p2</SPAN>。
<P>
<P><SPAN lang=en-us>1) int k = 100;</SPAN>
<P><SPAN lang=en-us>2) int* p1 = &k;</SPAN>
<P><SPAN lang=en-us>3) int* p2 = p;</SPAN>
<P>
<P><SPAN lang=en-us>4) cout << *p1 << endl;</SPAN>
<P><SPAN lang=en-us>5) cout << *p2 << endl;</SPAN>
<P>
<P>編譯并運行,觀察結果應發現,<SPAN lang=en-us>*p </SPAN>和<SPAN lang=en-us> *p2
</SPAN>值相等,為什么?因為二者指向同一變量:k。
<P>
<P>第三步、請像第一步一樣,觀察,k 的地址,及p1, p2 的值。看三者是否相等。
<P>
<P>最后<SPAN lang=en-us>,</SPAN>將后面的兩行輸出刪除,改為以下兩行代碼。第一行輸出 k 的地址、p1、p2的值。
<P>第二行 輸出k的值、*p1、*p2 值。
<P>
<P>//cout << *p1 << endl;
<P>//cout << *p2 << endl;
<P>
<P>cout << "&k = " << &k << ", p1 = " <<
p1 << ", p2 = " << p2 <<endl;
<P>cout << "k = " << k << ", *p1 = " << *p1
<< ", *p2 = " << *p2 <<endl; <BR>
<P>
<P>運行后結果如下:
<P align=center><IMG height=73 src="教學--第19章 指針一 基本概念.files/ls19.h5.jpg"
width=332 border=0>
<P align=center><SPAN lang=en-us>(1245064 </SPAN>是十進制的,它等于十六進制的<SPAN
lang=en-us> 0x0012FF88)</SPAN>
<P>
<H3><B><SPAN lang=en-us><A name=19.7>19.7</A>
</SPAN>上機實驗二:改變指針所指變量的值,改變指針的指向</B></H3>
<P>
<P>盡管在上面的例子中修修改改也能改成本例,不過枝節太多的代碼不會混淆了我們的目的。這次我們重點在于“改變”。
<P>
<P>第一步、 通過指針,改變其所指向的變量的值。(好繞啊!代碼卻很簡單)
<P>
<P><SPAN lang=en-us>int k = 100;</SPAN>
<P>
<P><SPAN lang=en-us>int* p = &k;</SPAN>
<P>
<P><SPAN lang=en-us>//</SPAN>先輸出一開始的k和*p的值<SPAN
lang=en-us>(</SPAN>用逗號分開<SPAN lang=en-us>)</SPAN>:
<P><SPAN lang=en-us>cout << k << "," << *p <<
endl; </SPAN>
<P>
<P><SPAN lang=en-us>//</SPAN>現在直接改變k值:
<P><SPAN lang=en-us>k = 200;</SPAN>
<P>
<P><SPAN lang=en-us>//</SPAN>輸出此時的二者的值:
<P><SPAN lang=en-us>cout << k << "," << *p <<
endl; </SPAN>
<P>
<P><SPAN lang=en-us>//</SPAN>然后通過指針來改變k值:
<P><SPAN lang=en-us>*p = 300;</SPAN>
<P>
<P><SPAN lang=en-us>//</SPAN>輸出此時的二者的值:
<P><SPAN lang=en-us>cout << k << "," << *p <<
endl; </SPAN>
<P>
<P><SPAN lang=en-us>system("PAUSE");</SPAN>
<P>
<P>輸出將是:
<P>
<P align=center><IMG height=83 src="教學--第19章 指針一 基本概念.files/ls19.h6.gif"
width=159 border=0>
<P>
<P>可見,當p指向k以后,修改 *p 的值完全等同于直接修改 k值。
<P>
<P>第二步、改變指針的指向
<P>
<P>所謂的“改變指向”,其實就是“改變指針變量中存儲的值(另一個變量的地址)”。我們一開始說的,兩種不同的說法而已。
<P>在前面的代碼最后,我們加上以下代碼:
<P>
<P><SPAN lang=en-us>...</SPAN>
<P><SPAN lang=en-us>int m = 1000;</SPAN>
<P>
<P><SPAN lang=en-us>//</SPAN>現在p改為指向變量<SPAN lang=en-us> </SPAN>m<SPAN
lang=en-us> :</SPAN>
<P><SPAN lang=en-us>p = &m;</SPAN>
<P>
<P><SPAN lang=en-us> k = 400;</SPAN>
<P><SPAN lang=en-us>cout << k << "," << m << ","
<< *p << endl;<BR> </SPAN>
<P><SPAN lang=en-us>*p = 2000;</SPAN>
<P><SPAN lang=en-us>cout << k << "," << m << ","
<< *p << endl;</SPAN>
<P>
<P><SPAN lang=en-us>system("PAUSE");</SPAN>
<P>
<P>屏幕輸出是:
<P align=center><IMG height=56 src="教學--第19章 指針一 基本概念.files/ls19.h7.gif"
width=158 border=0>
<P>
<P>當p改為指向m以后,之前指向的k便再也和它沒有什么關系了。改變k值不會再影響p;而改變p值,則影響到m值而非k值。
<P>
<H3><B><SPAN lang=en-us><A name=19.8>19.8</A> </SPAN>指針的加減操作</B></H3>
<P>整型變量可以加減,求和,求差:
<P><SPAN lang=en-us>int a = 100;</SPAN>
<P><SPAN lang=en-us>int b = 99;</SPAN>
<P><SPAN lang=en-us>int c = a - b;</SPAN>
<P>
<P>而指針,由于它存的是一個內存地址,那么我們可以想到,對兩個指針進行求和,求差,是沒有意義的。想想,把你家的門牌號(206)和對面的的門牌號(207)相加(413),得到的數有什么意義嗎?
<P>
<P>那么,指針的加減指什么呢?主要是指移動(而不是聯通:()。比如,你家是206,那么,你的下一家,應該是206 + 1 =
207,而上一家則是206 - 1 =
205。你會說,我們這里的門牌號不是這樣編的。但不管如何,大致應當是一個等差關系,或其它規律。都可以通過不斷加上一個數,來得到下一家。
<P>
<H4><B><SPAN lang=en-us><A name=19.8.1>19.8.1</A> </SPAN>指向數組的指針</B></H4>
<P>
<P>現在,來說說指針指向一個數組的情況。
<P>
<P><SPAN lang=en-us>int arr[] = {1,2,3,4,5}; //</SPAN>一個數組
<P>
<P><SPAN lang=en-us>int* parr; //</SPAN>一個指針。
<P>
<P><SPAN lang=en-us>parr = arr; //</SPAN>沒有<SPAN lang=en-us> </SPAN>‘<SPAN
lang=en-us>&</SPAN>’<SPAN lang=en-us> </SPAN>?對啊,對數組就是不用取址符。
<P>
<P><SPAN lang=en-us>cout << *parr << endl;
//</SPAN>輸出<SPAN lang=en-us> *parr </SPAN>
<P>
<P>先猜想一下,輸出結果是什么?
<P>
<P>最“直覺”的想法是:<SPAN lang=en-us>parr
</SPAN>指向一個數組,那么輸出時,自然是輸出數組中的所有元素了。所以答案應該是:“12345”了?
<P>不過,我想,學過前面的數組,我們就能知道這種想法錯誤。
<P>
<P>正確答案是輸出數組中的第一個元素: 1 。
<P>
<P>接下來,如果是這樣輸出呢?
<P>
<P><SPAN lang=en-us>parr = arr;</SPAN>
<P><SPAN lang=en-us>cout << parr << endl;</SPAN>
<P>
<P>答案是輸出了<SPAN lang=en-us>arr</SPAN>的地址。就等同于輸出<SPAN lang=en-us> arr</SPAN>
。
<P><SPAN lang=en-us>cout << arr << endl;</SPAN> 的作用
<P>
<P>在這里,難點是要記住,數組變量本身就是地址。所以有:
<P>
<P>1、想讓指針變量存儲一個數組的地址(想讓指針變量指向一個數組)時,不用取址符。
<P>2、解析一個指向數組的指針,得到的是數組的第一個元素。
<P>
<P>我們來看示意圖:
<P>
<P align=center><IMG height=277 src="教學--第19章 指針一 基本概念.files/ls19.h9.gif"
width=452 border=0>
<P align=center>(指向數組的指針)
<P align=center>
<P>盡管數組中的每一個元素都有自已的地址,然而一個指向數組的指針,它仍然只是存儲數組中第一個元素的地址。復習數組的章節,我們知道,數組中第一個元素的地址,就是數組的地址。即上圖中的<SPAN
lang=en-us> 10000010</SPAN>。
<P>
<P>事實上,如果我們想故意讓代碼很難理解,則對于這一句:
<P>
<P><SPAN lang=en-us>parr = arr;</SPAN>
<P>可以改為:
<P><SPAN lang=en-us>parr = &arr[0];</SPAN>
<P>
<P>本來嘛, arr 和<SPAN lang=en-us> &arr[0]
</SPAN>的值就相等,我們在數組的章節已經學過。你若不信,可以輸出一個:
<P><SPAN lang=en-us>cout << arr << "," << &arr[0]
<< endl;</SPAN>
<P>
<H4><B><SPAN lang=en-us><A name=19.8.2>19.8.2</A>
</SPAN>上機實驗三:指向數組的指針</B></H4>
<P>
<P>int arr[2] = {1,2};
<P>int* p = &arr[0];
<P>
<P>//輸出:指向數組的指針,數組的地址,數組中第一個元素的地址。
<P>cout << p << "," << arr << "," <<
&arr[0] << endl;
<P>
<P>system("PAUSE");
<P>
<P>結果是:
<P align=center><IMG height=34 src="教學--第19章 指針一 基本概念.files/ls19.h10.gif"
width=191 border=0>
<P align=center><SPAN lang=en-us>(</SPAN>指向數組的指針,數組的地址,數組中第一個元素的地址。<SPAN
lang=en-us>)</SPAN>
<P>
<H4><B><SPAN lang=en-us><A name=19.8.3>19.8.3</A> </SPAN>偏移指針</B></H4>
<P>
<P>請看前圖的這一部分:
<P align=center><IMG height=66 src="教學--第19章 指針一 基本概念.files/ls19.h11.gif"
width=322 border=0>
<P align=center>
<P><SPAN lang=en-us>parr </SPAN>中存的值為 “10000010”。
<P>
<P>指針可以進行加減操作。假設我現在再定義一個指針:
<P>
<P><SPAN lang=en-us>int* parr2;</SPAN>
<P>
<P><SPAN lang=en-us>parr2 = parr + 1;</SPAN>
<P>
<P>現在問,<SPAN lang=en-us>parr2 </SPAN>的值是多少?有兩種答案。一種說,<SPAN lang=en-us>
parr </SPAN>存的值是<SPAN lang=en-us> 10000010 </SPAN>,加1后,自然應為<SPAN
lang=en-us> 10000011</SPAN>了。這看似自然的答案又是錯誤了。
<P>
<P>正確答案:<SPAN lang=en-us>10000014</SPAN>。繼續看前圖另一小部分:
<P align=center><IMG height=111 src="教學--第19章 指針一 基本概念.files/ls19.h12.gif"
width=204 border=0>
<P align=center>(加1后,指針指向了下一個元素)
<P>
<P>加1后,指針指向了下一個元素。由于這是一個<SPAN lang=en-us> int
</SPAN>類型的數組,每個元素的大小是4個字節。所以第二個元素的地址是10000014。
<P>
<P><B>重點 <SPAN lang=en-us>& </SPAN>易錯點:對指針
進行加1操作,得到的是下一個元素的地址,而不是原有地址值直接加1。</B>
<P>
<P>知到了如何“加”,也就知道了如何“減”。減以后,得到的是上一個元素的大小。
<P>
<P>所以,一個類型為 T 的指針的移動,以 <SPAN lang=en-us>sizeof(T) </SPAN>為移動單位。
<P>
<P>比如:<SPAN lang=en-us> </SPAN>
<P><SPAN lang=en-us>int* pInt; </SPAN>移動單位為 <SPAN lang=en-us>sizeof(int)
</SPAN>。即:4。而<SPAN lang=en-us> char* pChar; </SPAN>移動單位為<SPAN lang=en-us>
sizeof(char)</SPAN>。即1。
<P>
<P>試舉一例:
<P>
<H4><B><SPAN lang=en-us><A name=19.8.4>19.8.4</A>
</SPAN>上機實驗四:指針的最小移動單位</B></H4>
<P>
<P><SPAN lang=en-us>int arr[6] = {101,102,103,104,105,106};</SPAN>
<P><SPAN lang=en-us>int* pI = arr;</SPAN>
<P>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -