零基礎編程入門(02)——計算機起源與組成

零基礎編程入門(02)——計算機起源與組成

在上一章中,鄙人已經向大家講解了本教程的一些相關內容,那麼從這章開始,我們就正式進入教程的學習,在我們開始學習Java語言前,鄙人想先為大家講解一些計算機與編程的來龍去脈,以及一些編程前所需要的預備知識,以便零基礎的同學能更好更順利的進行後續章節的學習,所以希望零基礎同學切勿略過此章節,認真閱讀,有所收穫,不能理解的部分也請向鄙人詢問或通過百度搜索獲取更多的相關解釋。


一、計算機的起源與歷史

說到計算機的起源,首先從字面上就可以了解到計算機就是用於計算的機器的意思,事實上最早的計算機也的確就是一台用於計算的機器,早在史前社會,人類就已經發明了計算機,它是長這樣的:

圖1,上古人力二則運算計算機

同學們看了肯定很驚詫,哎喲我去,這不就是幾根破繩子嘛,和能操紅警打星際(嗯,沒暴露年齡吧?)的計算機有什麼關係,你不是在忽悠我吧?

那鄙人得說,就這幾根破繩子還真是一台計算機,原始人使用這種稱為結繩記事的方式來記錄日常生活中的一些數據,比如,鄙人今天下海撈了3條魚,那麼我就在一根繩子上打3個結,記住我撈了3條魚,然後我吃了一條,就解開一個結變成2個結,如果到了月底發現框里的魚和繩子上的結對不上,那魚肯定就是被我老婆偷吃了,晚上回去好好教育教育...

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

從這個故事種我們可以看到,這幾根破繩子有如下幾個作用:

  1. 可以用於記錄數字,1個結就代表數字1,2個結就代表數字2,以此類推
  2. 可以進行加減運算,比如我繩子上有2個結,然後今天又撈了3條,那麼就再打3個結,變成了5個結,那麼就是2+3=5。然後晚上我吃了1條,於是就解開1個結,變成4個結,那麼就是5-1=4。

有了這兩個個作用,我們就得到了一台完整二則運算計算機,因為一台計算機只需要有兩個功能:

  1. 記錄數據,將需要參與運算的數字記錄下來
  2. 對數據進行運算,對記錄下來的數字進行運算

但是由於只能用於加減運算,所以就稱為二則運算計算機。


但是顯然,這種計算機運行效率那是相當的低下,記錄的數據也非常有限,比如我昨天撈了200條魚,那我就得打200個結,繩子是不是夠長不說,就是打結的功夫也是相當的累人,指不定比撈魚還慢,而且還只能做加減運算,比如如果我和隔壁張三做大額魚類期貨交易,要做乘除法怎麼辦?200條魚的繩子乘個2就是400條,那我得再打上200個結,乘個10就是2000個結,我去,這活沒法幹了。

所以,講到這裡鄙人不得不佩服我們古人的智慧,公元3世紀(200多年)的時候,東漢人徐岳發明了這玩意兒:

圖2,國產人力四則運算計算機

沒錯,就是算盤,不過很可惜,由於鄙人小學珠算沒及格,這東西咋用的我早丟給爺爺輩了,但是!鄙人可以告訴你,算盤相對於繩子,有兩大改良:

  • 算盤加入了進位

我們可以看到算這個盤每一列有上面2個珠子和下面5個珠子,下面5個珠子每向上推1個代表加個1,而上面的珠子每推1個代表加5,上面2個珠子都推了就代表加10,這就是個典型的10進位,但是由於算盤有很多種,有些是上面1珠下面4珠的,所以並不能說所有算盤都是10進位,事實上更多的是混合進位,恩,說遠了,不懂沒關係。

當然,你現在還不知道什麼是進位,鄙人後面會再給大家詳細解釋,不明白的同學稍安勿躁,接著看下去。

  • 算盤加入了乘除法

算盤可以通過一定的口訣,實現乘除法,所謂口訣就是一些預先設計好的操作順序。比如第1步推這個,第2步推哪個等等,然後操作人員只需要根據口訣去一步步操作,就能對算盤上當前的數據進行乘除法。

