Re: [請益] C++觀念參考書選擇
※ 引述《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--; /* v 還沒變成 0 的話,就做這件事 */
}
如果你想觀察每次呼叫過程中的變化,可以補上一行 printf():
void decrease_until_zero(unsigned v)
{
if(v == 0) return;
printf("%u\n", v);
v--;
}
再來就是你希望這段程式可以不斷反覆跑到你想要的結果出來為止,
那就是讓這個會讓傳入參數不斷減一的函式不斷反覆跑,也就是呼叫自己:
void decrease_until_zero(unsigned v)
{
if(v == 0) return;
printf("%u\n", v);
v--;
decrease_until_zero(v); /* 無論如何,就是要一直做到停下來為止 */
}
這個函式裡的構成物就只有剛剛講的兩種:終止條件、不滿足終止條件時要做的事。
遞迴講白話點就是設定好目標,然後讓程式不斷反覆做一樣的事,直到目標達成為止。
其它各種形式的遞迴都是基於這個原理再做一些小變化而已,根本沒有什麼難懂的。
只要你能理解遞迴的本質是這種東西,之後看到遞迴或要寫遞迴時就完全不會怕了。
遞迴在「不知道要做多久」、「不知道有多少東西要做」的情況來講很好用,
因此它也深受數學家的喜愛,寫了就是「管你有多少東西要做多久,做就對了」的意思。
也因為這樣,最初數學家所寫的程式常常要跑很久很久,電腦科學才被發展起來。
這些東西因為不管你學哪個語言都會用到,所以我就先講一講。
當然萬一你真的很不幸是電資類科系的,那你還有更基礎的一些東西得同時學習。
最基本的要求是你要會分別單獨操作前置處理器、編譯器、組譯器和連結器,
還有搞懂編譯出來的執行檔結構,以及它被載入到記憶體執行後的佈局是長怎樣。
這些東西對科班生來說是基本要求,因為要知道自己寫的每一行程式碼在電腦裡怎麼跑。
而對於一般寫應用軟體的人來說,講究的是抽象化概念,不需要知道太具體的東西。
對於也會寫程式的資訊管理系和應用數學系來說,他們關心的都是更高階更抽象的東西,
所以教他們變數可以說那是個盒子,說記憶體位址的時候可以說是什麼門牌地址。
但是對於電資類科系來說,這些說法都是非常要不得的不精確說法,沒在那邊箱子門牌。
也因此兩邊從一年級的計算機概論教學方式就有差距,
電資類科系教的是計算機科學導論,和那些教教進制轉換及 Office 的計概天差地別。
搭配著同時開始的 C 程式設計一起,這門課會同時導覽資工四年所會修習到的核心科目。
其中電腦架構的計算機結構概論,對於指標及記憶體佈局的認知有極大幫助。
其中的程式語言概論,也會告訴你程式是被怎麼被編譯器解析,以及文法表的閱讀方式。
其中的作業系統概論,除了字面上的意義會講的一些東西之外,
還能讓你在大一就提前體驗一下多處理程序程式甚至多執行緒程式的設計方式。
總而言之,這兩種人的訓練方式是完全不同的,從一開始學習的方向就不一樣。
也因此你會看到網路上有人把指標講得超級難,有人卻能輕鬆自在地把玩它。
其實那些根本都不是天分的問題,而是基礎訓練方式的差異,所以在難度認知上有差異。
你到底想要成為哪種人,目標是什麼,還是得先說清楚,不然會很難回出一個方向。
--
Ling-hua Tseng
Senior Engineer
Compiler Group, RD/Software Division
Andes Technology Corporation
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 122.116.164.123
※ 文章網址: https://www.ptt.cc/bbs/Soft_Job/M.1530045810.A.BE1.html
※ 編輯: tinlans (122.116.164.123), 06/27/2018 05:21:09
推
06/27 06:27,
5年前
, 1F
06/27 06:27, 1F
推
06/27 06:30,
5年前
, 2F
06/27 06:30, 2F
→
06/27 06:30,
5年前
, 3F
06/27 06:30, 3F
→
06/27 06:31,
5年前
, 4F
06/27 06:31, 4F
→
06/27 06:31,
5年前
, 5F
06/27 06:31, 5F
→
06/27 06:32,
5年前
, 6F
06/27 06:32, 6F
推
06/27 06:56,
5年前
, 7F
06/27 06:56, 7F
推
06/27 08:03,
5年前
, 8F
06/27 08:03, 8F
推
06/27 08:22,
5年前
, 9F
06/27 08:22, 9F
→
06/27 08:28,
5年前
, 10F
06/27 08:28, 10F
推
06/27 08:29,
5年前
, 11F
06/27 08:29, 11F
推
06/27 08:37,
5年前
, 12F
06/27 08:37, 12F
→
06/27 08:55,
5年前
, 13F
06/27 08:55, 13F
→
06/27 08:55,
5年前
, 14F
06/27 08:55, 14F
推
06/27 09:07,
5年前
, 15F
06/27 09:07, 15F
推
06/27 09:07,
5年前
, 16F
06/27 09:07, 16F
→
06/27 09:07,
5年前
, 17F
06/27 09:07, 17F
推
06/27 09:21,
5年前
, 18F
06/27 09:21, 18F
推
06/27 09:28,
5年前
, 19F
06/27 09:28, 19F
→
06/27 09:28,
5年前
, 20F
06/27 09:28, 20F
C++ 從最早發展到稍微穩定有點樣子的時候是 1990 年,標準化是 1998 年末。
2018 - 1998 = 20,換句話說教 C++ 的最少要在 20 年前有好好學習過 C++。
更不用說在 2011 年底 C++ 還有一次大改,也就是說教的人在 7 年前還得更新知識。
在學校做研究的教授都在衝論文數,而且從歲數反推就會知道他們根本沒機會學好。
沒學好的東西又怎麼可能拿出來教,所以當然是只能當成 C 語言來教。
加上科大的資工系歷史很短,初期很多是電機、電子這邊的教授跑過來開資工系。
要他們寫教你程式,不如要他們教你怎麼讀那本史密斯還比較有用。
其次就是應數、資管、網通所等等過來開的,這些專長都是偏應用的部分。
所以教授的專長要嘛不是很數學、很微積分,就是很硬體,要不就是很應用。
能完整傳授資工核心科目的教授在科大一直都有限,很多靠自學還是比較快。
這和早期一堆學校開設資管系,卻沒有資訊背景師資,
只是因為資管系變得很熱門,所以幾乎只有純管背景的教授就硬開出資管系很相似。
更何況學術界不會太重視工具的使用,普大科大其實都很缺會教 C++ 的教授。
以前學術界是有講師這種注重教學的教育者存在的。
但是不知道什麼時候開始,可能跟四技二專升格科大而想跟他們區別化有關,
學校 0 講師、所有師資都有博士學位這點居然可以拿來當成學校特色和優勢在講。
甚至還有學校逼迫副教授幾年以內要升等成正教授,不然會被踢出去。
升等的途徑是什麼?在早期不論科大還是普大,都一樣是論文點數。
2000 年初期台科身為技職龍頭,卻率先叛離技職體系,開始偏愛高中生而非高職生。
這背後的原因到底是什麼也很明白,就是養肥養大以後拐他們簽下去,幫他們發論文。
這種瑕疵滿滿的評鑑制度洗走了一波認真教學的教育家,留在學術界的大都剩嘴砲王。
推
06/27 09:48,
5年前
, 21F
06/27 09:48, 21F
推
06/27 10:05,
5年前
, 22F
06/27 10:05, 22F
推
06/27 10:13,
5年前
, 23F
06/27 10:13, 23F
推
06/27 10:24,
5年前
, 24F
06/27 10:24, 24F
推
06/27 10:32,
5年前
, 25F
06/27 10:32, 25F
推
06/27 10:49,
5年前
, 26F
06/27 10:49, 26F
推
06/27 10:53,
5年前
, 27F
06/27 10:53, 27F
推
06/27 11:18,
5年前
, 28F
06/27 11:18, 28F
推
06/27 11:21,
5年前
, 29F
06/27 11:21, 29F
推
06/27 11:25,
5年前
, 30F
06/27 11:25, 30F
推
06/27 11:41,
5年前
, 31F
06/27 11:41, 31F
推
06/27 11:47,
5年前
, 32F
06/27 11:47, 32F
推
06/27 11:50,
5年前
, 33F
06/27 11:50, 33F
推
06/27 12:04,
5年前
, 34F
06/27 12:04, 34F
※ 編輯: tinlans (122.116.164.123), 06/27/2018 12:11:33
推
06/27 13:19,
5年前
, 35F
06/27 13:19, 35F
→
06/27 13:19,
5年前
, 36F
06/27 13:19, 36F
推
06/27 13:23,
5年前
, 37F
06/27 13:23, 37F
還有 29 則推文
還有 3 段內文
推
06/27 20:18,
5年前
, 67F
06/27 20:18, 67F
推
06/27 20:26,
5年前
, 68F
06/27 20:26, 68F
推
06/27 20:54,
5年前
, 69F
06/27 20:54, 69F
推
06/27 20:58,
5年前
, 70F
06/27 20:58, 70F
推
06/27 21:41,
5年前
, 71F
06/27 21:41, 71F
推
06/27 22:31,
5年前
, 72F
06/27 22:31, 72F
推
06/27 22:46,
5年前
, 73F
06/27 22:46, 73F
推
06/27 23:29,
5年前
, 74F
06/27 23:29, 74F
推
06/28 00:25,
5年前
, 75F
06/28 00:25, 75F
推
06/28 00:30,
5年前
, 76F
06/28 00:30, 76F
推
06/28 01:21,
5年前
, 77F
06/28 01:21, 77F
推
06/28 03:03,
5年前
, 78F
06/28 03:03, 78F
推
06/28 04:28,
5年前
, 79F
06/28 04:28, 79F
推
06/28 08:52,
5年前
, 80F
06/28 08:52, 80F
推
06/28 09:13,
5年前
, 81F
06/28 09:13, 81F
推
06/28 10:50,
5年前
, 82F
06/28 10:50, 82F
推
06/28 11:34,
5年前
, 83F
06/28 11:34, 83F
推
06/28 11:40,
5年前
, 84F
06/28 11:40, 84F
推
06/28 15:10,
5年前
, 85F
06/28 15:10, 85F
→
06/28 15:11,
5年前
, 86F
06/28 15:11, 86F
推
06/28 15:45,
5年前
, 87F
06/28 15:45, 87F
推
06/28 16:03,
5年前
, 88F
06/28 16:03, 88F
推
06/28 19:04,
5年前
, 89F
06/28 19:04, 89F
→
06/28 19:04,
5年前
, 90F
06/28 19:04, 90F
推
06/28 19:28,
5年前
, 91F
06/28 19:28, 91F
推
06/29 10:05,
5年前
, 92F
06/29 10:05, 92F
推
06/29 10:08,
5年前
, 93F
06/29 10:08, 93F
推
06/30 09:38,
5年前
, 94F
06/30 09:38, 94F
推
06/30 09:47,
5年前
, 95F
06/30 09:47, 95F
推
07/02 02:55,
5年前
, 96F
07/02 02:55, 96F
推
07/02 13:52,
5年前
, 97F
07/02 13:52, 97F
→
07/02 13:52,
5年前
, 98F
07/02 13:52, 98F
→
07/02 13:52,
5年前
, 99F
07/02 13:52, 99F
這篇其實大多是在講 C 基礎,如果已經對這些沒問題,那 C++ 的學習才剛要開始。
C++11 之前的書大都粗略把 C++ 的 programming paradigm 分成四大類:
1. procedural programming
2. object-based programming (又稱為 ADT)
3. object-oriented programming
4. generic programming
如果只學跟純 C 共通的部分,那差不多就是只學到四分之一的 C++03。
一般學校可能會教到 3 的開頭,後面就會因為老師本身不熟物件導向教不下去。
物件導向不是單純把現實世界的物體假想成物件來寫程式這麼簡單,
但很多台灣人寫的書會這樣胡謅,造成新手製造出很多濫用、誤用繼承的案例。
先不要說新手,很多自稱熟悉物件導向的人終其一生都可能不知道怎樣才是正確的。
不得不說歐萊禮的深入淺出系列救了不少人,可惜它的範例是 Java。
推
07/04 03:19,
5年前
, 100F
07/04 03:19, 100F
※ 編輯: tinlans (122.116.164.123), 07/06/2018 14:12:18
推
07/06 23:48,
5年前
, 101F
07/06 23:48, 101F
推
02/22 16:58,
6年前
, 102F
02/22 16:58, 102F
推
06/20 20:46,
4年前
, 103F
06/20 20:46, 103F
推
09/24 01:18,
4年前
, 104F
09/24 01:18, 104F
討論串 (同標題文章)