作者 主題: C語言-寫作風格  (閱讀 27750 次)

0 會員 與 1 訪客 正在閱讀本文。

stlee

  • 鑽研的研究生
  • *****
  • 文章數: 817
    • 檢視個人資料
C語言-寫作風格
« 於: 2007-03-01 16:13 »
又再重灌了,來打屁一下吧!

風格這種東西就像藝術,每個人都有不同的標準,您說這樣好,我說那樣棒,都沒個準的
不過如果是"良好習慣"的風格,相信寫程式這回事就不是什麼痛苦的事了
其實寫程式不辛苦,辛苦(痛苦)的是debug除錯了,以前曾花一天寫了一個自認為滿屌的功能
後來這個功能花了兩個禮拜去除錯--->真的是太屌了
至於"良好習慣"其實本人沒受過正規訓練,只是一些經驗談,因為覺得學電腦不是在學"成功"
的經驗而是要去學習"失敗的經驗",您沒失敗過怎麼知道這樣做不行,那樣做可以呢,而且我很
多朋友知道我會寫程式,直覺的都認為我"電腦一定很厲害"....

會寫程式可不是筋開,腰軟,會旋轉了 :lol: 不會的更多阿

來說說我的失敗經驗吧
程式最忌幫使用者預設他的使用範圍,當然這需要一點實做經驗
才能有所體會,所謂實做經驗就是被客戶要求改東改西然後原來寫的幾乎體無完膚或作廢
悶著頭寫程式的品質會不錯(內行人看起來),可是您寫的程式是要給他使用上手後您會
翹起大拇指對他說"您真內行"^^!還是那些電腦白痴呢?(我遇到的都是後者)
所以寫作期間與未來的使用者進行溝通是必要的,您不一定要跟他討論技術細節,只要在寫
作某項功能(搜尋想怎麼打,日期要不要加等等的)跟他問一下,當您開始跟他溝通後,他反而
會開始提供您當初想都想不到的一些情報(相信我,我吃過這種甜頭)雖然很多都是沒用的
可是要的是那些偶爾才出現的"天籟之音"啊,幾通電話的投資報酬率是很高的 :wink:

事前的規劃(資料蒐集)應佔很大的比重,前年寫過一個職棒三四星的計算軟體(比六和彩複
雜100倍),約年初一月寫三月底交件,事後也沒遇到很大的bug(測試兩個禮拜中抓到一些
小bug)然後客戶用到現在也沒說有問題^^,是我功力高強嗎?還是我筋開,腰軟,會旋轉了,
都不是.....在寫作開始前(大前年中秋後)就開始蒐集資料及一些紙上作業,並請教客戶她
們實際運作狀況等等到實際上機寫程式時其實只是做一些使用者操作介面及更早之前程式
(也是我寫的相關軟體)的資料上的連結(不能叫他分開算吧)而已,其實寫的時候是很快樂
的啦並沒有痛苦(抓蟲抓到人都要彌留了)的事情發生^^

寫作時成對的東西連著打,比如叫用malloc(a)後馬上跟著free(a)然後中間再隔一些空
白列,if()時裡面的判斷式別想一行搞定很複雜的判斷
if((((a==b || b==c) &&(aa())) || (c=d)) && (c==(bb()+x) && cc()))
別跟我說您看得懂上面是啥東西,我自己都不知道在寫什麼了別說看懂
可是如果是這樣
代碼: [選擇]

if(
    (
      (
        (
          (a==b || b==c) && aa()
        ) ||  
        (c==d)
      )
    ) &&
    ( c==(bb()+x) &&
      cc()
    )
  )

if()裡面也是可以縮排的啦 :wink:

快跑完了....有空再補充吧
程式是人寫的,別讓工具的限制成為您想像力的極限
~程式中最重要的部份應該是註解而不是程式碼,這是因為解讀註解一定比解讀程式碼簡單
~程式寫好後約一個月就會忘的差不多了,所以花點時間把註解寫好至少能讓自己(或別人)看的懂當初在寫什麼

elleryq

  • 鑽研的研究生
  • *****
  • 文章數: 908
  • 性別: 男
    • 檢視個人資料
    • Thinking more...
C語言-寫作風格
« 回覆 #1 於: 2007-03-01 23:00 »
今天才看到的好東西:Nelson 的遊樂場 - [分享] UniversalIndentGUI - 重整程式碼的工具 :: PIXNET BLOG ::
不妨試試看~
他算是一個 frontend 工具~

不是在 Windows 下的話,用 indent 或 astyle 直接排也可以~
Plan your work, then work your plan.
我的首頁:http://blog.elleryq.idv.tw
351899by http://counter.li.org

stlee

  • 鑽研的研究生
  • *****
  • 文章數: 817
    • 檢視個人資料
C語言-寫作風格
« 回覆 #2 於: 2007-03-02 02:54 »
引述: "elleryq"
今天才看到的好東西:Nelson 的遊樂場 - [分享] UniversalIndentGUI - 重整程式碼的工具 :: PIXNET BLOG ::
不妨試試看~
他算是一個 frontend 工具~

不是在 Windows 下的話,用 indent 或 astyle 直接排也可以~


很棒的工具喔^^

只能翹起大拇指對elleryq大大說--->"您真內行" :wink:
程式是人寫的,別讓工具的限制成為您想像力的極限
~程式中最重要的部份應該是註解而不是程式碼,這是因為解讀註解一定比解讀程式碼簡單
~程式寫好後約一個月就會忘的差不多了,所以花點時間把註解寫好至少能讓自己(或別人)看的懂當初在寫什麼