當然,真正的珠算口訣要複雜的多,具體我就不說了,因為我自己也搞不清,沒做過賬房先生。看到這想知道的同學鄙人也不推薦你去研究,因為和我們要學的東西無關,無關的東西就不要學,這是學習的根本方法之一,有的時候我們需要剋制下自己的求知慾。

回到正題,從上面我們知道,算盤可以通過這些預先設計好的操作順序對算盤上記錄的數據進行乘除法,非常有意思的是,這些口訣,從本質上來講,就是一種程序,因為程序本質上就是進行某種運算的操作順序,而設計了這些口訣的古人則正是我們中國最早的程序員。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

看到這裡,我們同學是不是很震撼,感到特別震驚?所以說我們古中華文明的智慧是無窮無盡的,我們現代生活中的很多東西早就已經存在於中國古代,所以同學們切勿自怨自艾,國人當對身為中華人有信心,為身為中華文明的傳人而自豪。同時也要為我們將要學習的內容放鬆心態,古人都能發明的東西,你怎麼會有學不會的道理?


上面我們學到了中華文明的璀璨之後,接下來,我們把時間向後撥上1600多年,來到近現代的歐洲。

1941年,二戰正進行得如火如荼,德軍依靠優勢空軍力量,不斷對英國進行空襲,大量的城鎮在一夜間滿目瘡痍。英軍為了獲得對德國空軍的戰術與情報優勢,瞄上了德國了的用於電報加密的恩尼格瑪密碼機(Enigma Machine)。

恩尼格瑪密碼機大致上就是好幾個轉盤,當發報員通過旋鈕對機器進行日期設置後,每敲入一個字元,比如A,然後轉盤就會通過一定的機械運動,將其轉換為另一個字元,比如R,然後運轉規律會按日期有所變化,比如今天按A,輸出的是R,明天按A,輸出就變成C了。然後收報員在收到加密的電報後,輸入相同的日期,然後就能解密,然後得到正確的電報內容。當然實際的加密過程要複雜的多,因為還有變碼等等功能,這個我們就不關心了,你就先這麼理解吧。

通過這個機器,德軍能很好的防止英軍截獲軍事情報,所以,英軍為了破解恩尼格瑪密碼機,便從全國徵招各路英豪,齊聚一個叫布萊切利的小莊園,其中就有我們的人工智慧之父,提出了圖靈機的阿倫·圖靈,還有全國的頂尖數學家和頂尖電器工程師。

然後某一天,由於一個德國發報員的發送的報文有一個拼寫錯誤,抱著嚴謹的心態沒換密碼又重發了一遍正確的報文,英軍意外通過對兩份密文對比找到了恩尼格瑪的部分規律,然後在天才們的努力下,最終完整破譯了密碼機的運行規律。

但是,我們故事到這裡還沒有完,雖然已經找到了密碼機的運行規律,但是由於每破譯一份電報都要進行巨量的數學計算,即使有一群數學大咖協作,每一份電報破譯完幾乎已經是一個星期後的事情了,對瞬息萬變的戰局幾乎起不到任何作用。

於是在阿倫·圖靈的主導下,電器工程師赫斯·羅賓遜與湯米·佛洛亞斯發明建造了一台電器設備,名為克羅索斯,差不多長這樣:

圖3,克羅索斯電器計算機

這台設備由電力馬達驅動,其中用於記錄密文運算的電路模塊是可以替換的,以實現變換解密演算法,當操作員通過打字機完成需要需要計算的電報密文輸入後,這台設備便會開始根據記錄了演算法的電路模塊對電報進行解密,每秒大約能解密5000字。

這樣的運行效率顯然已經完全滿足了英軍需要,一份德軍密電幾分鐘後就能放到丘吉爾桌上,而克羅索斯則因為湯米·佛洛亞斯設計的獨特的可替換演算法電路模塊,而成為了世界上第一台可編程電子計算機。

