精華區beta NTUE-CS102 關於我們 聯絡資訊
指標。 先附樣東西 照今年猜題內容寫的code http://www.mediafire.com/?jknoozzu2zl 各自取用。 -- 來講解指標...這部份講解請打開下頁的的Book1.xls 首先,請想像整個表單是已經被分塊的記憶體樣貌 : 也就是指每個格子都代表某個變數使用的空間 空白的可能是未使用,或是其他變數的位置,就先當作是平常說「未宣告區塊」那種狀況 打開以後應該都是在Sheet1這 直接看,你會看到B3、J11各有個765465 這裡把B3視做一個int變數,名稱為A,位址當然就是B3、存放的內容是"765465" 再來看J11,姑且稱為變數B,表面上都是765465,但是當你選取這格時 你會看到其實儲存格內容是"=B3",像這樣就是指標的用法 也就是,由一個變數B,去"向"被"記"的另一個變數A這樣 所以修改顯示值也好,移除數值也好,其實都是針對A在處理 這裡的B只是一個中繼點去表示A而已 對B做處理,最多最多就是我去把他標記的位置從B3移到B5這樣而已 -- Book1.xls http://www.mediafire.com/?jknoozzu2zl 這也是為什麼說,在同一個函式裡面用指標通常是很蠢的事情 在自己面前有塊餅乾,伸手就能拿來吃,幹嘛沒事還要叫人家幫忙拿呢? 所以說,這個指標就是用在函式間的連結 可能隔壁房間有我要找的東西,可是我現在忙著寫教學沒辦法過去拿 因此,我請一個路人幫我拿過來給我 像這樣的情況才會變得比較有意義 -- 回到主題來,繼續講一下指標的用法 int A; int *B; 這個*B的*,就是表示宣告為指標,至於指標為什麼還要特別指定型態這點 晚點會提到。 因為B這個名字,表示J11這個位址,而B只能存放另一個位址 : 請回頭看Book1.xls 所以是不能用 B=A; 這樣的寫法的,因為這樣是想把A裡頭765465放到B中 而不是把A的位址(B3)放進B,正確的寫法是 B=&A; &A即取得A的位址,然後利用=傳入B裡頭 -- 這裡你可能會誤寫成 *B=A; 這樣的行為當然是成立的,因為寫成*B 就會令*B等同B所標記的位址 (變成那個位址上的變數) 在此例中,因為沒有預設指定位址,所以會發生"不可預期的結果"這樣 好,初步說明到這個階段,再來是個小小的程式碼 利用指標,從主函式傳值到副函式輸出、改變數值後,再回到主函式輸出 -- #include<iostream> using namespace std; void print(int *a) { cout <<&a <<endl; *a=6 } int main() { int b=2; print(&b); cout <<b; } -- 輸出結果是 2 6 這樣,這裡附帶重新提一下 使用函式時副上的參數數 可以視為函式使用時是 int *a=&b 這樣的狀況,這樣記也許比較能夠避免錯誤 下頁是陣列 -- 這裡可以翻到sheet2了 對於陣列與指標的關係,大致上可以說"陣列名稱"就是指標 也就是呢...宣告一個陣列時,就只是指定一串記憶體為特定變數型態 然後由一個指標指定起點 比如說sheet2中 C2到H2就是一串陣列A : 畫成橫的感覺比較順,所以請不要挑剔(跑) 在電腦中只會去記憶&A=C2,然後每個變數佔用的記憶體單位 這也是為什麼我們的陣列初始從A[0]開始用,表示從被記錄的位址數起第零個 所以說,在傳陣列到函式時 用法會是 void funtion(int *point){;} int main(){ int name[10]; funtion(name); } -- 因為name 表示的就是一個位址,所以不用對name取位址(不用寫成&name) 就能讓函式內參數順利接受這個位址 到這邊都不是問題...吧(?) 對於這個陣列如何在函式內使用... 大概可以分成 1.照基本概念走 從位址起算 *(point+n) n為任意整數 2.當一般陣列用 point[n] n為任意整數 隨意舉個例 *point 等價於 point[0] *(point+1) 等價於 point[1] 以下類推。 -- 下一項是利用指標傳二維陣列進函式 這部份先繼續參照sheet2 C6:H8這段範圍 就當作我宣告int array[3][6];,表示這個二維陣列的樣子這樣 當然,傳進去不能像一維那樣使用,不然就沒什麼好說的了 這裡先有個基礎,不論宣告幾維陣列或陣列大小,在給予記憶體空間時一定是一串的 : 請翻到sheet3,C6:T6這整段才是array[3][6]在記憶體的樣子,而不是分布在C6:H8 而作為起點的位址也還是只有一個 C6,不會因為三列而有三個起點 可是,這個陣列大小是不會隨著函式被傳遞的 不能說傳進一個起點,就要函式能主動判斷幾列幾行 : 利用指標控制陣列時,腦袋不清楚很容易用到不該使用的範圍,請多加注意 所以說...要在宣告時告訴函式每一個子陣列的起點分別在哪 -- 這部份的作法是:宣告一串一維陣列擺指標,然後讓指標放各個陣列的起點 這樣一個擺放指標的陣列,稱為指標陣列 宣告方法是 (*point)[6] ^^^^^^ ^^ 變數名稱 陣列大小 這個變數名稱會再被傳入的數值取代,構成一個二維函式 或許換個方式說成是宣告N個佔用6單位記憶體的變數更能理解...? : 拿回sheet3看,就是有一個變數代表C2:H2這段,下個變數表示I2:N2...(下略) 與 *point[6]不同,解釋會變成 ^^ ^^^^^^^^ 指標 一維陣列 →→ 放六個指標的一維陣列 在意義上就有些不同了 正確用法如下 void funtion(int *point)){;} funtion(name); -- 好像沒什麼好寫的 就先這樣好了(思) -- 違背命運是人之常情。   人們從在犯了錯之後,才向神明祈禱以求補償。                   狼與辛香料 克拉福‧羅倫斯 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 58.114.76.199
dosomethnig:GOOD 01/08 19:34
gcobc12632:我想直接把以前全部寫的作業都帶過去 然後慢慢參考= = 01/08 19:56
Arashinoon:未看先推 01/08 23:22
j2612280:我發現錯誤啦!! 第六頁的cout <<a <<endl;是印出住址 01/12 20:33
※ 編輯: game0416 來自: 58.114.76.199 (01/12 21:08)
j2612280:呃..我說的是輸出結果不是2啦~是住址才對 01/13 00:03
game0416:輸出內容才是那段的目的啊qq 01/13 00:11