netman

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 17407
    • 檢視個人資料
    • http://www.study-area.org
C語言-寫作風格
« 回覆 #3 於: 2007-03-02 09:45 »
哈,感謝 stlee 兄分享!
有空再多些來傳授密招哦~~~  ^_^

ricky

  • 實習板主
  • 鑽研的研究生
  • *****
  • 文章數: 669
    • 檢視個人資料
    • Ricky 碎碎唸
C語言-寫作風格
« 回覆 #4 於: 2007-03-02 09:51 »
呵呵
只能說C是個神秘語言
可以寫的很清楚,也能夠寫的讓人完全看不懂
還記得曾舉辦過 "闇黑" C 語言程式大賽
目的就是要寫出個 "最讓人看不懂" 的Hello world
最重要的是... "還得符合Ansi C"

int i;main(){for(;i["]<i;++i){--i;}"];read('-'-'-',i+++"hello, world!\n",'/'/'/'));}read(j,i,p){write(j/p+p,i---j,i/i);}

傳說中的經典  :D
1984年的得獎作品
在.Net or gcc 都還可以過
我的symfony作品:YOMOpets 寵物誌
有興趣可以一起來討論symfony喔
我的部落格:http://ricky.ez2.us/

stlee

  • 鑽研的研究生
  • *****
  • 文章數: 817
    • 檢視個人資料
C語言-寫作風格
« 回覆 #5 於: 2007-03-02 14:53 »
引述: "ricky"
呵呵
只能說C是個神秘語言
可以寫的很清楚,也能夠寫的讓人完全看不懂
還記得曾舉辦過 "闇黑" C 語言程式大賽
目的就是要寫出個 "最讓人看不懂" 的Hello world
最重要的是... "還得符合Ansi C"

int i;main(){for(;i["]<i;++i){--i;}"];read('-'-'-',i+++"hello, world!\n",'/'/'/'));}read(j,i,p){write(j/p+p,i---j,i/i);}

傳說中的經典  :D
1984年的得獎作品
在.Net or gcc 都還可以過


以前就聽說了,今天總算看到 :D

果然只有一行,果然經典 :D  :)  :lol:  :P  :wink:
程式是人寫的,別讓工具的限制成為您想像力的極限
~程式中最重要的部份應該是註解而不是程式碼,這是因為解讀註解一定比解讀程式碼簡單
~程式寫好後約一個月就會忘的差不多了,所以花點時間把註解寫好至少能讓自己(或別人)看的懂當初在寫什麼

stlee

  • 鑽研的研究生
  • *****
  • 文章數: 817
    • 檢視個人資料
C語言-寫作風格
« 回覆 #6 於: 2007-03-02 14:58 »
引述: "netman"
哈,感謝 stlee 兄分享!
有空再多些來傳授密招哦~~~  ^_^


 :D 有空!有空!當然有空啊! :D

也很感謝您提供這麼棒的地方喔 :D
程式是人寫的,別讓工具的限制成為您想像力的極限
~程式中最重要的部份應該是註解而不是程式碼,這是因為解讀註解一定比解讀程式碼簡單
~程式寫好後約一個月就會忘的差不多了,所以花點時間把註解寫好至少能讓自己(或別人)看的懂當初在寫什麼

stlee

  • 鑽研的研究生
  • *****
  • 文章數: 817
    • 檢視個人資料
C語言-寫作風格
« 回覆 #7 於: 2007-03-03 16:47 »
為變數,函數,功能.....取個"好名字"在寫作中的重要性很多人都會忽略
所謂的好名字不是要給他取得很有"文學氣息","很強"或之類的,真正的好名字是"好記"
怎麼個"好記"法呢?,這完全因個人習慣,說說我的習慣吧
曾貼過一個[不限位數的四則運算]原碼
http://phorum.study-area.org/viewtopic.php?t=43966
裡面的函數開頭都是lee_xxxxx,其實我寫的所有函數都是以這個規則來命名的
(lee是LinuxEucEdit的簡寫)這是去年寫文書處理器(在Linux平台開始建立的第一個函
數庫)所沿用下來的,而第二個是專案名稱最後才是函數名稱,要拿專案名稱在前面也可以
啦,可是千萬不要只有函數名稱,原因是您已經確定知道所有標準,商用函數的所有名稱了
嗎,有沒有可能重覆(我還真的遇到過呢--->改了三天:x ),當然這可以透過原型宣告的手
段來避免,不過原型宣告是另一項習慣,現在都是這兩個方法並用
例如printf()要include<stdio>當您沒需要printf()時是不會去include<stdio>的
所以當您自己寫了一個printf()後有要用到標準函數時去include<stdio>了-------->改三天

而這樣命名第一個好處是,在以後的專案中只要有"bug"發生時會非常容易除錯;命名和除
錯怎麼扯得上邊??一個程式(專案)不會所有的函數都是您自己寫的吧,當然會叫用一些標
準函數庫啦,商用函數庫啦等等的,當程式出現bug時我慣用的是getch()除錯,也就是在程
式中插入printf("11111\n")後馬上接getch()然後程式會在執行到getch()時停下來,在
停下來之前由於前一個是printf()所以當有一個沒顯示出來我就知道程式是當在哪一段,這
樣逐步逐步縮減範圍最後把蟲抓出來

如果有固定的命名規則時您將會發現其威力的強大因為寫過程式的都知道"天下沒有不會
出錯的程式"所以您怎麼確定您今天寫出認為完美的函數能接收所有您客戶所輸入的資料
呢,別忘記您的客戶都是"電腦白痴",就算您的客戶不是電腦白痴,您也要預定她們都是"電
腦白痴"這樣一來真的遇到了也不用怕他真的"粉白癡"了(好像在繞口令喔 :x )