然而非常可惜的是,由於英軍出於機密的考慮(恩尼格瑪破譯有很多黑歷史就不說了,比如故意放任已經破譯的密電,而讓多佛慘遭轟炸),克羅索斯長期被列為高級機密,隱藏在了機密文檔之中,而其計算機本身也在二戰後慘遭銷毀。

至於阿倫·圖靈更是在二戰後因其他原因被迫自殺,成為計算機界知名的慘案,至此,這段歷史也就再也無人知曉,直到近十幾年才得以曝光。但是此時,世界第一台電子計算機的桂冠卻早已被美國1946年製造的用於原子彈製造研究計算的ENIAC埃尼阿克計算機摘去,而他的設計者之一,馮·諾依曼更是依靠其對ENIAC埃尼阿克計算機設計方案的優化,一舉成為現代計算機之父。

(後注,克羅索斯破解的實質上是德軍在恩尼格瑪上衍生的更為複雜的Tunny密碼機,但限於篇幅就混為一談吧,事實上這也是需要克羅索斯需要能替換演算法的主要原因)

二、現代計算機起源

1944年,美籍匈牙利數學家與量子物理學家,馮·諾依曼正在美國洛·斯阿拉莫斯實驗室參與一件苦逼的工作,原子彈研發。由於原子彈研發過程中大量需要進行幾十億次的巨量的數學運算,他不得不僱傭了上百個妹子為其做算術題,然而依然完全不夠,無盡的數學題如同海綿一般吸幹了他那無窮無盡的腦細胞。

一個偶然的機會,他遇到了ENIAC埃尼阿克計算機研發部門的主管,在了解了其工作後,立刻產生了極大的興趣,然後在主管推薦下,便以顧問的身份加入了ENIAC部門。

當時的埃尼阿克ENIAC計算機設計方案中並沒有數據存儲功能,其操作方式極為原始,需要由妹子(不對,操作人員)通過電線插座面板(簡稱控制面板,是不是很熟悉)去進行輸入操作,然後再進行計算和輸出結果,其輸入數據操作時間往往比計算時間還長,加起來的運算效率可能還不如我們的算盤。

馮·諾依曼加入顧問團後,便開始著手對其工作方式進行改良,最終在1945年,寫了一份101頁的報告,提出了一個名為『EDVAC』翻譯過來就是『存儲程序通用電子計算機方案』的新型可編程電子計算機方案,而這個方案正是如今世界上所有計算機的根基,70年了,依然未被推翻,所以如今所有的計算機也被稱為馮·諾依曼計算機,而其本人也被稱為現代計算機之父而享譽全球。

在這份報告中,有三個關鍵點:

第一、計算機中的數據應當使用二進位進行存儲與運算

第二、程序也是數據,應當與數據一同存儲在計算機的存儲器中

第三、計算機應當由五個部分組成,分別為:運算器、控制器、存儲器、輸入設備、輸出設備

這三點非常重要,下面我們就一個一個來看。


第一點,計算機中的數據應當使用二進位進行存儲與運算

講到這一點,我們先要理解什麼是二進位,前面提到了一個進位的概念,而講到進位,我們首先要明白什麼是位,所謂的『位』就是我們日常生活中常說的:個位、十位、百位、千位、萬位、十萬位、百萬位、千萬位、億位等等等等。

比如,

數字:12345讀作1萬2千3百4十5(個),那這個數字包含了5個位,分別是萬位,值為1、千位,值為2、百位,值為3、十位,值為4、個位,值為5

這個數字也可以拆分成如下公式:

1 * 10000 + 2 * 1000 + 3 * 100 + 4 * 10 + 5 * 1 = 12345注釋:注意此處 * 代表乘法,後續的課程中皆為此意。

從上述公式,我們可以推導得出一個結論,什麼結論呢?

就是,

萬位本質上就是10000乘上萬位數值1,千位本質上就是1000乘上千位數值2,百位本質上就是100乘上百位數值3,十位本質上就是10乘上十位數值4,個位本質上就是1乘上個位數值5,將這幾個結果累加,即可得到12345。

然後,我們細心的同學可以發現一個現象:

