Re: [問卦] 有沒有學習 C 語言指標的好方法?

看板Gossiping作者 (吹笛牧童)時間3年前 (2020/09/20 02:20), 3年前編輯推噓18(1809)
留言27則, 18人參與, 3年前最新討論串4/4 (看更多)
我們從機械語言定址法說起好了 絕對定址法: 比如,從位址 0x300 取出值,放入累加器 間接定址法: 比如,從位址 0x300 取出值,這個值又當成位址,再去該位址取出其值,放入累加器 組合語言應該是不會那麼三八,給你兩層三層的間接定址的 但 C 語言可以,每多打一個星號取出其值,就是取出的值再間接定址一次 但事實上還不是湊出來的 :P 前面說了,值取出後放入累加器 那我就把累加器的值不當值,當成位址,再取一次就好啦 在機械語言裡這麼直觀的東西 在 C語言裡,說"為了你方便",有點不一樣 0x300+1 是多少? 0x301 嘛,對吧~ 但如果在 C, 就會說指標指的物件是有 size 的 如果是個 word, 那麼 0x300 + 1(word) = 0x302 也就是那個 1,必需賦與單位,單位是 word 就這樣而已,差別不大 XD 但這在陣列裡算好用的 比如一個 size = 32 byte 的元素 0x300 + 1(32byte) = 0x320 在陣列就真的好用 要把 0x300 當數值用時,比如當 word, 其實就是 (word)0x300 就算它本來是指標,也會被 cast 成 word 要把 0x300 當指標用時,就算它本來是word, 只要你 cast 下去,就會變指標 (void*)0x300 像這樣,它就變指標 一般來說,我們不胡搞,以免自己受不了 可是當你在看別人程式時,你無法禁止別人胡搞 如果跨模組時,直接胡搞更是把不同模組黏起來最快的方法 就像拿全域變數寫程式一樣,又爽又危險 XD 所以就算本來宣告 int ***a; 說 a 是個三層指標好了 可是我要用時,馬上 cast (int**)a 這樣用 你受不了又怎樣呢?就是可以 XD 一個變數要被視為什麼,是要'活在當下'的 當下怎麼用它,它就是什麼 如果你不確定,就多步進執行或加 print 去看它 而因為指標的加一減一,事實上是帶單位的 所以記得 sizeof 偶爾要用用,去檢查檢查它是不是你所想的那麼一回事 回到 怎麼學能學好 你要故意學很高深當然可以,就好像學生時微積分學到很難,出社會後好像沒在用 你常用的程度自然就會熟了 我是蠻愛用指標的,因為它可以創造物件的分身 寫程式時要注意本尊只有一個,其他都用分身 這樣的好處是不用注意物件的 sync 問題 比如, a=3 , b=a, 然後 a=4 b 是拷 a 的值,但 a 改成 4 之後,b 卻沒一起改 這就是複製的缺點 用分身的話,a 的改變,b 不用通知也會跟著變,多好... 而一堆人都要用變數,到底把本尊放在哪好? 那就是程式架構的問題了 本尊一定要最早產生,最後消滅 如果沒這特性,比如上面的 a 先消滅,b 又保留 a 的值要繼續使用 那 b 不就從分身轉而為本尊的地位? 這麼複雜的擁有權轉移,很容易讓人暈頭轉向的 但也不是絕對不做;觀念清楚就可以 於是我們漸漸會確立物件是個有形有質的'東西' 要好好保管,或好好轉移擁有權 這有形有質的概念堅持下來,物件導向就很有感覺 物件導向不是 class, private, public, method 這些字眼而已 它就是把一群變數好好的當成物件去保管,以有形有質去對待它 有這概念,就算用 c 都可以寫出物件導向 我第一次寫二元數排序,照著課本做就失敗了 後來連續做兩次都失敗,但我確定校對兩次,絕對沒打錯 結論很簡單:課本印錯了,誤人子弟 XD (第一次成功,就是拋開課本,自己寫就成功了) 若再加上硬 cast 指標以讓程式會動的這些 code 可以說糊成一團粥的機率大增 那還是會自己檢查指標比較重要 檢查下去你就知道那些指標運算在幹麻 像 COM 的巨集裡也在運算指標,我看了就很暈 但拆開來步進一下就懂 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 49.216.189.45 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/Gossiping/M.1600539650.A.350.html

09/20 02:21, 3年前 , 1F
看了這一串 我還是乖乖待python 就好了
09/20 02:21, 1F
鄉民當然要用 python, 它怎麼翻譯的?它和我褲子裡那條意思是一樣的 另外城市獵人的那把槍,也叫 python

09/20 02:24, 3年前 , 2F
看完這篇...我今晚可以很好睡了
09/20 02:24, 2F
再給個番號更好睡

09/20 02:24, 3年前 , 3F
09/20 02:24, 3F
※ 編輯: HuangJC (49.216.189.45 臺灣), 09/20/2020 02:26:06

09/20 02:28, 3年前 , 4F
有看有推
09/20 02:28, 4F