好,既然程式會出錯您也抓到是哪裡錯了,別以為真的是那一行錯了,怎麼抓到那一行錯卻
不是那一行錯呢??哈哈!不由得您不信事情就是這樣的,別以為標準函數庫不會錯,當您傳
給他的資料本身就是錯的或超出其處理範圍,使用標準函數庫的那一行就是個錯了

解決辦法是自己寫一個標準函數庫還是改變您傳給他的參數呢??答案您已經知道了,這又
和命名有何關係??要知道有些時候是無法準確的知道是哪一行出錯的(尤其是記憶體溢位)
而是在某個範圍, 這個時候如果此範圍有一些標準函數也有一些您自己寫的函數時.........

所以遇到這種情形我就知道從這兩個方向除錯先
1.先檢查一些資料是否宣告錯誤(翻一下函數庫的書)
2.再檢查自己(已有規則的命名)寫的函數裡面所接收的參數的初始,處理中,處理後的變化

這樣除錯就很快樂啦 :wink:
程式是人寫的,別讓工具的限制成為您想像力的極限
~程式中最重要的部份應該是註解而不是程式碼,這是因為解讀註解一定比解讀程式碼簡單
~程式寫好後約一個月就會忘的差不多了,所以花點時間把註解寫好至少能讓自己(或別人)看的懂當初在寫什麼

stlee

  • 鑽研的研究生
  • *****
  • 文章數: 817
    • 檢視個人資料
C語言-寫作風格
« 回覆 #8 於: 2007-03-05 17:22 »
呵呵!要在硬碟裡"找一個字",應該會找很久,就來說說"找"吧

基本上只要能"讀得到"就"寫得進",但要如何讀到,讀到的是否正確您必須要能去"看得到"
說起來很複雜,做起來其實很簡單,比如您有一些資料要從檔案取出後作一些處理,可是不管
您怎麼處理他就不是您想要的結果!!!這個時候您應該會一直想說:哪裡處理錯了,怎麼不是
這個結果!!!其實我門把問題往回想:取出的是正確的資料嗎,如果取出的是錯誤的資料,
就算您叫托瓦茲來寫處理方面,跟您賭一塊錢--->他也寫不出來

所以啦怎麼知道取出的是否正確呢??printf()會用吧,每讀一筆資料出來就在後面跟一個
printf()就好啦--->在迴路內追蹤(觀察)每次處理的結果

這樣一來連除錯都免了 :wink:
程式是人寫的,別讓工具的限制成為您想像力的極限
~程式中最重要的部份應該是註解而不是程式碼,這是因為解讀註解一定比解讀程式碼簡單
~程式寫好後約一個月就會忘的差不多了,所以花點時間把註解寫好至少能讓自己(或別人)看的懂當初在寫什麼

thyme

  • 老人組
  • 俺是博士!
  • *****
  • 文章數: 1281
    • 檢視個人資料
C語言-寫作風格
« 回覆 #9 於: 2007-03-05 17:43 »
好的寫作風格還要配合好用、順手的工具,
我在 linux 上寫 C 的編輯器,都是用 vi (多程式相關就用gvim),
除錯時就用 ctags 及 cscope 工具(很好用唷^_^),
有時懶得開 cscope 就直接用 grep 搜尋,
遇到 kernel 或是 Xorg source code,就非得請出 cscope 了。
好的寫作風格真的有助 debug 。
基於平台的關係,對我來說,printf 、 echo 也是相當重要的 debug 工具。

anderson1127

  • 訪客
C語言-寫作風格
« 回覆 #10 於: 2007-03-06 00:39 »
引述: "stlee"

所以啦怎麼知道取出的是否正確呢??printf()會用吧,每讀一筆資料出來就在後面跟一個
printf()就好啦--->在迴路內追蹤(觀察)每次處理的結果

這樣一來連除錯都免了 :wink:


喔......這招我記得我以前專科時代寫Dbase + Clipper 就常常用!! 不然還真不曉得
我到底那裡寫錯了!!

後來寫C/Perl/PHP 等等都還是維持這個怪怪的習慣 來幫忙做Debug !!

stlee

  • 鑽研的研究生
  • *****
  • 文章數: 817
    • 檢視個人資料
C語言-寫作風格
« 回覆 #11 於: 2007-03-07 17:32 »
前面曾講過:不要幫使用者預設他的使用範圍,說起來簡單,做起來也那麼簡單嗎
其實是有一點點[眉角]的(當然這也是我的一點點[習慣]可能與您認知的不一樣)

一般來說當寫到一段程式碼有重覆出現(或兩段類似)的情況時,我會不假思索的把它寫成
一個函數,就算真的只有這兩個地方會去呼叫它,可是這並不代表以後的專案中不會有這
種情形發生,到時就算該函數與實際情況並不相同,但當初拆出來的函數可是一個非常好
的[範本]呢

:D  :D   是的!一個使用C語言寫程式的人最大的資產就是[函數庫]了   :D  :D

但這與預設使用者範圍有何關係,打個比方:當要處理的是一個二維陣列的資料時我會這
樣宣告這個函數
代碼: [選擇]
lee_str(char *str,int y,int x)
這樣宣告的意義相當於str[y]
  • ,就算他是一個以malloc()宣告的一維陣列記憶體區