10000可以記作4個10相乘,也就是10的4次方,1000可以記作3個10相乘,也就是10的3次方,100可以記作2個10相乘,也就是10的2次方,10則是10的1次方,而個位的1,則是10的0次方(注,除0外,任意數的0次方為1)

所以從中我們可以總結出一個規律,就是:

個位就是10的0次方,十位就是10的1次方,百位就是10的2次方,千位就是10的3次方,萬位就是10的4次方,更高位,亦可以此類推,於是上述12345也可記作:1 * 10 ^ 4 + 2 * 10 ^ 3 + 3 * 10 ^ 2 + 4 * 10 ^ 1 + 5 * 10 ^ 0 = 12345注釋:此處 ^ 代表乘方,10 ^ 2就是10的2次方,後續課程中皆是如此

在了解了位的概念後,我們再來看什麼是進位,所謂進位,意思就是說,每一位數字,凡是到了9,如果這位需要再加1,則將此位歸0,並將左邊的更高位加1,比如:

9+1 --- 個位為9,個位+1後,進十位並歸零個位 ---> 1019+1 --- 個位為9,個位+1後,進十位並歸零個位 ---> 20190+10 --- 十位為9,十位+1後,進百位並歸零十位 ---> 200

如果左邊的位也是9,則同樣處理,左邊位再歸0,然後更左邊的位再加一,比如:

99+1 ---個位為9,個位+1後,進十位並歸零個位然後進十位時,十位也為9,則再進百位並歸零十位---> 100

這種記數的方式,數學上就稱為10進位,而這種模式,則稱作10進位,也就是『10進位的制度』。

聰明的同學可以發現,在10進位中,每一位其實一共有0、1、2、3、4、5、6、7、8、9這十種狀態,所以,我們也可以將每一位有10種狀態的進位制度,稱為十進位。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

而在馮諾依曼的報告中,其提出了10進位雖然是我們人類的記數方式,但並不適合計算機去記數,最適合計算機的記數方式為2進位,所謂2進位,就是逢2進1位,每位有0和1兩種狀態。

為了直觀比較,我們下面例子分2列,用2進位來表示我們人類能看懂的10進位數:

10進位 2進位 0 0 1 1 2 10 3 11 4 100 5 101 6 110 7 111 8 1000 9 1001 10 1010

我相信看到這裡,我們同學應該就能明白了,在2進位種,每位都只有0與1兩個狀態,而馮諾依曼則提出了,這種進位才是最適合計算機使用的,為什麼呢?

因為計算機是一台電子設備,其用於傳輸的媒介其實就是電線,電線在傳輸數據時,只有通電與不通電這2種狀態,不通電時意為0,通電意為1。(事實上是高低電平,但那個涉及電學知識,不給你深入,就當是通電不通電吧)

而存儲時,比如磁碟,磁碟上某個點有磁性代表1,無磁性代表0。這樣我們就看到了,2進位對於計算機而言處理起來遠比10進位來得簡潔和高效,並能有效降低硬體成本,也正是基於這個原因,馮·諾依曼通過大量的數學證明最終提出了應該使用2進位做為計算機運算與存儲的根基這一跨時代的概念。


第二點、程序也是數據,應當與數據一同存儲在計算機的存儲器中

在看完第一點後,接著我們再來看第二點,馮諾依曼在對ENIAC的早期方案進行分析後發現其存在運算效率的低下的問題,原因在於每次運算需要操作人員反覆將每次收到的上一步運算結果再輸入計算器進行下一步運算,其操作流程大致如下,比如我要運算1加1等於幾:

1 + 1 = ?操作數1 操作類型+ 操作數1

操作人員在進行這個運算時,需要做如下操作:

  • 在控制面板上輸入操作類型:加
  • 在控制面板上輸入加類型所需的第一個操作數:1
  • 在控制面板上輸入加類型所需的第二個操作數:1
  • 由於加類型只需兩個操作數,完成指明加類型,以及兩個操作數輸入後,操作結果會自動列印到紙帶上,告訴操作人員結果