09/20 02:30, 3年前 , 5F
不同環境平台指標用多了會出現奇奇怪怪現象
09/20 02:30, 5F

09/20 02:30, 3年前 , 6F
牛逼 第一次學樹 堆的時候真d痛苦
09/20 02:30, 6F

09/20 02:30, 3年前 , 7F
到後來變成少用指標的好
09/20 02:30, 7F
C 的指標有陷阱啊 XD 2D 陣列有兩種做法 一種是等長的一維陣列,組成二維 一種是不等長的一維陣列,組成二維 這兩種陣列的取值都是兩個星號,但骨子裡不一樣 而這個不一樣又只有 compiler 在肚子裡知道 所以要常用 sizeof 去檢查,就會知道問題了

09/20 02:32, 3年前 , 8F
以前一直對物件導向不太了解,都傻傻地用
09/20 02:32, 8F
※ 編輯: HuangJC (49.216.189.45 臺灣), 09/20/2020 02:34:46

09/20 02:35, 3年前 , 9F
大端小端對齊就夠你搞,還是不要用指標比較通用
09/20 02:35, 9F

09/20 02:39, 3年前 , 10F
感謝分享!物件本尊分身那跟檔案系統的 inode link 好
09/20 02:39, 10F

09/20 02:39, 3年前 , 11F
像。
09/20 02:39, 11F

09/20 02:43, 3年前 , 12F
用c做出物件導向的特性會有點累
09/20 02:43, 12F
我是不得已的啊,我先學會了物件導向,才碰到工具... 相反的看到人用工具,肚子裡裝的不是物件 才知道觀念不通的人永遠都不通 XD ※ 編輯: HuangJC (49.216.189.45 臺灣), 09/20/2020 02:45:10

09/20 02:49, 3年前 , 13F
推字多好睡~
09/20 02:49, 13F

09/20 02:54, 3年前 , 14F
看得半懂 但有收穫 推
09/20 02:54, 14F

09/20 03:00, 3年前 , 15F
淺顯易懂,讚
09/20 03:00, 15F

09/20 03:06, 3年前 , 16F
推 看來我還是乖乖寫php就好
09/20 03:06, 16F

09/20 04:46, 3年前 , 17F
只要看到書裡寫連兩個星號**才認為4高手的 把牠當渣就好
09/20 04:46, 17F

09/20 04:48, 3年前 , 18F
故意複雜化、玩符號艱澀耍婊藝術 高來高去的 都當渣就好
09/20 04:48, 18F

09/20 04:51, 3年前 , 19F
老外教學 也沒有教人專練這種功 來婊人的 有叫他去吃屎
09/20 04:51, 19F

09/20 08:33, 3年前 , 20F
優文 還有連範例都錯 這書也太爛 XD
09/20 08:33, 20F

09/20 08:36, 3年前 , 21F
身為python和golang黨表示自己很幸福,很少看到一堆*號的
09/20 08:36, 21F
一個星號代表查一次表,只要每一層表格都有命名 也就是把抽象概念具象化,自然不需要多層星號 一次取出一層即可,並且用表格名字去承接 只有當抽象到暈頭轉向時程式才會看不懂 但事實上你早就在用多層指標了;一定有 光是字串就是一維 char* str1 = 'hello' char* str2 = 'world' 字串串成文章就是二維 text *text1; (在此我省略空間的產生及釋放;直接使用) text *text2; text1[0] = str1 text1[1] = str2 多篇文章難道在系統裡過份?那就三維了 texts[0] = text1 texts[1] = text2 當要取出第一篇文章的第一行的第一個字時 texts[0][0][0] <= 這什麼鳥?一次解三維? 或者 text = texts[0] <= 先取出文章 str = text[0] <= 再取出字串 a = str[0] <= 再從字串取出字元 有難嗎?其實三層不是早就在用了? 只因為每層結構都有命名,一次取用一層,你以為沒在用而已 ※ 編輯: HuangJC (49.216.189.45 臺灣), 09/20/2020 12:04:56 ※ 編輯: HuangJC (49.216.189.45 臺灣), 09/20/2020 12:11:51

09/20 18:26, 3年前 , 22F
不可能學好 它表達方式本身就爛
09/20 18:26, 22F

09/21 00:59, 3年前 , 23F
它那個表達不錯了,C 的初衷是取代組合語言,最接近底層
09/21 00:59, 23F

09/21 00:59, 3年前 , 24F
的高階語言,所以如果高階到一個境界,無法預測底層怎麼
09/21 00:59, 24F

09/21 01:00, 3年前 , 25F
實作組合語言是不可以的;而要能手把手代換成組合語言
09/21 01:00, 25F

09/21 01:00, 3年前 , 26F
那麼取值是 *,取址是 &,已經簡單到不能再簡單
09/21 01:00, 26F

09/21 01:01, 3年前 , 27F
它是寫 driver 最好的語言,不怎麼打算給你寫超高階啊..
09/21 01:01, 27F
文章代碼(AID): #1VPam2DG (Gossiping)
文章代碼(AID): #1VPam2DG (Gossiping)