※ 引述《powenyu (powen0706)》之銘言:
: 小弟不才 打算在暑假選一本C++的書來啃
: 我本身有稍微碰過C,但是觀念非常不扎實,像是指標、陣列、遞迴之類的
: 我目前是計畫把zerojudge的題目A在暑假做完,但是還是希望能配著書來讀
我花了十分鐘用 Google 爬完你發過的文。
大致上可以知道去年已經是大一,原本是讀高中,然後考台科讀。
其它私事就先不提,總之光從 IP 看你都是用台科無線網路,所以查不到科系。
但根據讀完大一以後只是「稍微碰過 C」和「指標、陣列、遞迴觀念不紮實」,
研判應該不是電資類的科系,不然應該至少已經被資料結構這門課操過了。
因為沒什麼力氣再去翻台科的電資科系的課表,姑且就先當你是個非相關科系學生。
如果你是非相關科系的學生,在學 C++ 之前,你得先搞清楚你為什麼要學 C++。
你未來想從事什麼方面的研究要用到 C++?你未來想從事什麼樣的工作會用到 C++?
你現在是大學生,不再是高中生,很快就要出社會工作,要盡量確立目標再決定學什麼。
先確立你的目標再來決定要學什麼東西,不要覺得自己時間還有很多,剩下三年很快的。
你把你的目標和動機還有自己背景都好好講出來,我再認真回技術方面的東西。
: 因為我以前的學習方式是拿到題目就寫,不會就問同學,或是去網路上看大神的程式碼
: 再依題目自己修改,可是常常就會忽略這個用法的觀念,招致錯誤的用法或沒效率的
: 用法
先講這些的原因是因為看到你還是以解題為目標,進行著很國中化、高中化的學習方式。
你沒有一個想要製作的作品,而且也沒嘗試過從無到有寫出一支程式,都是透過模仿。
問同學固然跟上網查一樣可以快速得到答案,但是你的知識就是片片段段無系統性。
把網路切掉,只給你 C 語言教科書和函式庫工具書,你能不能寫出個什麼來?
是不是沒有人問,沒有辦法透過網路或一堆範例的書抄程式碼來改,你就什麼都做不到?
你先設法逼自己只有 C 語言教科書和函式庫工具書就能寫出程式,之後再來談其它。
C++ 對現在的你來說還是太龐大了,特別是現在這種學習方式,根本沒辦法把 C++ 學好。
: 想問大神們對這種狀況有什麼推薦的書籍嗎,像有一本:插畫學C語言 我覺得圖解對我的
: 觀念有很大的幫助,但是我覺得他講太少了,例題不夠內文不連貫,蠻可惜的,但是如
: 果有類似的書,歡迎大家推薦。
會找到適合自己的書是好的開始。
學程式的前幾本書我從來都不建議叫人推薦,畢竟每個人適合的入門學習法不同。
你先多找到幾本可以釐清你觀念的書,自學到入了門了,再找人推薦經典書籍才有意義。
你得天獨厚人在台北,自己去重慶南路逛一下天瓏書局,現場去挑適合你自學的書。
很多縣市的學生沒有這種環境,只能網路上沒看過就買,搞到選書跟抽籤一樣碰運氣。
圖書館也是一個可以利用的地方,但這很看學校及館藏,去專業電腦書店選書絕對沒錯。
你也不一定要去選 C 或 C++ 的書,有興趣的題材跟程式語言你都能翻來看看有無興趣。
會一直跟你強調這個是因為 C/C++ 在泛軟體業裡不是大宗,很多公司並不使用 C/C++。
如果你是電資類的本科系學生,因為常需要寫中低階程式,學 C/C++ 我就會覺得還好。
但即使是這類學生跑來問,我一樣還是會先問你將來想幹嘛。
如果你不想思考或回答我這些問題,你可以直接殺去 C_and_CPP 板再發問一次。
既然你發在 Soft_Job 這種社會人士板,那我會先以入社會後想幹嘛為考量來回文。
當然不管你是什麼科系,未來想幹嘛,想透過 C/C++ 來學程式,有些東西可以在這先講。
首先,你需要的書只有兩種。
一種是打穩基礎觀念的 C 語言教科書。
另一種就是羅列 C 語言標準函式庫所有函式及簡易使用範例的工具書。
你需要的書就只有這兩種,其它速成類、純範例類的書,你可以全部跳過。
靠著這兩種書寫出你想寫的東西,解你想解的題目,不要上網查或問人。
如果做不到,那代表你的個性根本就不適合以寫程式為業,當日常生活工具玩玩就好。
只是要把程式當日常生活工具玩玩就好,你有更好的選擇,C/C++ 絕對不是首選。
你去學個按鍵精靈的命令稿語言搞不好在把妹上還比較有利,我是很認真在說。
當你用這些方法去土砲實作東西和解題時遇到方法或效能上的障礙,那才需要讀其它書。
所謂其它書,就是資工本科系的兩大必修課,資料結構和演算法。
如果你對背後的數學原理有興趣,想要自己設計演算法,還需要讀一下離散數學。
但是這幾種書對現在的你來說都還太早,你連程式語言的基礎都還沒系統化學習過。
說真的如果你是好好讀書從基礎學起,我不清楚陣列跟指標到底有什麼難懂。
陣列名稱跟指標名稱都是識別字 (identifier),使用前需要先宣告 (declare)。
這些識別字在被定義 (define) 後會在記憶體被配置一塊空間,裡面可以存資料。
當這些識別字被拿來當變數 (variable) 使用時,同時也會是運算元 (operand)。
而針對運算元進行操作的符號稱為運算子 (operator),功能當然就是拿運算元來運算。
由運算元和運算子構成運算式 (expression),譬如 a + b 這樣的東西。
由一條運算式再加上分號做結尾,就構成一條簡單敘述 (simple statement)。
而使用大括號把好幾條敘述包起來的就叫複合敘述 (compound statement)。
敘述 (statement) 在 C/C++ 是真正的基本單位,整個程式由各種敘述完成。
一般人講的什麼 if 語法、switch 語法等等,真正的名稱是叫 if 敘述、switch 敘述。
講這些幹嘛?因為程式語言也是語言,只是限制比較多,學起來比自然語言簡單而已。
你學英文一樣要學文法,要知道如名詞、動詞、形容詞、副詞等各種詞性。
運算式在英文的文法裡如同子句 (clause) 或片語 (phrase),
而敘述在英文的當中就是更淺顯易懂的東西,稱為句子 (sentence)。
就如同文章是由段落組成,段落是由句子組成一樣,
你的整個程式也是由一段一段的敘述所組合出來的。
當然就像一本著作甚至還會區分章節一樣,程式其實也有編譯單元、模組等概念。
不過這種東西對你現階段來說還太早,因為你寫程式的主要方法還是拿現成的來改。
你要先學的東西,就只是怎麼在一張完全空白的白紙上寫出無語法錯誤的一支支小程式。
陣列名稱說穿了丟到程式上就是個運算元及變數,然後它有特殊的運算子可以對它操作,
也就是下標運算子 (subscript operator),就是中括號 [] 這種東西。
指標名稱說穿了丟到程式上還是個運算元和變數,它也有個特殊的運算子可以對它操作,
稱為提領運算子 (dereference operator),也就是星號 * 這種東西。
這東西你只要稍微瞭解一下是在幹嘛,就算看到 N 個提領運算子在一起,也不會怕它。
N 個提領運算子在一起就是做 N 次提領而已,也沒什麼,本質都是不變的。
除此之外,運算子作用在不同型別的運算元上也有不同意義,
譬如你對一個指標型別的運算元做 + 1,實際上運算結果常常不是只是多了 1 而已。
你必須先搞清楚不同型別 (type) 的運算元有哪些運算子可以用,它們的作用是什麼。
什麼叫型別?陣列和指標本身就是一種型別,當然你常看到的 int、float 等等也是。
型別影響到編譯器怎麼去看待運算子跟運算元,轉譯出來的機械指令也有差別。
兩個 double 變數相加,編譯器轉譯出來的是浮點運算指令,
因此這種加法的兩個運算元裡的位元排列方式,CPU 會以浮點數特有的格式來做解讀。
兩個 int 變數相加,編譯器轉譯出來的是整數運算指令,
因此這種加法的兩個運算元裡的位元排列方式,CPU 會以整數格式來做解讀。
當運算子兩邊的運算元型別不同時,編譯器還得先暗中把它們轉成同型別再決定指令。
其它東西要一口氣在這講完就太多了,多到可以寫一本來賣,就留給你自己看吧。
遞迴是一種程式結構,它的原理就是數學,但是這邊可以先不管。
在程式上遞迴就是一種叫電腦暴力反覆做一樣的事,直到你設定的條件發生為止的東西。
所以遞迴的構成元素就只有兩項:1. 繼續往下用力算的執行部分 2. 終止條件
所以你想要寫一個把傳入的變數不斷遞減到 0 的遞迴函式的話,首先就要放終止條件。
就像我一開始問你想學 C++ 是什麼目的,你有什麼目標?
程式總是為某個目的而寫的,所以你一開始要決定的就是目標。
void decrease_until_zero(unsigned v)
{
if(v == 0) return; /* 終止條件是讓 v 變成 0 */
}
然後達到目的的過程是「不斷遞減」,所以你得加上一行遞減的動作:
void decrease_until_zero(unsigned v)
{
if(v == 0) return;
v