如果需要做多重運算的話,比如 1 加 100 減去 30 等於幾?

1 + 100 - 30 = ?

則需要這麼操作:

  • 操作類型:加
  • 操作數:1
  • 操作數:100
  • 輸出結果到紙帶,101
  • 操作類型:減
  • 操作數:輸入上次運算的結果101
  • 操作數:30
  • 輸出結果到紙帶,71

顯然這樣的操作非常繁瑣,而且極為重複,每次運算1+1,都得需要操作人員去手工輸上那麼一堆東西,顯然很弱智。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

為了解決這個問題,馮諾依曼就提出了一個稱為存儲器的概念,所謂存儲器就是能按順序存儲一些數據的設備,典型的有:

人(對沒存儲器的電腦來說,人肉就是存儲器)

紙張(人寫的在那個年代顯然計算機讀不了,但凡事有特例,後面會講)

磁帶(嗯,就是聽歌的那種,95後可能都沒見過)

磁碟(你電腦里的硬碟,不是固態的那種)

光碟(80年代的高科技產物)

快閃記憶體(固態硬碟,U 盤,內存條)

無論是什麼形式的存儲器,在存儲器中,都能以單元的形式存放數據,最簡單的單元就是條,比如我這人肉存儲器只能記住20條數字,多了就炸。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

有了存儲器,然後馮諾依曼提出,我們上述運算中的操作類型與操作數都應當以一條條數據的形式存放在存儲器中,具體怎麼做呢,其實很簡單,比如我們回到1+100-30的例子,我們能看到在這個例子中,有兩種類型的數據:

  • 一種是操作類型:加減乘除
  • 一種是操作數:1、100、30。

操作數好辦,直接以二進位數字的形式放到存儲器上就行,那操作類型怎麼辦?它不是數字啊!!!

這問題其實簡單的很,既然操作類型不是數字,那就給他個數字替代表示下唄,多簡單的事,瞧你們這折騰的。

所以,我們就分別給加、減、乘、除,這四種操作類型分配一個數字,

然後,給從對前次運算結果進行加、減、乘、除各分配一個數字,比如:

加用0表示,減用2表示,乘用4表示,除用6表示,

從上次結果加用1表示,從上次結果減用3表示,從上次結果乘用5表示,從上次結果除用7表示

然後,再加入一個新操作,叫做輸出結果,用8表示

最後,數字還是用數字表示,於是上述的操作以這種數據形式就變成了:

操作類型:+ ----> 1操作數:1 ----> 1操作數:100 ----> 100操作類型:從上次結果減 ----> 3操作數:30 ----> 30輸出結果到紙帶 ----> 8

然後,將1、1、100、3、30、8這串數字存放到存儲器上,有計算機去讀取並執行,運行邏輯如下:

讀取第一個數據,得到1,由於是第一個數據,所以肯定是一個操作類型,於是得知為加由於加指令為雙操作數指令,所以接著讀取後2個數據1與100開始進行運算,得到結果101,第一次運算執行完畢,以操作類型形式讀取下一條數據讀到操作類型3,於是得知為從上次結果減由於從上次結果減為單操作數指令,所以接著讀取後1個數據30開始進行運算,得到結果71,第二次運算執行完畢,以操作類型形式讀取下一條數據讀到操作類型8,於是得知為輸出結果操作,將71輸出到紙帶

最後,通過這樣的方式,馮諾依曼就實現了對於計算機操作的數字化,而上面的這一串數字就是我們現代計算機程序的起源,其中的操作類型,我們稱為計算機指令,而參與操作的數字,則稱為操作數。

存放在存儲器上,能由計算機直接讀取運行的1、1、100、3、30、8這串數字,我們則稱為機器碼,由於機器碼雖然計算機能讀但人卻難以閱讀,所以後面有人想出了用字母替代其中的指令碼,以方便人肉閱讀,將其變為:

注釋:以ADD替代指令1,以MIN替代指令3,以OUT替代指令8,於是得到:ADD 1, 100MIN 30OUT

這樣的程序就稱為彙編程序(當然我這彙編指令是瞎掰的,不過真的也沒複雜到哪去)。


第三、計算機應當由五個部分組成,分別為:運算器、控制器、存儲器、輸入設備、輸出設備

在提出了存儲器與程序這兩個概念後,為了實現計算機能從存儲器讀取並執行程序,馮諾依曼將計算機分為了五個部分,運算器、控制器、存儲器、輸入設備與輸出設備,其中:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

運算器

就是用於對單條指令進行運算和對臨時數據進行暫存的電路模塊(現在的運算器有更多的模塊,但你不用管),比如我們上面的計算機中包含了加,減,乘,除四種運算,以及暫存運算結果,那麼運算器中就將包含:

加運算電路,減運算電路,乘運算電路,除運算電路,以及一個能存放上述電路輸出結果的東東,稱為寄存器。

(注釋:事實上我們現代的計算機只有一個加運算電路,稱為累加器,減、乘、除都是通過累加器實現的,不過這個涉及門電路知識,和我們課程無關,我就不深入了)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

控制器

控制器的主要工作是負責控制計算機的方方面面,比如按一定的頻率從存儲器上讀取指令,然後根據指令不同,進行不同的操作,比如:

讀到加指令,就接著讀兩個操作數,然後將兩個操作數送入運算器的加運算電路;

然後再讀取下一條指令,發現是從結果減,然後就再讀一個操作數,然後將運算器中存放結果的寄存器中的數據與這個操作數再送入減運算電路;

然後接著從存儲器讀下一條指令,發現是輸出,則將運算器中結果寄存器內的數據輸出到輸出設備。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

存儲器

我們上面已經做過解釋,具體不再複述,我們需要知道的是,目前存儲器一共有兩種,內存與硬碟,內存是快速但不持久的存儲器,硬碟則是低速但持久的存儲器。運算器與控制器只會從內存中讀取數據與指令而不會直接訪問硬碟,而內存則會根據指令從硬碟中載入一整塊數據。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

輸入設備

輸入設備就是指人向計算機輸入指令和數據的設備,常見的設備有:

  • 控制面板(現在還有,就是你機箱上的開關機鍵)
  • 磁帶機(現在基本已經沒了,只有極少數機構在用)
  • 紙帶機(打孔紙帶機,上古程序員每天面對的東西)
  • 鍵盤(克羅索斯上就有,不奇怪)
  • 滑鼠(圖形化時代的一大創新)

等等等等,更多我就不列了。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

輸出設備

輸出設備就是指計算機向人輸出數據的設備,常見的設備有:

印表機

紙帶機

磁帶機

顯示器

等等等等,我們可以注意到很多輸入設備同時也是輸出設備。


最後,需要同學們注意的是,在上述五個設備中,運算器與控制器合在一起,就是我們如今所熟知的CPU即中央處理器。

三、結語

在本章我們通過一段關於計算機從無到有的歷史,學習了如下幾個知識:

1、什麼是計算機,有什麼用?

2、什麼是位,什麼是進位,什麼是十進位與二進位?

3、什麼是程序?程序是如何怎麼產生的?程序有什麼作用?

4、現代計算機的五個組成部分,以及五個部分各有什麼用?

希望大家能從中有所收穫,下一章,我們將引入操作系統以及關於編程語言的相關知識

四、作業

1、通過網路搜索,學習正整數的二進位與十進位數相互轉換

2、嘗試自行理解二進位中負數與小數(浮點數)的表現形式,不理解也沒關係,後面會提到

3、看完了,給本文個贊

五、問答

暫無問題,等待添加

六、其他章節

零基礎編程入門(01)——前言

零基礎編程入門(03)——操作系統與語言

零基礎編程入門(04)——Java與環境搭建


推薦閱讀:

理論上最好的編程語言: 並行因果篇
Confluence 6 用戶宏示例 - Color and Size
中文編程目前面臨的難題是什麼,你有哪些建議?
Filedescriptor out of range in select
辦公自動化與python編程探索(二)

TAG:編程 | 編程語言 | 自學 |