段我還是會這樣宣告它,這樣做的好處明眼人一眼就看出來他能處理的範圍並不限在函
數本身,而是限制在該函數的呼叫者而當呼叫者是以malloc()宣告該二維陣列(二維陣
列可以想成只是在一維陣列固定位數中插入字串結束符號但這不包括不定長度二維陣列
(其實意思差不多))也可以被正確處理的

所以當您以後有要字串做相同處理時,呵呵!!寫程式真的是越做越輕鬆的工作啦 :wink:
而且更重要的是,他也很容易除錯,也就是現在一個很熱門的話題[模組化],當然模組化並
不是只有把程式拆開來的觀念那麼簡單,不過把程式拆開成一段一段的函數後您會發現
寫程式這件事並不如想像中那麼複雜的啦---->複雜的是設計
程式是人寫的,別讓工具的限制成為您想像力的極限
~程式中最重要的部份應該是註解而不是程式碼,這是因為解讀註解一定比解讀程式碼簡單
~程式寫好後約一個月就會忘的差不多了,所以花點時間把註解寫好至少能讓自己(或別人)看的懂當初在寫什麼

elleryq

  • 鑽研的研究生
  • *****
  • 文章數: 908
  • 性別: 男
    • 檢視個人資料
    • Thinking more...
C語言-寫作風格
« 回覆 #12 於: 2007-03-08 08:33 »
引用
一般來說當寫到一段程式碼有重覆出現(或兩段類似)的情況時,我會不假思索的把它寫成
一個函數,就算真的只有這兩個地方會去呼叫它,可是這並不代表以後的專案中不會有這
種情形發生,到時就算該函數與實際情況並不相同,但當初拆出來的函數可是一個非常好
的[範本]呢

延伸閱讀:重構─改善既有程式的設計 « 書籍比價 « Findbook
Plan your work, then work your plan.
我的首頁:http://blog.elleryq.idv.tw
351899by http://counter.li.org

stlee

  • 鑽研的研究生
  • *****
  • 文章數: 817
    • 檢視個人資料
C語言-寫作風格
« 回覆 #13 於: 2007-03-08 15:50 »
"見縫插針","大事化小","小事化大"是必須勤練的招式,最好練到"看到黑影就開槍"

比如說當您在寫作一個與系統有關的函數時,可能有要叫用一些系統函數,這些系統函數絕
對不只有一個參數可讓您傳入,可能他會依您所傳入的值決定要處理的方向及結果,這種函
數在您將程是拆成很多個小函數後就知道為什麼要這麼幹了--->太多重覆的原碼了

但是有些時候您並無法知道這些系統函數能幫您做些什麼,或您要的結果是否他能辦得到??
所以這時"見縫插針"的功夫就要拿出來了,以stat()函數來說,他是一個標準函數,相信在很多
函數庫的書上都有介紹:取得檔案狀態;當初看到這個函數的功能時實在無法和"權限"拉上
關係,但"unix系統將所有東西都視為檔案"的句子被我在書上看到時,決定再更深入去研究
研究,終於把之前有些檔案存取失敗(權限不足)的問題給徹底解決了

當然一開始不是就能存取到所有檔案的,而是使出"小事化大"這招寫了好多個小函數來達成
最後再使出一招"大事化小"把它整合成一個能開啟任何權限(有些特殊權限還不行但已能應
付自己應用程式內對檔案的需求)的存取檔函數....呵呵!以後寫檔案存取都會唱~~快樂的不得了~~呢

先求能用,再求精簡,再求速度 :wink:
程式是人寫的,別讓工具的限制成為您想像力的極限
~程式中最重要的部份應該是註解而不是程式碼,這是因為解讀註解一定比解讀程式碼簡單
~程式寫好後約一個月就會忘的差不多了,所以花點時間把註解寫好至少能讓自己(或別人)看的懂當初在寫什麼

shihyu

  • 活潑的大學生
  • ***
  • 文章數: 223
    • 檢視個人資料
C語言-寫作風格
« 回覆 #14 於: 2007-03-09 13:42 »
引述: stlee


當然一開始不是就能存取到所有檔案的,而是使出"小事化大"這招寫了好多個小函數來達成
最後再使出一招"大事化小"把它整合成一個能開啟任何權限(有些特殊權限還不行但已能應
付自己應用程式內對檔案的需求)的存取檔函數....呵呵!以後寫檔案存取都會唱~~快樂的不得了~~呢


引用



小事化大 ---> 是說寫很多小函式存取各種檔案
大事化小 ---> 是用一函式去控制上面的很多小函式包含在這函式裡面傳入參數呼叫所要的存取檔案嗎???

有無代碼可以參考看看^^

謝謝

stlee

  • 鑽研的研究生
  • *****
  • 文章數: 817
    • 檢視個人資料
C語言-寫作風格
« 回覆 #15 於: 2007-03-09 16:28 »
引述: shihyu
引述: stlee


當然一開始不是就能存取到所有檔案的,而是使出"小事化大"這招寫了好多個小函數來達成
最後再使出一招"大事化小"把它整合成一個能開啟任何權限(有些特殊權限還不行但已能應
付自己應用程式內對檔案的需求)的存取檔函數....呵呵!以後寫檔案存取都會唱~~快樂的不得了~~呢


引用



小事化大 ---> 是說寫很多小函式存取各種檔案
大事化小 ---> 是用一函式去控制上面的很多小函式包含在這函式裡面傳入參數呼叫所要的存取檔案嗎???

有無代碼可以參考看看^^

謝謝


