軟體工程學生怎樣學好 C 語言?

在下大一軟體工程新生,本來滿懷憧憬的開始學習c語言。但現在發現老師上課講的根本聽不懂,他是按照我們什麼都會的前提給我們講的。可我什麼都還不會啊,我該怎麼做。求具體一點的方法。o(&>﹏


不敢說自己懂C語言,權當拋磚引玉吧。

為什麼要學C語言?

在你學習C語言之前,你必須明白C語言是用來幹什麼的。也許你看了書上的範例代碼,渾渾噩噩,印象里好像可以寫一個諸如華氏度轉攝氏度的東西,或者是給一堆數排個序之類的。總之,語言是用來寫程序的。

那什麼是程序呢?我不知道你對計算機有多少了解,不過我猜想你應該知道,計算機的處理器能夠處理一條一條的指令,這些指令對應著不同的對數據的操作。計算機運行一個程序,就是把這些指令和數據載入到內存裡面,然後一條一條地執行。

我相信你也知道計算機內部全都是用二進位表示信息。在機器中,每一條指令也是用二進位數來表示的。我們很難記住這些數和指令的對應關係,它的表現也不夠直觀。所以計算機科學家們開始用助記符(比如mov、jmp等)來表示指令。這被稱作彙編語言。儘管相比於徒手擼機器碼有進步,但是說到底彙編語言也只是很淺的一層抽象。實現一個複雜的功能,也許要寫很長的一段代碼。更可怕的是,許多彙編代碼移植性不好,切換到另一個平台上需要改很多代碼。因此開發大型軟體很不方便。

在C語言出現之前,已經有過許多在彙編語言基礎上進一步抽象的高級語言,比如FORTRAN、COBOL等等,而且許多至今都還在某些領域有各自的一席之地。而C的抽象在它出生的那個年代做得恰到好處,既有高級語言的簡潔和表達力,又不失貼近底層系統的直接,再加上它與UNIX系系統的密切關係,C在之後許多年裡成為了系統編程和軟體開發的首選語言。C的代碼相比於之前的彙編,在可移植性上已經有了諸多進步,切換到另一個平台的程序,只要那個平台上有C的編譯器,不需要修改或者只需要修改少量的代碼。我們可以看到在程序語言發展的過程中一個很明確的趨勢就是抽象層次愈來愈高,比如後來又出現了號稱「一次編寫,處處運行」的依靠虛擬機的Java和眾多的腳本語言,當然那是後話了。

忘說了,在程序語言的發展之路上,還有另一條分叉,函數式語言,典型代表是lisp。它的思維方式同傳統的基於指令的語言截然不同,知乎上有大牛說過,函數式語言就是數學,只要數學不過時,函數式編程語言就不會過時。不過在C誕生那個年代呢,由於機器條件所限,函數式編程語言還沒有那麼得到人們的重視。

好了好了,講歷史的部分到此打住,在今日軟體項目的實際開發中,C語言所佔的比重早已不能和八九十年代同日而語了。之所以還要學C語言呢,就是因為它跟底層有天生的親近感,C語言的許多特性和「坑」,深挖下去,其實也是計算機體系結構的問題。《C標準庫》的作者在書里打趣說,C大概是少數能自我實現標準庫的語言了。所以,學C的時候,如果關注點僅僅是語法本身,那還不如python來得親切。(不過我想說國內大學裡有些教C語言的老師恐怕連python是什麼都不知道)

什麼是Hello, world!

大多數初學C語言的人寫的第一個程序都是所謂的「Hello, world!」。簡言之,就是一個能在屏幕上輸出這句話的程序。這句話的起源是C語言之父(可不是譚浩強哦)Dennis Ritchie和Brain Kernighan的名著《C程序設計語言》。從此以後成為了所有程序設計語言學習者的第一課。

題主說自己是軟體工程專業的學生,不知道你是哪個學校的。不過在我校呢,軟體相比於牛氣衝天的土木和建院實在是太渺小了,許多同學甚至是選專業失敗被調劑來的。也許你也像他們一樣,對所謂的「程序」或者說「軟體」,在之前並沒有一個明確的概念或者印象。也許你會認為軟體是像網易雲音樂一樣的,或者說是手機上的微信一樣的,有一個漂漂亮亮的窗口,還有按鈕,還有標籤什麼的東西。但當你費盡千辛萬苦,照著書上敲完這一段也許還不能一次敲對的代碼,結果發現只有一個「黑漆漆」的屏幕的時候,你會不會略感失望呢?這就是我要的程序嗎,為什麼長這樣?

如果你去問老師,說自己不想要這種程序。脾氣不好的老師也許會直接罵你一頓,有耐心點的老師可能會告訴你學會了這個才打好了基礎。可是我想你還是不明白這個黑漆漆的窗口到底代表著什麼。這也難怪,因為你用的是Windows,如果之前沒有弄過什麼bat腳本的話,也許都從來沒有接觸過終端這個東西。不過我想你可以給家裡人打個電話聊聊。如果你爸媽在九十年代的時候學過計算機的話,他們應該對DOS的命令行界面還有印象。說不定小時候偷看過親戚玩電腦的你也有。事實上,在所謂的「圖形用戶界面」出現以前,一個程序的輸入和輸出基本只能依靠命令行中的鍵盤和屏幕。你在Windows的資源管理器里對著a.txt右鍵點擊刪除,和你在DOS的黑屏幕里敲del a.txt然後回車是一個效果。只不過,前者可能對用戶而言更加友好。

所以你明白了吧,由於早期計算機的顯示技術和設計理念的限制,輸入輸出採用的是命令行的方式。而你跑這個Hello, world!程序時候出現的黑窗口,實際上可以理解為是Windows對早期命令行系統的一種模擬。如果你還知曉有一種語言叫VB,它的Hello, world!可以用創建一個窗體,然後在上面畫一個Label的方式來實現。對比一下,可以發現,其實這兩者之間並無什麼本質區別。之所以我們喜用在命令行下輸出Hello, world!的程序來教授編程的第一課,原因首先是它簡單,不用考慮輸出的布局、格式,僅僅是內容就可以了;然後是C語言的標準庫也並沒有給我們提供這樣一個圖形化的介面。事實上設計一個圖形界面的程序也沒有那麼簡單,你需要設定好布局,要為每個組件編寫事件響應介面……作為初學者,你應當知曉的是,之所以用命令行,並不是因為C語言不能做圖形界面,而是因為那跟我們在初學的時候需要挖掘的東西相隔太遠。不管是寫一個命令行的Hello, world!,還是點擊按鈕彈出Hello, world!,甚至是用電腦的蜂鳴器bee一聲,本質都是一樣的。

編程的意義

事實上,寫程序和設計的目的是一樣的,都是為了解決問題。(儘管有些人喜歡欣賞所謂「純粹的技術」)國內高校教材最大的缺點之一,就是只告訴你這個是什麼,卻從來不告訴你學了有什麼用。即使講了所謂的用途,給人的感覺也只是湊數用的。不信?可以拿我校數學系編的那本紫皮的《線性代數》和國外優秀的線代教材比,看看兩者差距有多大。

儘管C語言相比python、Java等語言缺少許多必要的「輪子」,不過對於初學者來說,寫點能運行剪刀石頭布的代碼,或者說能夠從某個文本文件里讀入生詞然後考查你背得如何的程序,都可以帶來巨大的成就感。上編程課和上高等數學不一樣,它不應該有什麼進度之分。在了解完基本的語法之後就可以動手實現了,期間遇到什麼問題再去網上查。寫完了再去跟別人寫得好的對比,看自己哪裡不足。

初學編程,關鍵在練習。

語法有什麼用?

似乎譚浩強和其它諸多所謂國內「專家」編寫的教材,把C語言當做數學來講,按照不同的語法內容劃分成章節,有些學校說不定最後還會有筆試。有些學校甚至還叫學生上交手抄代碼。我不太能夠理解和認同這種行為。作為初學編程的你,大概早就受夠了這種被動式的接受,在心裡反問自己:就算我都看完了,能寫出個什麼呢?

確實寫不出什麼東西。因為在這種情況下,讀者很難理解到這些語法的含義。比如,你看到書上講分支語句和循環語句的時候,有想過它們有什麼用嗎?我不用分支行不行,不用循環行不行?

試想我們有一個程序,讓我們在輸入的一堆數裡面找出最大的那個。假設輸入是定死的,第三個數最大,那我完全可以接收到第三個輸入的時候直接輸出,結束程序了對不對?你可能覺得我這樣是在耍流氓,哪裡會有這樣的程序。事實上,這也是所謂條件語句存在的本質——程序需要接受不同的輸入(任何形式)。如果輸入是固定的,那麼理論上我可以改寫為沒有條件語句的代碼。變數的概念,也是因為它所包含的值不是確定的。話說回來,只有用if語句才能實現分支結構嗎?你讓我求一年每個月多少天,我是不是可以開一個數組來保存,然後單獨判斷閏年就可以了?你讓我輸出從1到100任意一個整數的平方,理論上我用switch...case語句或者if也能做,可直接輸出n*n,不是更好理解也更方便嗎?循環其實是類似的道理,只是它的目的在於重複執行某一段代碼,而重複次數是不固定的。我們說過,編程的目的是解決問題,不是讓你在寫代碼的時候故意賣弄一些什麼東西上去把代碼搞亂,像寫高中的語文作文一樣。

每學到某個語法概念的時候,都要問一問自己,如果沒有這個東西,有沒有什麼程序是寫不出來的?或者說,如果沒有了這個語法,我寫程序的時候會增加多少麻煩?理論上,一門編程語言只需要非常簡單的語法,就可以寫出任何形式的程序。(可以搜一下「圖靈完備」)但是為什麼還有這麼多編程語言呢?為什麼有的編程語言適用於某個特定領域呢?為什麼人們會覺得用python寫點小程序比C要來得方便呢?C語言和現代高級的腳本語言比,語法實在可以用「簡陋」來形容,標準庫提供的東西也不多,實際編程要用到的一些數據結構都要自己去實現。在自己「造輪子」的過程當中,你會自己去感受諸如內存分配這樣的事情,在這個基礎上理解其他語言一些高級數據結構的實現原理。比如說鏈表,比如說內存池。

公式和代碼的區別

雖然說一開始學習編程的時候,許多同學都會把C語言當做一個計算器來用,比如說我輸入一個變數a,然後計算它的一個函數再輸出。在這個層面上,我們可以說,如果不考慮溢出的情況,數學公式(或者說理論上的演算法吧)和實際代碼可能是對等的。這是非常簡單的情況。但是當我們的程序越來越大,步驟越來越複雜,寫起代碼來可能就沒那麼簡單了。比方說,我們用C來寫高精度相乘,最簡單的情況是兩個數組,每個元素代表一位。如果在腦子裡想,可能會很簡單:就是逐位乘然後相加嘛。可如果你真動手寫了,你會面臨這樣的問題:

  • 既然我的數占不滿整個數組,那到底是靠左還是靠右?
  • 乘法的過程不能一次結束,我需要一個臨時數組來容納中間結果嗎?
  • 我怎麼知道這一輪乘的數是十位、百位,還是千位?相乘的函數應該有幾個參數?
  • 如果題目包含小數,我怎麼知道最終結果小數點後有多少位?我應該怎麼輸出?
  • ……

儘管在搞競賽的人看來這簡直就是入門都算不上的題,但是還是有很多人不能一次寫對的(poj1001,比如我……)。數學上的演算法和公式是普適的,但是要實現成程序,就必須要落腳到具體語言的語法上。為什麼人們說要學好編程要多練習?因為練習就是一個踩坑的過程。我這一次踩到這個坑了,知道這裡容易出錯,我總結下來,以後也是如此。天下大事必作於細,所謂的代碼能力就是這個。對編程的初學者來說,知道不等於會做。所以如果有什麼程序自己老是寫不對,不要一下子就灰心喪氣,但是要對它有個印象。比如說數組不會自動初始化,比如if不加花括弧就只執行後面一句。

C語言與底層系統

我們講,C語言在出生的時候,因為作了適當層次的抽象,才能抓住歷史潮流成為最流行的語言之一。這個所謂的「適當層次」,意思就是既避免了直接面向機器指令,又不完全將計算機運行的原理隱藏起來。於是你稍微學深入了,會產生許多疑問……

  • 為什麼printf("%u", -1);結果會輸出4294967295?
  • 為什麼數組訪問a[-1]但程序沒有出錯?
  • 為什麼char str[]="abcd";我就可以修改str[0],而對於char *str="abcd";我這樣做程序就會出錯?
  • 為什麼我#define G 3+3而G*G的結果卻是15?
  • 為什麼scanf的參數名要加一個號?
  • 為什麼printf和scanf的參數可以是不固定的?
  • 為什麼一個浮點數加了10次0.1之後結果卻是0.99999...?
  • 為什麼一個局部數組開太大了程序會爆掉?
  • ……
    多數問題,深挖下去都和計算機體系結構、計算機內部數據表示、可執行文件格式、編譯原理等內容相關。知其然而不知其所以然,就很難說自己了解C語言。

數據結構

作為一個看見演算法就暈的非ACMer,我想我本來沒有什麼資格說數據結構。不過我想換個角度談談這個問題。數據結構和演算法的重要性自不必說,太多人都會像一個長者一樣叮囑你要想程序寫得好,數據結構最重要。數據結構的確重要。可是你有沒有想過,到底什麼是數據結構,數據結構的本質是什麼?

有一大批講授數據結構的書籍一開始就把各種數據結構的概念灌輸給你,然後帶著你用實際的代碼去實現這些結構(多半是C++或者Java的書吧)。不過我覺得這些作者仍然忽略了一個問題,即:這些東西有什麼用?

事實上,每種數據結構都可以看作是對現實生活中物件的刻畫。為什麼會有棧?因為有很多場景需要先進後出。更本質地說,是在這些場景裡面,先進的需要包含後進的才能完成。比方說C語言函數的調用棧,逆序表達式的求值。或者在生活當中,假設我們要拆一台電腦,我們得先打開它的外殼,然後拆下大零件,最後弄下大零件里包含的小零件。如果我們要裝配回去,我們要先裝上小的,再裝上大的,這裡有一個先後順序。我們就可以說,當我們拆機的時候,各個零件組成了一個棧,外面的殼在棧底,裡面的小部件在棧頂。當然,在修電腦的時候,我完全可以把所有的零件一通亂地扔在我的床上,要裝上去的時候再找,不用像數組一樣有序排列。為什麼?因為當我完成步驟k的時候,我內心清楚k+1步需要哪個零件。而寫程序的時候,比如求逆序表達式的值,我就沒有辦法知道下一個「零件」是什麼,我只能猜測是棧頂元素。因此,在實際程序中,它必須有序。這就是棧這種數據結構的來源,它是一種抽象。本質上講,這也是個信息的問題。

其他的數據結構,比如隊列、樹、哈希表等等,都一樣可以看作是對現實生活中事物運轉方式的刻畫。比如樹是一個極其典型的遞歸結構,想一想中世紀歐洲的封建制度,其原則是「我只需要對我下面一級的人發號施令就行了」。所謂二叉樹,它的特殊性在於它是樹的最簡形式,節點有兩個子節點的情況是生活中最常見的,比如我們的四則運算就可以用樹來表示。嗯,說到四則運算,我們可以把普通的中序表達式轉化為逆序表達式,本質上也就是把一棵二叉樹變成了棧,感受一下這個演算法。

功利一點?

其實如果僅就題主的問題本身,我想我沒有必要說那麼多。我個人感覺,我校軟院對大一新生的C語言考察要求還是不高的(可能是我校太渣?)。期末上機三道題,第一題無腦,第二題要考到C語言里的許多語法內容,第三題會涉及到數據結構,不過不懂的人憑感覺寫估計也能過幾組數據。所以如果說你的目的僅僅是通過考試拿一個不錯的成績的話,大概沒有必要花這麼多時間去看這些「有的沒的」的東西。後面一些回答提到的東西大概是從從事C開發的專業人士的角度闡述的。作為大一新生,其實你就像我,不知道自己以後會從事哪方面的工作,也許去干前端也說不定。我絕對不相信一個對操作系統沒什麼了解的大學生真能像某些人建議的一樣啃下APUE,更何況一個連C編程和Linux操作都不熟悉的呢,是吧?

如果你所在的學校還沒有腦殘到要筆試學生C語言的程度,並且你們用的教材是譚浩強那本的話,我覺得你可以扔掉它了,真的。譚老對我國計算機普及作出的貢獻當然很大。但是都到2015年了,學校還在用這本書,我看這不是譚浩強之恥,是學校之恥!我沒有看過C Primer Plus這本書,寫作這個回答的時候到學校圖書館翻了翻,感覺還可以。學計算機的話,就不要畏懼這些大部頭了。厚不一定代表難讀。大學的課堂老師一學期也講不了多少內容,多數還得自己去看。一個好的老師,只能說給學生以最正面的引導,讓他們少走彎路。

現在這個時代,大學生可以接觸到的項目很多,主要的類型無非是跟Web相關,其中的大多數也用不到C語言。不過不要因此就否定C/C++的價值,對此知乎上的大牛們講的很多了。

還有,千萬記住,C和C++是兩種語言,C++也不完全兼容C. 不信?在C和C++里分別輸出sizeof("Z")試試。

建議書目

Code: The Hidden Language of Computer Hardware and Software
The Information: A History, A Theory, A Flood
Head First C
C Programming: A Modern Approach
The C Programming Language
Computer Systems: A Programmer"s Perspective
Expert C Programming: Deep C Secrets
Pointers on C
C Traps and Pitfalls

(題主可以看一下鄙人拙作cguide)
(答主也是大一學生啊喂,有什麼表達不準確的歡迎指出,不過請輕噴...)


C Primer Plus
做題,順便看C陷阱與缺陷,很薄一本
然後看C語言介面與實現,看不懂的話直接抄代碼做書後題就行
這時候你應該有一些關於C語言設計和歷史的一些感覺了
繼續做題,可以做一個項目,比如查字典程序
然後看C和指針,看看你能不能理解裡面的一系列指針進階操作
然後看C專家編程
然後回過來根據你已有的積累,嘗試自己寫一個C語言容器庫


去網易雲課堂,計算機專業體系課程看浙大翁凱老師的視頻。

既然是小白,每次我遇見的小白都刷新我的認知下限,在我這裡就把你理解成了電腦都用不利索的小白。

為什麼不推薦書,因為我見到的小白,很多是看不懂書的,不知道為什麼,我也很無語,然而我又沒心情給她講。。


除了看視頻你該怎麼做。。

1.妹子就找個本專業大神(一般都是男生),沒準還有一段美好的故事發生呢。。(然而這都看臉)。

2.試著把你的操作系統用的麻利點。

3.你可以看書了。

還有,看1000遍不如試著做一遍,把代碼敲出來,當然我又要安利visual studio了,不會用就翻我答案,簡直就是為小白量身定製。。。


我是一名寫了N年(N &> 8)C語言的軟體工程師。

希望我的經驗能給初學者一些建議或者啟發,本文沒有涵蓋C語言的方方面面,但是對於想入門的初學者來說足夠了。另外需要說明的是,我不是大神,真正的大神是開發C語言標準,寫標準庫,寫編譯器的那幫人,但我自認為我的C語言掌握的比周圍的很多人都要好,所以才敢在這裡發言。

想學一門編程語言,不知道學什麼才好? 毫無疑問 C 語言啊。

C 語言是整個計算機體系的基礎,往下可以操作硬體(不止X86計算機,還有ARM,DSP,單片機等各種微處理器)寫Firmware,寫驅動、寫OS,寫編譯器,往上可以寫 App,並且大部分的計算機書籍里的演算法都是C語言描述的。

所以學會了 C 語言,就是掌握了軟體領域的必備技能,以後再學其他的比如C++,Java,各種解釋性語言、就是小 Case 了。

我初學 C 語言是在 2005年大二,那個時候,上課的模式是老師在上面講,我們在下面聽,然後就沒有然後了,因為沒有電腦練習,我根本就沒有機會在課下了解更多的東西。學完了一本書,C 語言是幹嘛的我都不知道,那個時候我並不知道 C 語言是用來寫軟體的,更何況別說軟體了,電腦都沒怎麼見過。

我們當初用的教材名字叫 《VC++ 語言程序設計》,這導致我很長一段時間都沒不知道VC++,和 C++, C 的區別,OMG!!

對 C 語言的深入學習是在研究生期間,我認真地從頭到尾翻了一遍H.M.Deitel 的那本 C++,有了電腦簡直如虎添翼,我有陣子天天在宿舍編程。對了,我是在學習C++的時候,順帶學習(複習)的 C 語言,反正 C++ 的書上總有會 C 的。

這裡是我總結的學習 C 語言的幾個步驟,其他編程語言基本類似,希望對大家有所幫助。

1. 看書

學習一門編程語言少不了先學習基本語法。

C語言的語法也就是變數,數組、指針、表達式、邏輯操作、函數,宏定義等等。學習這些先買一本入門級書籍,其實大都差不多,最經典的就是譚浩強的那本了,雖然在知乎上沒少被人黑,但是畢竟流行了這麼多年,總歸是有可取之處的,其實作為入門書,你不能指望從它裡面得到你想知道的所有東西。

除了基本語法,C 語言另一部分是標準庫。

這一點很少被C語言入門書提及,但是你要想寫出一個像樣的程序的話,標準庫必不可少。推薦這本世界級C語言專家編寫的《C標準庫》。

2. 寫代碼練習

要想學好一門編程語言,看書遠遠不夠,一定要把書里的代碼搬到電腦里。

相信大多數人都是使用的Widnows,那麼就下載安裝一個Visual Studio吧,用哪個版本?最新的 VS2017 毋庸置疑。

喜歡 Linux 的朋友,就先下載 Glibc 庫,然後安裝 gcc, gdb。

好了,有了開發環境,接下來一切變得簡單,並且好玩。

試著寫一些簡單的代碼,比如 Hello World,文件讀寫,數學操作,常用演算法,等等。

這是我以前練手時寫的

3. 總結心得體會

把你覺得很抽象、難以理解的東西放到 VS 裡面進行調試,會有很多發現。我以前電腦里就經常會有一個名字叫 Test 的工程文件夾,哪裡有疑惑了,就把代碼放進去,一 Debug,全部的疑雲就解開了。

比如這樣,了解 Struct 內存結構

比如這樣,了解 Union 的內存結構

比如這樣,了解 指針和數組

然後把這一切,記錄在一個 Word 中,這樣知識就變成自己的了。

這是我從前總結的一個文檔

4. 寫個小作品

基本知識掌握的差不多了,試著寫個小程序。

看著人生第一個自己開發的程序,會有很多的成就感,並且在寫程序的過程中,你的編程能力會有質的飛躍。

我曾經寫過一個控制台的五子棋遊戲,可惜年代久遠,現在已經打不開了。

另外需要說明的是,想在 Windows 上寫一個有界面的程序的話,還需要學習Windows API,不過這彷彿是 C 語言之外的東西了,單單學習 C 語言,一個控制台程序就夠了。

最後一句話作為總結,想要使自己的編程能力突飛猛進,一定要不斷地勤加練習。

=========更新========

C語言學習路線圖

參考此文:

C 語言學習路線圖 - 知乎專欄


具體的方法:把他講的或者PPT上提到的你不知道的名詞記下來 然後開始谷歌(別用百度) 這個你可以課後做也可以課前做
如果一不小心你點開一個維基頁面
結果裡面又是大量你不知道的名詞
繼續遞歸搜索
你不是不懂C語言
是缺少常識 邱超凡的答案里說了很多常識 先確保你看懂那些吧


要有能夠學好 C 語言的信心!

C99 標準撇去標準庫的東西就 170 來頁,比你的教科書薄把!


圖 ISO/IEC 9899:TC3 目錄


先入門 入門以後的進階有很多大神都給過經驗了 自己在知乎搜
我說的入門不是指迷迷糊糊地跟著老師敲代碼記筆記
看c prime plus
別管你老師講的怎麼樣天花亂墜
很大可能他的啟蒙書也是primer plus
但是他為什麼不給你們推薦這本書
以及國內絕大部分高校都不用它做教材
其中一個原因是因為講的內容比較多,從基本語法講到簡單的c庫,鏈表,介面,樹這些數據結構內容太多課時安排不來
另一個方面大概也許應該就是。。。。出於老師私人目的給你們推薦了你們本校自編的教材或者清華大學出版社的那本………至於什麼目的不好揣摩

先把c primer plus一口氣啃一遍 把上面的例子對著電腦敲敲
寫程序無它,唯手熟爾。
等你看完大半的時候是不必擔心期末考試的 因為期末考的重點你已經掌握了
實在不理解找人也無法解決的疑惑先記下來,以後積累的知識多了就好了
至於上面說的文件,進程,IO什麼等你以後學操作系統的時候自然會學,不急,有興趣可以自己提前看
還有現在跟你說socket編程,內核什麼都是耍流氓
要知道是怎麼做成軟體界面的去學MFC或者qt
但是你至少應該先入門敲代碼敲一段時間吧
我們學校用的教材是清華那本。看完後知其然而不知其所以然
但是c primer plus就講的不錯。會跟你講緩衝區,講內存。理解不理解先不說,起碼知道有這回事了啊,能把這個小小的程序跟黑乎乎的DOS框還有你面前呼呼作響的大傢伙聯繫起來了啊
哦,忘了說,自己調試程序的時候最好單步調試,並學著查看內存變數,理解程序運行原理。
還有,將來好好學彙編,數據結構,操作系統,計算機組成原理,編譯原理
許多批判c語言勸你不要學的,語言只是工具沒那麼重要的,因為別人已經找到更適合於自己發展的語言了。但是對於初學者來說,基本是在問你「何不食肉糜?」
先別管那麼多,好好學自己的。多敲代碼,多思考。
不要覺得c primer plus很厚不適合看
在我們這個領域有很多這樣的磚頭書的
深入理解計算機系統,Windows核心編程,c++primerplus ,Java核心編程 演算法導論,講Linux ,unix的隨便拉出來一本都會厚到讓你覺得人生無望
要是抱著這樣的心態基本上就不用學了
常用網站:知乎,博客園,CSDN,chinaunix,網易公開課,魚c論壇


反對上面大部分答案。

學好只有一條路: 多寫代碼。。。

計算機是一門學科,一個專業,
但編程不是一門學科,而是一項技能
技能,需要不斷地實踐、練習。

看完所有經典奇書,光看不練不寫代碼,
還不如隨便找本書,把上面所有例子都手打一遍(比如看譚浩強的教材--公認的垃圾編程教材)

我是在vc6上敲著敲著就學會c++的,c都沒正兒八經學過。


邱的回答很精闢,也很有含金量。王子豪這個答主我就不忍不去批評。邱的答覆很值得思考,為什麼你要嫉妒人家,誣陷別人的回答具有計算機導論的風範?
我就話一番功夫和你較勁,一則替人打抱不平,二則作為一個反面教材。
首先,為什麼要來知乎?知乎一開始最吸引我的地方是這裡大牛多,但是現在牛越來越少了,騙贊的卻是越來越明目張胆了。
如果你只是想獲得存在感,請你遠離這個平台,去貼吧水去吧。
回到正題,該怎麼學習C語言?我也是大一我不好談這個問題,邱已經回答得很好了!
為什麼我那麼崇拜邱,第一他回答的真的很到位,第二,他說的那個高精度運算是我遇到的問題,當初面試的時候,管理員就是出這道題的。學http://VB.NET的人表示一開始根本不懂怎麼回事,用C 勉強算了一下,根本取不到想要的值。
我想說的是,因為很多語言可以通過類似於JAVA 庫的東西拓展功能而導致程序員往往忽視最簡單的問題。
難道這就是你不思考的理由嗎?
要想學好C越是要思考那些簡單的東西,刨根問底才能學得好。但反觀某豪,信誓旦旦的對題主說世界上還有許多新奇的語言。這不是答非所問嗎?給你一萬個語言,你不深入思考,而是說世界上還有很多語言這種逃避現實的話你覺得你能學好嗎?
好了,這次是真的不說廢話了 ̄ 3 ̄
要學好C 語言首先你就得明確,一定要刨根問底。遇到坑的時候千萬不要吝嗇踩一腳。
其次,一定要多練習。不要局限於課本練習,自己想要做什麼程序,也可以當作一種練習做下去。
第三,看好書。一些經典的書都是翻譯自外文書籍,沒有了原滋原味,而且譯者的思想也逐漸的掩蓋了原作者的思想。如果你想要學的好,那麼你還是看原著吧( ̄、 ̄)這一條推薦打算研究演算法的人,如果你不研究演算法我覺得看了也許沒什麼用,但是如果你搞演算法,看原著學人家的思想那是很重要的。

其次真的沒有什麼好回復了,學習沒有捷徑,一味的尋找捷徑那是在作si,這個專業的話要吃教訓,只有感悟了教訓你才能長經驗。
( ? 3?)我不會告訴你,一門語言可以學的很快,打開書從頭看到尾就可以算學完了。
但是那有用嗎?啃的只是知識點,學習的方法是文科,出來的人恐怕也只能去中專混一口飯。


首先,軟體工程的學生和學習C語言沒有什麼關係。

其次,學習C語言的最主要的途徑就是多練,紙上得來終覺淺

對著書上的例子,一個一個的去實現,等到你把這些都學的差不多的時候,可以自己思考著用C語言寫個比較大的項目,比如五子棋,貪吃誰之類的,這樣基本就算學會了C語言了。


突然想回答這個問題了

我的解決方法是 看書 + 搜索引擎

看的書不應該局限於一本C的書,好幾本C的書,好多其他類型的書,比如CSAPP,同時,看書的次數也不局限於一次,翻爛了都不為過。

而搜索引擎的用處是 找各種資料,不建議用百度,有能力用英文在bing與谷歌上查找

還可以搓輪子,

對於無法理解的問題,建議先放放。

一些題外話
眼界開闊一些,編程語言不止那幾種。不要人云亦云。

我個人目前最討厭的語言是Java,至於原因,有人贊再說吧


開始解釋我為啥不喜歡Java,但先說明,Java的確是個不錯的語言。

理由一:
NullPointerException (不知道拼對了沒)
雖然說C#也有類似的東西,然而為何Java出現這個異常的平率如此之高。。

理由二:
用的人太多
雖然用的人多不是件壞事,然而如果全世界的程序員都學習使用Java,可能這將比世界末日還可拍。畢竟物種豐富性還是相當重要的。

理由三:
總是會接觸到一些只會寫Java,而心氣很高的人。這幫人,呵呵

理由四:
Java 的持有者,某古文公司,我敢打賭,沒有公司比他還要*****。明明是律師事務所,還要擠破頭進這一行,真是比格力還可怕。

(以上就當是開開玩笑,別說我黑Java**)


我覺得很大的問題在於初高中時期,我們都把時間浪費在中考和高考上,而選志願時也是匆匆而定,導致真的選擇了某個專業後,完全沒有任何基礎。更悲劇的是,大學教授畢竟不是教師,不太會教課,導致了題主現在的情形。我的建議是,可以買一本英文的C語言入門書來看(不要選中文的,翻譯錯誤太多),然後多照著書上的題目練習,再輔以學習一些關於UNIX系統方面的知識,這樣,C語言才可能學得比較好。


抱著不恥下問的精神,熬幾個月,你就學會了,有些苦難沒有捷徑,都是硬生生地啃下來的


入門學c幹嘛 Python就行


對於新手來說確實很迷茫,我是過來人,曾經不知道方向。有時候捧著一本C語言的書翻來覆去地看,怎麼看都看不完,看完了也看不懂,慢慢地知道是學習的方法不對。我後來去一些IT相關的網站找了很多教學視頻,有人講課帶著你學比自己看書生動得多,我印象中最牛逼的算是CSDN了,還有極客學院,慕課網什麼的。後來在CSDN看到一個合作教學的黑馬程序員,那上面視頻講得特別詳細,就是視頻太多太長了,一時半會學不完,不過按照那個學習路線圖學下來,感覺還不錯,收穫倒是很大,資源什麼的都是免費的,這點還不錯,反正對所有人都是不要錢的,不看白不看。甩個鏈接,希望不要被河蟹 2017C/C++學習路線圖(附全套自學視頻+工具)-黑馬程序員IT技術論壇 - 黑馬程序員快速入學必看論壇


首先,取決於你對C語言學好的定義,如果是為了以後其他語言打基礎,看看C primer plus,一站式學習C編程,然後去杭電啊,vscode啊這樣的網站去刷刷題就可以了。
如果你想更加深入的學習,那就任重而道遠了,可以去看看各種函數的源碼,去搞些操作系統的源碼看,然後就是多寫多練。

教程的話,網上有很多,但個人還是比較推薦那些培訓機構比如傳智播客的教程(資源可能不太好弄,可以去淘寶買,幾十塊錢,相比較你能收穫到的知識實在太值了。)

學好C只是第一步,學編程最重要的就是多編碼,多編碼,多編碼。

另外就是多和比你厲害的人在一起,始終讓自己是圈子裡最弱的人(當你技術成為一個圈子裡中上等,就馬上去融入一個技術水平更高的圈子。)

還有永遠別滿足於學校教給你的東西。。不斷學習。

如果是妹子,可以私信我要教程的資源(逃)。。。。。。。。


掌握c庫,熟悉常用的api; 掌握數據結構鏈表、排序等;推薦《代碼大全》看完後知道什麼是好代碼什麼是爛代碼。最重要還是有實際的編碼歷練,有個老師幫你看哪裡寫得好,哪裡有問題。建議直接在linux下開發一些網路相關的程序,如ftp,http服務


反對各種建議題主看視頻、看課件、刷題庫的回答。

C語言不是沒有良好的入門書籍(比如C Primer Plus,雖然中譯版有些坑但也能看得過去),看書後多加練習,遇到問題問靠譜的老師、學長或者其他人就可以快速而高質量地達到題主的要求(至少在不遇到坑B題的情況下,期末考拿個不錯的成績還是可以的)。有如此條件還跑去看視頻、看課件、刷題庫,簡直就是浪費時間。


我們老師講課我也是聽不懂的,
然後偶然發現網易雲課堂翁老師的C語言
算是入了門
學校有實驗課,上課不停的寫代碼找錯誤找不到查書問老師。

多寫多看就可以。

那會實驗課才熟悉了if while數組等等好多知識。
然後發現這就完全是一些數學而已。
T_T突然覺得也不是很難,考試(#?Д?)96。


不是很贊同目前得票最高的答主的答案,提主的問題是如何學習C語言,說需要的具體的建議,而不是一些枯燥的計算機理論。

提主未提到是否有編程基礎,所以這裡就以我自己的經驗和需要的坑說一下,我自己也是大二的,從高一開始學習編程。

個人認為的第一點就是,如果答主學習C語言的目的是為了考試或者交項目,那就不要去糾結計算機的底層和結構了,善用搜索引擎找到具體的教程或者實例來學習,一定要多動手寫。如果想真真正正想學好C語言也沒有關係,這些系統性的知識可以補回來,而且因為有了編程經驗,所以認識會更深刻。我的經歷就是這樣的。

第二就是,如果答主有多餘的時間,可以嘗試著去學另一門簡單的語言,比如python或者php。因為C語言涉及底層,對於沒有經驗的新手來說學不懂很容易產生挫敗感。而python和php沒有這樣的問題。學習另一門語言的目的是,編程語言的本質是相同的,學習一門語言同時也會對另一門語言產生更深刻的理解,而這個過程你自身是感受不到的,或許有一天你會發現原來弄不懂的問題突然懂了,這就是編程中的頓悟。

第三就是要有意識的培養自己的編程思維。現在許多高校還在用VC6和過時的教材,也不注重思維培養。舉例,上次我的老師給我和班上另外一編程很好的同學下了個關於演算法的任務。完了之後我找對方要了源碼來看,卧槽簡直爆炸,雖然程序本身沒出錯,但是變數名看不懂,代碼冗餘,結構混亂,看了一半放棄了。所以答主需要去有意識的避免這些問題,即培養 應該怎麼寫 和 不該怎麼寫 的編程思維,這方面也需要搜索引擎。

凌晨手機碼字,若有不當之處,請多見諒。


推薦閱讀:

如何評價迅雷9?

TAG:學習 | 大學生活 | 軟體工程 | C編程語言 | 計算機科學 |