C語言和內存管理有什麼關係?為什麼說學習C語言的關鍵在內存管理?

1.看了很多人都說學習C語言精髓在內存管理,還要熟悉計算機體系結構和操作系統,這是為什麼?

2.C語言不就是一種高級語言嗎?為甚麼和這些搭上邊呢?

3.C語言沒有自動內存管理,內存管理不是操作系統裡面的東西嗎,難道也是C語言裡面的東西?


1.看了很多人都說學習C語言精髓在內存管理,還要熟悉計算機體系結構和操作系統,這是為什麼?

這要涉及到C語言誕生的時代背景。C語言是在上世紀70年代初誕生的,是為了高效編寫/移植Unix操作系統而生。 所以,C語言帶有強烈的和底層掛鉤的特性。比如,它的指針,是確確實實的指向進程內存空間的對象,而像Java這種高級語言的「對象」, 已經高度抽象化,完全脫離了內存空間中的對象這一概念(你只要明白它是一種描述某事物的對象,不需要明白它關聯著內存的某個位置,Java的虛擬機全權幫你負責這些東西)。再比如, C還有函數「調用慣例」這個概念,指函數參數進棧次序,棧空間組織這些ABI層面的東西。再再比如, C實現了內存管理,什麼意思呢? 你可以把裸機視為一台最低級的機器,它的內存模型就是一個線性的物理內存空間,由機器指令訪問。在這之上,C語言建立了更高層次的抽象,把這台裸機抽象成更」人性化的「機器, 它的內存空間是每個進程一個線性空間(這就需要底層操作系統的協助了), 需要區分棧區, 堆區,等。

當然,不明白這些東西,完全可以用C來編程。它也算「高級語言」, 有類比自然語言的這種簡單明了的語言特性, 學習起來不太費勁。 你依然可以拿來寫很多程序, 寫很多演算法。 但是,不明白它的底層原理,很多C語言的一層」語言層面「的要求,你只能硬背著去使用。當你明白後,使用進來更通透。

2.C語言不就是一種高級語言嗎?為甚麼和這些搭上邊呢?

C被稱為高級語言的重要原因是,它提供了更自然的,類人類語言化的語法 ,比如,if ... else; while...do...等。這些重要的抽象,使計算機新手都能拿C語言像模像樣地寫程序。 但其實,C

本質還是偏底層的語言,它很多特性是和底層的計算機直接掛鉤的。 比如指針,就是內存位置。

位操作, 直接映射到底層指令的位操作。等等。

作為類比,Java也是高級語言,但它基本完全屏蔽了底層特性,它本身就實現了一台高級抽象的JAVA虛擬機,還有自己的」指令「 --- 位元組碼。

3.C語言沒有自動內存管理,內存管理不是操作系統裡面的東西嗎,難道也是C語言裡面的東西?

沒錯,都是操作系統的東西。你可以不知道,依然能用C編程。但不明白這些,C的威力就被削弱了。 純粹編程的話,在各個領域,可能都有比C更適合的語言。 所以,從計算機學習知識角度,利用C,深入去學習包括編譯,鏈接,操作系統等知識,我覺得是非常合適的。起碼就我個人而言,非科班,是通過C這個窗口,學習了很多底層計算機知識; 從使用角度,那麼選擇適合的語言就好。


在此拋磚引玉,講講自己的見解,可能更適合新手:

1. 看了很多人都說學習 C 語言精髓在內存管理,還要熟悉計算機體系結構和操作系統,這是為什麼?

因為不熟悉計算機體系結構與操作系統,你不可能順利學好 C 語言,學的也僅僅是 C 語言的語法:if, while,for 等。

為什麼要熟悉?因為 C 語言與操作系統的底層緊密結合,比如指針的大小取決於你的操作系統是32位還是64位,結構體的size 為什麼會變大(pending),unsigned int 的內存表示(整數為什麼會有溢出變負數),浮點數的內存表示等等。

看完了,還要知道函數調用的彙編過程,了解彙編與 C 語言的對應關係。

除此之外,你還要知道靜態鏈接,動態鏈接與裝載,linux 系統需要知道 ELF 文件格式,符號表,還有.bss段放未初始化的全局變數,.data 段放數據,.rodata 放 const 常量,往深了還有弱符號,強符號的坑等等等等等[0]。 熟悉了這些就可以做很多意思的事情了[1]如自己找符號表的信息來獲取所有函數信息,自己手動安裝 apt-get 的東西等。

內存管理是精髓是因為沒有多少語言可以讓你自己操作底層的內存,申請,修改內存的東西。內存越界會讀什麼東西,系統的內存模型是怎麼樣,我用 malloc究竟申請的是哪裡的內存,怎麼樣重新解讀內存等等[2]

【以上,只需要一本《深入了解計算機系統》,即可入門;輔助 C 語言書籍一起學即可】

2.C 語言不就是一種高級語言嗎?為甚麼和這些搭上邊呢?

高級語言是相對於彙編(助記符)而言, if,while,for以及變數 等語法,讓 C 語言可讀性高了很多,更像語言了。

3.C 語言沒有自動內存管理,內存管理不是操作系統裡面的東西嗎,難道也是 C 語言裡面的東西?

內存管理是操作系統裡面的東西, 但是你自己寫的程序也可以在自己的小內存里做管理。

[0]: C/C++編譯鏈接與裝載深入淺出

[1]: 用C實現JS里eval(「function(arg1, arg2)」) 以及 How does apt-get work exactly?

[2]: how to invade memory in C


因為C語言是裸奔的,沒有自動內存管理。那麼當然要你親自進行手動內存管理。

其它的高級語言,腳本語言大都有引用計數,Java有基於掃描的垃圾回收。你創建一個對象,不用太考慮什麼時候應當釋放它了。

另外補充一下一對一的回答:

1:C語言的精髓在於裸奔,內存管理是你不得不做的麻煩事。

2:當年的高級語言,還比較低級。

3:操作系統管理各個進程的內存,你自己管理你進程裡面的內存。具體的東西,你用過之後自然就知道了。不然光憑嘴說很難解釋清楚。


看了很多人都說學習C語言精髓在內存管理,還要熟悉計算機體系結構和操作系統,這是為什麼?

我不認為「學習C語言精髓在內存管理」這種說法成立,更不認為「學習C語言」「還要熟悉計算機體系結構和操作系統」。

不知道你這裡的「為什麼」是什麼意思,如果你是問為什麼「學習C語言精髓在內存管理,還要熟悉計算機體系結構和操作系統」,那你應該問持這種觀點的人;如果你問為什麼很多人持這種觀點,我的看法是他們誤解了C語言或者是在人云亦云以訛傳訛。

C語言不就是一種高級語言嗎?為甚麼和這些搭上邊呢?

問得好!要是我也會這樣問的。

不過,這還是那些需要持「說學習C語言精髓在內存管理」觀點的人來回答。誰主張誰舉證。


推薦閱讀:

講C語言內存管理的書籍或者博客?
筆記本內存佔用突然變高,本來29%左右,現在開機就58%,沒開任何程序啊,急求,感謝?
asp.net 應用佔用內存過大如何排查?
Python可以視作同時支持像C++一樣的RAII特性,也具有垃圾回收GC的編程語言嗎?
非同步操作時的內存管理?

TAG:編程語言 | C編程語言 | 內存管理 |