http://phorum.study-area.org/viewtopic.php?p=222657#222657
參考看看喔^^不過它是把檔案"映射"到記憶體,再去處理記憶體.....當然,只有"取檔",而
存檔呢,每個專案所要存的應該都不一樣,所以我就沒寫存檔的部份,這也是我的一個小習
慣[盡量只寫"殼",不寫"程式"]
程式是人寫的,別讓工具的限制成為您想像力的極限
~程式中最重要的部份應該是註解而不是程式碼,這是因為解讀註解一定比解讀程式碼簡單
~程式寫好後約一個月就會忘的差不多了,所以花點時間把註解寫好至少能讓自己(或別人)看的懂當初在寫什麼

stlee

  • 鑽研的研究生
  • *****
  • 文章數: 817
    • 檢視個人資料
C語言-寫作風格
« 回覆 #16 於: 2007-03-09 16:34 »
補充:
裡面有個FM_RWXRWXRWX請自行翻函數庫的書定義成-rwxrwxrwx的權限值即可
(那一個.h擋~~樂樂長~~所以我沒貼上來,而且只用到一個FM_RWXRWXRWX)
程式是人寫的,別讓工具的限制成為您想像力的極限
~程式中最重要的部份應該是註解而不是程式碼,這是因為解讀註解一定比解讀程式碼簡單
~程式寫好後約一個月就會忘的差不多了,所以花點時間把註解寫好至少能讓自己(或別人)看的懂當初在寫什麼

netman

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 17407
    • 檢視個人資料
    • http://www.study-area.org
C語言-寫作風格
« 回覆 #17 於: 2007-03-10 00:44 »
呵,真是學到不少呢!
不知道 stlee 大要不要來跟大家分享一場講座啊?
我們台南三月剛好缺講師呢~~~  ^_^

stlee

  • 鑽研的研究生
  • *****
  • 文章數: 817
    • 檢視個人資料
C語言-寫作風格
« 回覆 #18 於: 2007-03-10 02:46 »
引述: "netman"
呵,真是學到不少呢!
不知道 stlee 大要不要來跟大家分享一場講座啊?
我們台南三月剛好缺講師呢~~~  ^_^


netman大大您別嚇小弟 :o 我這點墨水上台出出洋相還可以....饒了小弟這一次吧

這裡寫得差不多時倒是可以一起分享分享甘苦談的 :D
程式是人寫的,別讓工具的限制成為您想像力的極限
~程式中最重要的部份應該是註解而不是程式碼,這是因為解讀註解一定比解讀程式碼簡單
~程式寫好後約一個月就會忘的差不多了,所以花點時間把註解寫好至少能讓自己(或別人)看的懂當初在寫什麼

stlee

  • 鑽研的研究生
  • *****
  • 文章數: 817
    • 檢視個人資料
C語言-寫作風格
« 回覆 #19 於: 2007-03-10 04:43 »
有些時候換個角度,甚至是完全相反的方向去思考有時候說不定能找到不錯的辦法
就拿"搜尋字串"來說,您認為"找得到"比較快,還是"找不到"比較快??

曾在書上看過一種字串搜尋法[Boyer-Moore法搜尋字串]-C名題精選百則-格致出版-先鏡光著
當然書上還有一種[Knuth-Morris-Pratt法搜尋字串]不過以BM法較快
不過呢!這兩種方法都是以"找得到"的思維去做字串的搜尋
(原碼滿長,請有興趣的同學去買來看,這本書不錯喔)

之前說過,本人有寫過一個文字處理器,當然有搜尋的功能,不過我的思維是以"找不到"為思考方向
不多廢話直接上原碼:
代碼: [選擇]

/*在一記憶體*mem內搜尋字串*hstr從footp找到endp,參數dir控制:往前(逆)INFO 往後(順)FROM 向搜尋
以strstr()也可找子字串但會受限於 '\0' 字串結束字元,
本函數不會受'\0'限制所以可搜尋2,3維陣列的全文搜尋,但要注意foot~endp的範圍不可超
過*mem實際宣告的大小即當mem[10][18]時endp不可大於10*18
*hstr必需是以'\0'結尾的字串

傳回的是旗標值,即mem[n]的索引n值,如果是二維陣列以下方式可求得

 char mem[sy[sx];
 int hun,x,y,max;

 max=sy*sx;
 hun=lee_memchunt(mem,hstr,0,max,FROM);
 ans=div(hun,sx);          ~~~~~起點,終點可以從指定段落開始(不是0及max)
 y=ans.quot;                    但終點不可超出max
 x=ans.rem;
 strncat(s,mem+(y*sy)+x,strlen(hstr));
           ~~~~~~~~~~~~
細微差別:不論順向或逆向起點及終點在呼叫者函數皆不用傳入游標所在旗標+1或-1這是因為:
逆向時第一層迴路起始是i=endp-1而第二層迴路是k=i+1(單一字元及游標本身在待尋字串內可正確)
順向時第一層迴路起始是i=footp而第二層迴路是k=i+1(游標在待尋字串左邊1個位元可正確)
*/
int lee_memchunt(char *mem,char *hstr,int footp,int endp,int dir)
{
  int hsn,i,n,k,x;

  hsn=strlen(hstr);
  if(hsn<1 || endp<1 || footp<0)/*無法搜尋的參數*/
    return(-1);
/*mvprintw(12,0,"footp=%d endp=%d ...lee_memchunt",footp,endp);
  refresh();
*/

  if(dir==INFO)/*往前(逆向)搜尋,INFO*/
  {
    x=0;
    for(i=endp-1;i>=footp;i--)/*因傳回k+1所以從endp-1找到footp*/
    {
      if(*(mem+i) == *(hstr+x))/*mem內第一個符合hstr+(sn+0)的字元*/
      {
        for(n=x+1,k=i+1;n<hsn;n++,k++)/*再找出從第2到第sn個符合的字元*/
          if(*(mem+k) != *(hstr+n))/*有不符合的字元即跳出*/
            break;
        /*結束(跳出)迴路後判斷n值是否比對到第sn個字元*/
        if(n>=hsn)/*已比對到第sn位元即已找到字串*/
          return(i);
        else/*沒找到字串則再從第*(hstr+0)個字元開始找*/
          x=0;
      }
    }
  }
  else/*往後(順向)搜尋,FROM*/
  {
    x=0;/*順向時要搜尋的字串hstr是從第0個字元開始比對*/
    for(i=footp;i<endp;i++)/*從footp找到endp*/
    {
      if(*(mem+i) == *(hstr+x))/*mem內第1個符合hstr+0的字元*/
      {
        for(n=x+1,k=i+1;n<hsn;n++,k++)/*再找出從第2到第sn個符合的字元*/
          if(*(mem+k) != *(hstr+n))/*有不符合的字元即跳出*/
            break;
        /*結束(跳出)迴路後判斷n值是否比對到第sn個字元*/
        if(n>=hsn)/*已比對到第sn位元即已找到字串*/
          return(i);
        else/*沒找到字串則再從第*(hstr+0)個字元開始找*/
          x=0;
      }
    }
  }
  return(-1);
}

KMP法是第一個突破(m*n)次的字串搜尋法(1977年)
當然現在應該有更好的方法了(手上沒資料..猜的),只不過別人怎麼寫的我並不清楚只能
以手上有的資料來比對,好,回到KMP法,由於其思維是以"找得到"字串的方向去找字串

先說明:我並沒有去參考KMP法或BM法只是後來去翻書翻到時覺得有點異曲同工之妙
不過我當初的思維是"如何找不到",如果沒算錯的話也是不用(m*n)次的,但邏輯卻簡單多了

有時候"逆向"思考問題的解答往往有意想不到的驚喜
(當初沒想到要這樣寫,只是有一個功能就是要"找不到某個字元"後演化出來的)

所以多多嘗試解決問題的方法它很可能在其它地方解決了其它問題 :wink:
程式是人寫的,別讓工具的限制成為您想像力的極限
~程式中最重要的部份應該是註解而不是程式碼,這是因為解讀註解一定比解讀程式碼簡單
~程式寫好後約一個月就會忘的差不多了,所以花點時間把註解寫好至少能讓自己(或別人)看的懂當初在寫什麼

shihyu

  • 活潑的大學生
  • ***
  • 文章數: 223
    • 檢視個人資料
C語言-寫作風格
« 回覆 #20 於: 2007-03-10 06:41 »
stlee 懂得東西真多~~ 希望你對C 風格再多post 心得^^

stlee

  • 鑽研的研究生
  • *****
  • 文章數: 817
    • 檢視個人資料
C語言-寫作風格
« 回覆 #21 於: 2007-03-10 13:43 »
引述: "shihyu"
stlee 懂得東西真多~~ 希望你對C 風格再多post 心得^^


呵呵!!一開始就說過這是[失敗經驗]的分享,失敗次數多了,想不懂都很難 :wink:

而且我懂得其實不多,只是靠著一招半式就闖江湖了,幸運的是還沒陣亡才能騙甲騙架一下啦 :D
程式是人寫的,別讓工具的限制成為您想像力的極限
~程式中最重要的部份應該是註解而不是程式碼,這是因為解讀註解一定比解讀程式碼簡單
~程式寫好後約一個月就會忘的差不多了,所以花點時間把註解寫好至少能讓自己(或別人)看的懂當初在寫什麼

stlee

  • 鑽研的研究生
  • *****
  • 文章數: 817
    • 檢視個人資料
C語言-寫作風格
« 回覆 #22 於: 2007-03-10 14:13 »
其實在寫作一個"程式"時我有一點一直銘記在心[電腦是要解決"人"的問題]的思考來寫的
所以當有些技術上無法獲得突破的瓶頸時,有兩個方法是慣用的

1.從日常生活中的解決方式去尋求答案,其實很多問題對人類來說已經有很完美且很有效率
的解決方式了,但對電腦來說,它就是沒辦法;就算想破我一百個腦袋還是解決不了!!還記得前
面提到過的[不限位數四則運算]吧,人類只要一支筆一張紙就可以辦到了,可是電腦(目前)就
是沒辦法,所以從"人類解決的方式"這個方向去思考,往往就把它給解決了

2.就乾脆停下來,努力把他忘了,等到忘得差不多時,再回頭寫(偷懶的好藉口:oops: )
武俠小說裡常說到的[走火入魔]....就是那個意思了,有時並不是無法解決,而是已經接近
[走火入魔]的地步了,停下來...放空自己...然後發現我真是個笨蛋--->問題就解決了

去散個步好好思考問題原點比坐在電腦桌前抓頭髮有用 :wink:
(我懷疑我的頭髮是被我抓禿的><")
程式是人寫的,別讓工具的限制成為您想像力的極限
~程式中最重要的部份應該是註解而不是程式碼,這是因為解讀註解一定比解讀程式碼簡單
~程式寫好後約一個月就會忘的差不多了,所以花點時間把註解寫好至少能讓自己(或別人)看的懂當初在寫什麼

stlee

  • 鑽研的研究生
  • *****
  • 文章數: 817
    • 檢視個人資料
C語言-寫作風格
« 回覆 #23 於: 2007-03-13 18:30 »
註解的威力是很強的!!!

有一種程式設計的方法是在書上看到的,這種方法可以用任何語言去寫,而且保證不用除錯
因為這種方法真的是"寫"出來的

PDL法(程式規劃語言,Program Design Language)由Caine,Farber,Gordon以論文公佈(1975年)
[如何進入程式設計的專業領域-旗標出版-STEVE McCONNELL原著-施威銘研究室翻譯]
(值得買的一本書,其理論適用任何語言,很多觀念都從這本書來的)

本人是不會用這種方法寫啦,可是同樣的利用[反向思考的邏輯]來說,意思差不多
流程是這樣的:寫一個函數時先觀察傳進來的參數是否正確(用到指標更需確定)如
果正確才開始去寫要處理的部份,當然中間不可能一次就寫好的,所以必須不斷去觀察這
期間處理的各項資料是否正確

在處理正確後再傳一些"不可能的資料"要這個函數去達成"不可能的任務",當然並不是真
的要去達成不可能的任務,而是要去把這個函數的終極極限給測出來然後才在程式內撰寫
注意事項等等的註解,

當然在撰寫期間會有一些狀況或可以再精進的地方時也要給他註解起來,當函數寫好後您
應該以為我會去看程式碼有沒有可以改進的地方吧!!其實都只去看當初寫的註解比較
多因為答案都在註解裡面了,尤其是寫一些與以後工作密切相關的函數可是一件非常累
人的工作,比如字串的插入,複製,刪除工作,當以後有要用到這些(一定常用)工具函數時
您會非常感激自己當初的努力呢 :D

而這種手法同樣的也用在對了解一個別人寫好的範例(可能是書上或網路上的)........
嗯......再書上的註解都是一點點的,所以範例抄起來以後順便下註解可以幫助自己更能
掌握它,網路的嘛...都沒有註解,所以您認為您功力高強時不用去註解他吧

所以當函數寫好後看起來是滿像用PDL法"寫"出來的咚咚
而這樣做的好處呢!!看下面的簽名吧 :wink:
程式是人寫的,別讓工具的限制成為您想像力的極限
~程式中最重要的部份應該是註解而不是程式碼,這是因為解讀註解一定比解讀程式碼簡單
~程式寫好後約一個月就會忘的差不多了,所以花點時間把註解寫好至少能讓自己(或別人)看的懂當初在寫什麼

stlee

  • 鑽研的研究生
  • *****
  • 文章數: 817
    • 檢視個人資料
C語言-寫作風格
« 回覆 #24 於: 2007-03-18 17:49 »
來說說程式怎麼拆吧

C語言所有工作都是函數,所有工作都必須靠函數來達成,函數也可以是參數

最基本的就是main()了,您的程式必須從main()開始,所以他是個"起點"比如aaa.c下面有兩個函數:
代碼: [選擇]
abc(a,b)
{
  111
  222
  333
}

main()
{
  aaa
  bbb
  ccc
  ddd
}


在這個程式裡會從aaa逐步執行到ddd,而111~333的部份並不會被執行,不管它擺在
main()前面,還是後面,他都不會被執行除非是這樣子
代碼: [選擇]
main()
{
  aaa
  bbb
  ccc
  ddd
  abc(a,b)
}


在main()裡面"叫用(呼叫)"abc()則111~333才會被執行,順序是
aaa~ddd然後執行abc()裡面的111~333,這是很簡化的說法,其中可能有if(xxx)
或迴圈for(xxx)等等,但執行順序的架構並不會被改變(有其他辦法改變它)
如果要改變它的架構,很簡單
代碼: [選擇]
main()
{
  aaa
  bbb
  abc(a,b)
  ccc
  ddd
}

這樣順序的架構就變成aaa,bbb,111,222,333,ccc,ddd

這跟本次主題有何關係呢!之前說過
代碼: [選擇]
一般來說當寫到一段程式碼有重覆出現(或兩段類似)的情況時,我會不假思索的把它寫成
一個函數,就算真的只有這兩個地方會去呼叫它,可是這並不代表以後的專案中不會有這
種情形發生,到時就算該函數與實際情況並不相同,但當初拆出來的函數可是一個非常好
的[範本]呢


也就是說,一個函數最好都只完成一項工作當然他也可以去完成"很多項工作"
但最好還是把"很多項工作"拆成"很多個特定功能的函數",所以當我們在不同地方
需要111~333工作的需求時只要這樣
代碼: [選擇]
main()
{
  aaa
  bbb
  abc(a,b)
  ccc
  ddd
  abc(a,b)
}


如此一來,您不覺得當111~333有問題時我們只要抓,改一個地方就可以解決掉兩個地方
的問題了嗎^^反之,您將要抓,改兩個地方而實際狀況往往沒這麼美滿:當您修正了上面
bbb後面abc()的問題,卻引發下面ddd後面abc()的部份出問題,這個時候您可能就要考
慮到將ddd後面的abc()改寫成def()然後變成這樣
代碼: [選擇]
main()
{
  aaa
  bbb
  abc(a,b)
  ccc
  ddd
  def(a,c)
}


這樣一來不是反而變得更麻煩了,呵呵...功夫就是這樣練出來的啦
當您在改def()時可能會發現根原來的abc()並沒有多大差別,所以何不乾脆增加一些
abc()的傳入參數變成一個"特定功能通用的函數"xyz(a,b,c)呢
代碼: [選擇]
main()
{
  aaa
  bbb
  xyz(a,b,c)
  ccc
  ddd
  xyz(a,b,c)
}

xyz(a,b,c)
{
  111
  222
  if(b)
    333
  if(c)
  {
    321
    333    
  }      
}

在xyz(a,b,c)裡面我們只要去判斷參數b,c就可以決定我們將進行哪些比較不一樣
的程序就可以了

這對函數而言只是比較"基本"的運用,比如執行緒或排序法還可以把函數當"參數"傳給
它來執行執行緒或排序的工作,但這是另一個"起點"的觀念

個人覺得:寫程式跟修車一樣,拆完再裝,裝好就跑看看,有怪奇再拆,再裝,再跑.....
 :cry:
程式是人寫的,別讓工具的限制成為您想像力的極限
~程式中最重要的部份應該是註解而不是程式碼,這是因為解讀註解一定比解讀程式碼簡單
~程式寫好後約一個月就會忘的差不多了,所以花點時間把註解寫好至少能讓自己(或別人)看的懂當初在寫什麼

trainman

  • 憂鬱的高中生
  • ***
  • 文章數: 138
    • 檢視個人資料
C語言-寫作風格
« 回覆 #25 於: 2007-03-18 18:38 »
引述: "netman"
呵,真是學到不少呢!
不知道 stlee 大要不要來跟大家分享一場講座啊?
我們台南三月剛好缺講師呢~~~  ^_^



呵 三月份的講師找到了呢 ^_^

stlee

  • 鑽研的研究生
  • *****
  • 文章數: 817
    • 檢視個人資料
C語言-寫作風格
« 回覆 #26 於: 2007-03-18 20:10 »
引述: "trainman"
引述: "netman"
呵,真是學到不少呢!
不知道 stlee 大要不要來跟大家分享一場講座啊?
我們台南三月剛好缺講師呢~~~  ^_^



呵 三月份的講師找到了呢 ^_^


球季剛開打,會有點小忙忙^_^!!

有活動是非常樂意共襄盛舉的啦~~~(還沒參加過講座呢>"<跟上課一樣嗎?)
程式是人寫的,別讓工具的限制成為您想像力的極限
~程式中最重要的部份應該是註解而不是程式碼,這是因為解讀註解一定比解讀程式碼簡單
~程式寫好後約一個月就會忘的差不多了,所以花點時間把註解寫好至少能讓自己(或別人)看的懂當初在寫什麼

stlee

  • 鑽研的研究生
  • *****
  • 文章數: 817
    • 檢視個人資料
C語言-寫作風格
« 回覆 #27 於: 2007-04-14 18:29 »
一個對人類來說是很複雜的問題,但是對電腦來說可能很簡單
相對的一個對電腦來說是很複雜的問題,但是對人類來說可能很簡單

原因就是在電腦的思考邏輯與人類的思考邏輯完全不同
正確來說應該是處理邏輯而不能說是思考邏輯,因為電腦並不會思考,人類才會思考

所以您在撰寫程式時應該把自己幻想成是一部電腦是怎麼去處理這些資料的,而不是把電腦
當成是人類去處理並思考您的問題所在

其實所謂的程式不過是對電腦所指定的一些程序,指定他下一個動作要做什麼,做完這個動作
後再接下哪些個動作等等如工廠中輸送帶上的工人一樣,這個工人做這個動作,那個工人做
那個動作,最後把成品從輸送帶末端吐出來

而一個程式的商業價值也就在這裡,決不是在炫麗的外表,因為美麗是可以被流行取代的
程式是人寫的,別讓工具的限制成為您想像力的極限
~程式中最重要的部份應該是註解而不是程式碼,這是因為解讀註解一定比解讀程式碼簡單
~程式寫好後約一個月就會忘的差不多了,所以花點時間把註解寫好至少能讓自己(或別人)看的懂當初在寫什麼

jimmp812

  • 懷疑的國中生
  • **
  • 文章數: 73
    • 檢視個人資料
C語言-寫作風格
« 回覆 #28 於: 2007-04-19 08:10 »
提到註解,小弟有一事請教,
我們公司是用 Delphi 啦,剛進公司看程式的時候,怪了,怎麼幾百行的程式找不到幾行註解!
後來發現,怎麼公司裡的人都沒有習慣寫註解!
然後大家又都說他們就都看的懂,就只有我看不懂!

現在我好像變成公司的怪人了!因為我的註解還算多,
因為希望可以直接看到註解就可以知道這一段是在做什麼,當初為什麼要寫這一段,
寫這一段還有什麼需要修正的…
所以有時候造成我的註解都有可能跟加入的程式碼一樣多的情形

請問我這樣做,很怪嗎?代表我實力差嗎?
我不懂為什麼大家都不用看註解,就可以寫程式耶!

stlee

  • 鑽研的研究生
  • *****
  • 文章數: 817
    • 檢視個人資料
C語言-寫作風格
« 回覆 #29 於: 2007-04-19 20:02 »
這種情形因為我沒呆過公司所以猜測如下

1.他們已經是從專案開始就加入開發的老鳥,所以自己寫的東西當然清楚了
2.他們是超人....請誠心的拜一下
3.貴公司有國畫教室嗎?專門在教怎麼畫老虎和蘭花

當然了,看得"懂"跟看得"通"是不一樣的

所以您的習慣,相信老闆都看在眼裡,有機會問一下老闆這樣做好不好吧
程式是人寫的,別讓工具的限制成為您想像力的極限
~程式中最重要的部份應該是註解而不是程式碼,這是因為解讀註解一定比解讀程式碼簡單
~程式寫好後約一個月就會忘的差不多了,所以花點時間把註解寫好至少能讓自己(或別人)看的懂當初在寫什麼