?? 教學--第二十章 指針 二 為指針分配和釋放空間.htm
字號:
<P><SPAN lang=zh-cn>(任務管理顯示我的機器使用了207兆的內存)</SPAN></P></TD></TR>
<TR>
<TD width="60%">
<P align=center><SPAN lang=zh-cn>第二步:分配了100兆的內存</SPAN>
<P align=center><IMG height=36
src="教學--第二十章 指針 二 為指針分配和釋放空間.files/ls20.h7.gif" width=301
align=middle border=0> </P></TD>
<TD align=middle width="40%"><IMG height=65
src="教學--第二十章 指針 二 為指針分配和釋放空間.files/ls20.h8.gif" width=82
align=middle border=0>
<P align=center>(<SPAN lang=zh-cn>多出了100M</SPAN>)</P></TD></TR>
<TR>
<TD width="60%">
<P align=center><SPAN lang=zh-cn>第三步:又釋放出這100兆</SPAN>
<P align=center><IMG height=41
src="教學--第二十章 指針 二 為指針分配和釋放空間.files/ls20.h9.gif" width=199
align=middle border=0> </P></TD>
<TD align=middle width="40%"><IMG height=66
src="教學--第二十章 指針 二 為指針分配和釋放空間.files/ls20.h10.gif" width=78
align=middle border=0>
<P align=center>(<SPAN
lang=zh-cn>回到207兆</SPAN>)</P></TD></TR></TBODY></TABLE>
<P>
<P><B><SPAN lang=zh-cn>注意:使用</SPAN> new <SPAN lang=zh-cn>得來的空間,必須用</SPAN>
delete <SPAN lang=zh-cn>來釋放;使用</SPAN> new [] <SPAN
lang=zh-cn>得來的空間,必須用</SPAN> delete [] <SPAN
lang=zh-cn>來釋放。彼此之間不能混用。</SPAN></B>
<P>
<P><SPAN lang=zh-cn>用</SPAN> new [] <SPAN
lang=zh-cn>分配出連續空間后,指針變量“指向”該空間的首地址。</SPAN>
<P>
<H4><B><A name=20.3.3>20.3.3</A> <SPAN
lang=zh-cn>詳解指向連續空間的指針</SPAN></B></H4>
<P>
<P>在<SPAN lang=en-us> </SPAN>通過<SPAN lang=en-us> new [] </SPAN>指向連續空間以后,p
就變得和一個一維數組很是類似。我們先來復習一下數組相關知識。
<P>
<P>假設是這么一個數組:
<P>
<P><SPAN lang=en-us>int arr[20];</SPAN>
<P>
<P>則<SPAN lang=en-us>arr </SPAN>的內存示意圖為(為了不太占用版面我縮小了一點):
<P align=center>
<P align=center><IMG height=268
src="教學--第二十章 指針 二 為指針分配和釋放空間.files/ls20.h4.gif" width=261 border=0>
<P align=center><SPAN lang=en-us>(</SPAN>數組<SPAN lang=en-us> arr
</SPAN>的內存示意<SPAN lang=en-us>)</SPAN>
<P align=center>
<P>和指針變量相比,<SPAN lang=en-us>
</SPAN>數組沒有一個單獨的內存空間而存放其內存地址。即:指針變量p是一個獨立的變量,只不過它的值指向另一段連續的內存空間;而數組arr,本身代表的就是一段連續空間。
<P>
<P>如果拿房間來比喻。指針和數組都是存放地址。只不過,指針是你口袋里的那本通訊錄上寫著的地址,你可以隨時改變它的內容,甚至擦除。而數組是你家門楣上釘著的地址,你家原來是“復興路甲108號”,你絕對不能趁月黑天高,把它涂改為“唐寧街10號”。
<P>
<P>數組是“實”的地址,不能改變。當你和定義一個數組,則這個數組就得根據它在內存中的位置,得到一個地址,如上圖中的“<SPAN
lang=en-us>0x1A000000</SPAN>”。只要這個數組存在,那么它終生的地址就是這個值。
<P>
<P>指針是一個“虛”的地址,可以改變地址的值。當你定義一個指針變量,這個變量占用4個字節的內存,你可以往這4字節的內存寫入任意一個值,該值被當成一個內存地址。比如,你可以寫入上面的“<SPAN
lang=en-us>0x1A000000</SPAN>”<SPAN
lang=en-us>,</SPAN>此時,指針p指向第一個元素。也可以改為“<SPAN
lang=en-us>0x1A00000</SPAN>3”,此時,指針p指向第二個元素。
<P>
<P>所以,當p通過<SPAN lang=en-us> new [] </SPAN>指向一段連續空間的結果是,p 是一個指向數組的指針,而<SPAN
lang=en-us>*p</SPAN>是它所指的數組。
<P>
<P>我們來看實例,首先看二者的類似之處。下面左邊代碼使用數組,右邊代碼使用指針。
<P>
<TABLE id=AutoNumber1 style="BORDER-COLLAPSE: collapse"
borderColor=#111111 cellSpacing=0 cellPadding=0 width="100%" border=1>
<TBODY>
<TR>
<TD width="50%">數組</TD>
<TD width="50%">指針<SPAN lang=en-us> (</SPAN>通過<SPAN lang=en-us> new
[] </SPAN>所得<SPAN lang=en-us>)</SPAN></TD></TR>
<TR>
<TD width="50%"><SPAN lang=en-us>//</SPAN>定義<SPAN
lang=en-us>:</SPAN>
<P><SPAN lang=en-us>int arr[</SPAN>20<SPAN lang=en-us>];
</SPAN></P></TD>
<TD width="50%"><SPAN lang=en-us>//</SPAN>定義:
<P><SPAN lang=en-us>int* p = new int[20];</SPAN></P></TD></TR>
<TR>
<TD width="50%">
<P><SPAN lang=en-us>//</SPAN>讓第一個元素值為100:</P>
<P><SPAN lang=en-us>arr[0] = 100;</SPAN></P>
<P> </P></TD>
<TD width="50%"><SPAN lang=en-us>//</SPAN>讓第一個元素值為100:
<P><SPAN lang=en-us>p[0] = 100;</SPAN></P></TD></TR>
<TR>
<TD width="50%"><SPAN lang=en-us>//</SPAN>讓后面19個元素值分別為其前一元素加<SPAN
lang=en-us> </SPAN>5<SPAN lang=en-us>0</SPAN>:
<P><SPAN lang=en-us>for (int i = 1; i < 20; i++)</SPAN></P>
<P><SPAN lang=en-us>{</SPAN></P>
<P><SPAN lang=en-us> arr[i] = arr[i-1] + 50;</SPAN></P>
<P><SPAN lang=en-us>}</SPAN></P></TD>
<TD width="50%"><SPAN lang=en-us>//</SPAN>讓后面19個元素值分別為其前一元素加<SPAN
lang=en-us> </SPAN>5<SPAN lang=en-us>0</SPAN>:
<P><SPAN lang=en-us>for (int i = 1; i < 20; i++)</SPAN></P>
<P><SPAN lang=en-us>{</SPAN></P>
<P><SPAN lang=en-us> p[i] = p[i-1] + 50;</SPAN></P>
<P><SPAN lang=en-us>}</SPAN></P></TD></TR>
<TR>
<TD width="50%"><SPAN lang=en-us>//</SPAN>輸出所有元素:
<P><SPAN lang=en-us>for (int i = 0; i < 20; i++)</SPAN></P>
<P><SPAN lang=en-us>{</SPAN></P>
<P><SPAN lang=en-us> cout << arr[i] <<
endl;</SPAN></P>
<P><SPAN lang=en-us>}</SPAN></P></TD>
<TD width="50%"><SPAN lang=en-us>//</SPAN>輸出所有元素:
<P><SPAN lang=en-us>for (int i = 0; i < 20; i++)</SPAN></P>
<P><SPAN lang=en-us>{</SPAN></P>
<P><SPAN lang=en-us> cout << p[i] <<
endl;</SPAN></P>
<P><SPAN lang=en-us>}</SPAN></P></TD></TR>
<TR>
<TD width="50%"><SPAN lang=en-us>//</SPAN>也可以不用[],而通過+號來得到指定元素:
<P><SPAN lang=en-us>//</SPAN>當然,對于數組,更常用的還是 [] 操作符。</P>
<P><SPAN lang=en-us>cout << *(arr + 0) << endl;
//*(arr+0) </SPAN>等于<SPAN lang=en-us> *arr</SPAN></P>
<P><SPAN lang=en-us>cout << *(arr + 1) <<
endl;</SPAN></P>
<P><SPAN lang=en-us>cout << *(arr + 1) <<
endl;</SPAN></P>
<P> </P>
<P>輸出結果:</P>
<P style="LINE-HEIGHT: 100%"><FONT color=#ffffff><SPAN lang=en-us
style="BACKGROUND-COLOR: #000000"> 100 </SPAN></FONT></P>
<P style="LINE-HEIGHT: 100%"><FONT color=#ffffff><SPAN lang=en-us
style="BACKGROUND-COLOR: #000000"> 150 </SPAN></FONT></P>
<P style="LINE-HEIGHT: 100%"><FONT color=#ffffff><SPAN lang=en-us
style="BACKGROUND-COLOR: #000000"> 200 </SPAN></FONT></P></TD>
<TD width="50%"><SPAN lang=en-us>//</SPAN>也可以不用[],而通過+號來得到指定元素:
<P>//其實,對于指針,這樣的+及-操作用得還要多點。</P>
<P><SPAN lang=en-us>cout << *(p + 0) << endl; //*(p + 0)
</SPAN>等于<SPAN lang=en-us> *p</SPAN></P>
<P><SPAN lang=en-us>cout << *(p + 1) << endl;</SPAN></P>
<P><SPAN lang=en-us>cout << *(p + 1) << endl;</SPAN></P>
<P> </P>
<P>輸出結果:</P>
<P style="LINE-HEIGHT: 100%"><FONT color=#ffffff><SPAN lang=en-us
style="BACKGROUND-COLOR: #000000"> 100 </SPAN></FONT></P>
<P style="LINE-HEIGHT: 100%"><FONT color=#ffffff><SPAN lang=en-us
style="BACKGROUND-COLOR: #000000"> 150 </SPAN></FONT></P>
<P style="LINE-HEIGHT: 100%"><FONT color=#ffffff><SPAN lang=en-us
style="BACKGROUND-COLOR: #000000"> 200
</SPAN></FONT></P></TD></TR></TBODY></TABLE>
<P>
<P>
<P><B>當指針變量 P 通過<SPAN lang=en-us> new [] </SPAN>指向一連續的內存空間<SPAN
lang=en-us>:</SPAN></B>
<P><B>1、<SPAN lang=en-us>p[N] </SPAN>得到第N個元素 (<SPAN lang=en-us>0 <=
</SPAN>N <SPAN lang=en-us>< </SPAN>元素個數)<SPAN
lang=en-us>;</SPAN>2、<SPAN lang=en-us>*(p + N) </SPAN>同樣得到第N個元素 (<SPAN
lang=en-us>0 <= </SPAN>N <SPAN lang=en-us>< </SPAN>元素個數)</B>
<P>如<SPAN lang=en-us> p[0] </SPAN>或<SPAN lang=en-us> *(p + 0)
</SPAN>得到內存空間第<SPAN lang=en-us>0</SPAN>個元素;
<P>
<P>把上面右邊代碼中的大部分<SPAN lang=en-us> p </SPAN>替換為<SPAN lang=en-us>
arr</SPAN>,則和左邊代碼變得一模一樣。
<P>
<P>下面再來比較二者的不同。
<P>
<TABLE id=AutoNumber2 style="BORDER-COLLAPSE: collapse"
borderColor=#111111 cellSpacing=0 cellPadding=0 width="96%" border=1>
<TBODY>
<TR>
<TD width="48%">數組</TD>
<TD width="52%">指針</TD></TR>
<TR>
<TD width="48%"><SPAN lang=en-us>//</SPAN>定義并且初始化<SPAN
lang=en-us>:</SPAN>
<P><SPAN lang=en-us>int arr[</SPAN>20<SPAN lang=en-us>] =
{0,1,2,3,4,5,6,7,8,9,0,</SPAN>……<SPAN lang=en-us>,19}; </SPAN></P>
<P><SPAN lang=en-us></SPAN> </P></TD>
<TD width="52%"><SPAN lang=en-us>//</SPAN>定義、并且生成空間,但不能直接初始空間的內容:
<P><SPAN lang=en-us>int* p = new int[20] {0,1,2,3,4 </SPAN>……<SPAN
lang=en-us>} //<FONT color=#ff0000> </SPAN>錯<SPAN
lang=en-us>!</SPAN></FONT></P>
<P> </P>
<P><SPAN lang=en-us>//</SPAN>只得通過循環一個個設置:</P>
<P><SPAN lang=en-us>for (int i = 0; i < 20; i++)</SPAN></P>
<P><SPAN lang=en-us>{</SPAN></P>
<P><SPAN lang=en-us> p[i] = i;</SPAN></P>
<P><SPAN lang=en-us>}</SPAN></P></TD></TR>
<TR>
<TD width="48%">//不能通過對數組本身<SPAN lang=en-us> </SPAN>+<SPAN
lang=en-us> </SPAN>或<SPAN lang=en-us> </SPAN>-<SPAN lang=en-us>
</SPAN>來改變數組的位置:
<P><SPAN lang=en-us>arr = arr + 1; // </SPAN><FONT
color=#ff0000>錯<SPAN lang=en-us>!</SPAN></FONT></P>
<P><SPAN lang=en-us>cout << *arr << endl;</SPAN></P>
<P> </P>
<P><SPAN lang=en-us>arr++; // </SPAN><FONT
color=#ff0000>錯<SPAN lang=en-us>!</SPAN></FONT></P>
<P><SPAN lang=en-us>cout << *arr << endl;</SPAN></P>
<P> </P>
<P><SPAN lang=en-us>arr--; // </SPAN><FONT
color=#ff0000>錯<SPAN lang=en-us>!</SPAN></FONT></P>
<P><SPAN lang=en-us>cout << *arr << endl;</SPAN></P>
<P> </P>
<P>輸出結果<SPAN lang=zh-cn>:</SPAN></P>
<P><FONT color=#808080><SPAN lang=zh-cn>無,</SPAN>因為程序<SPAN
lang=zh-cn>有語法錯誤,</SPAN>通<SPAN lang=zh-cn>不</SPAN>過編譯。</FONT></P></TD>
<TD width="52%"><SPAN lang=en-us>//</SPAN>可以通過<SPAN lang=en-us>
</SPAN>+<SPAN lang=en-us> </SPAN>或<SPAN lang=en-us> </SPAN>-<SPAN
lang=en-us> </SPAN>操作直接改變指針:
<P><SPAN lang=en-us>p = p + 1;</SPAN></P>
<P><SPAN lang=en-us>cout << *p << endl;</SPAN></P>
<P> </P>
<P><SPAN lang=en-us>p++;</SPAN></P>
<P><SPAN lang=en-us>cout << *p << endl;</SPAN></P>
<P> </P>
<P><SPAN lang=en-us>p--;</SPAN></P>
<P><SPAN lang=en-us>cout << *p << endl;</SPAN></P>
<P> </P>
<P>輸出結果:</P>
<P style="LINE-HEIGHT: 100%"><FONT color=#ffffff><SPAN lang=en-us
style="BACKGROUND-COLOR: #000000"> 1 </SPAN></FONT></P>
<P style="LINE-HEIGHT: 100%"><FONT color=#ffffff><SPAN lang=en-us
style="BACKGROUND-COLOR: #000000"> 2 </SPAN></FONT></P>
<P style="LINE-HEIGHT: 100%"><FONT color=#ffffff><SPAN lang=en-us
style="BACKGROUND-COLOR: #000000"> 1 </SPAN></FONT></P></TD></TR>
<TR>
<TD width="48%">//<SPAN lang=zh-cn>釋放空間:</SPAN>
<P><SPAN lang=zh-cn>//數組所帶的空間由系統自動分配及回收</SPAN></P>
<P><SPAN lang=zh-cn>//無須也無法由程序來直接釋放。</SPAN></P></TD>
<TD width="52%">//<SPAN lang=zh-cn>釋放空間:</SPAN>
<P>//<SPAN lang=zh-cn>指向連續空間的指針,必須使用</SPAN>delete [] <SPAN
lang=zh-cn>來釋放</SPAN></P>
<P>delete [] p;</P></TD></TR></TBODY></TABLE>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -