辛巴學院-Unity-劍英陪你零基礎學c#系列(三)計算與型別

瘋光無線發表於2015-09-24

辛巴學院:正大光明的不務正業。

中秋節快樂,每逢佳節倍思親,尤其是那素未謀面的老婆,對吧,屌絲們。

 

今天我們來探索一下C#裡面奇怪的計算,奇怪的型別。

奇怪的計算

當我剛剛接觸計算機程式設計的時候,一切在我看來都是奇怪的。

i++
i=i+1
i==i+1

這都是些什麼鬼?

機器語言是圖靈機模式的,那玩意不是人類語言,是關於操作暫存器的。

附:圖靈機視訊地址測試版:

http://v.youku.com/v_show/id_XMTM0MDg0NjUxMg==.html?from=y1.7-1.2

高階語言是模擬人類語言的,可是上面那些鬼用人類語言完全看不懂呢。

沒人能看懂,以自然語言的角度來說做了很多的省略。

此處的等號和數學的等號全無關係,而是替代自然語言的一個簡化符號

不僅僅是等號,程式語言中出現的所有符號,他其實都是想說一句話,不一定和你數學中熟悉的那個符號表達相同含義

i++ (他想表示一句話,讓i這個變數的值增加1)
i=i+1(他想表示一句話,讓i這個變數的值改變,改變為i+1)(這裡初學會很糾結我們等下來解釋)
i==i+1(他想表示一句話,判斷i 是否和 i+1 相等)

你要時刻提醒自己,這不是數學,這不是數學,這不是數學

高階語言中,所有的語句,都想表示一句話

i=i+1,表示的這句話是不是有點奇特呢?讓i這個變數的值改變,改變為i+1。他們的時空觀到底是個what?放心,這不是黑客帝國。

我們的時空觀還在牛頓經典物理水平。(初中物理水平)

前面講過:"程式碼是棵樹,執行有順序"。這就是個順序的問題。他相當於先拿一個臨時變數j=i+1,這就沒有時空困擾了,然後再讓i=j。

並不是時空觀上有什麼奇怪,而是這句話隱含了一箇中間出現臨時變數的機制。

初學者可能會在這裡繞圈圈繞一會兒,沒關係,多繞一下。

=這個符號,是"讓誰的值改變為xxx"的代表符號,而不是數學中的等號

 

3

2

1

繞清楚了麼?

對加減乘除與數值型別來說,倒是和數學意義一致,不用特別說明

然後出現的奇怪計算是這個:i==i+1

這個叫做邏輯運算,完整的寫法應該如下:bool b =i==i+1; 完整的想要表示的自然語言是:讓b的值改變為是或否, i是否與i+1相等。

所有的邏輯運算得到的結果只有是或否,bool型 專門用來表示這個 是 或 否。Int型專門表示整數。

邏輯型別最常用的場合是配合if做選擇邏輯,If(i>2)隱藏了一些細節,完整的寫法是

bool b = i>2;
if(b)
{

}

c#將所有的需要邏輯表示式的場合,統一為使用bool型別的引數。

也就是說c#中所有使用邏輯運算的場合,均可如上面那樣展開寫一個明確的bool變數。

當你寫到這些問題完全不會繞住,完全不會弄錯,你可以完全忽視這一切。
現在,假如你寫程式碼寫到邏輯運算繞住了,那你可以把他展開寫,更容易看懂。

只要你始終牢記所有的運算子都是想說一句話,那就不會陷入這個陷阱中。

其實不止是運算子,高階語言我們說過,整個就是顆樹,每一句都是想說一句話,一句人類的話,只是太多的簡化,說的不那麼好。

C#中還有一類特殊的計算,位運算,這個是2進位制的範疇,在邏輯清晰要求剩餘記憶體要求的現下,位運算出鏡率已經接近於零,所以我們不提這個部分。

奇怪的型別

在講到型別,一般來說,言必及封裝繼承多型,言必及物件導向。

我們還沒到那裡,收回來,不要去考慮物件導向的問題,物件導向講的是:貓繼承自動物,狗繼承自動物,波斯貓繼承自貓,短毛貓繼承自貓。
深不以為然,而且現下,我們並不是要去考慮物件導向的問題。

為什麼我們在c#裡 不能直接寫 i=1,而要寫int i=1;為什麼所有新的變數前面都有個型別 int float string bool,blabla,各種各樣的東西,為什麼?

不寫可不可以,當然可以,basic就是這樣的語言,不用區分變數型別。這些事情交給runtime去處理。

這是程式圈裡面分為兩派一直在口水的一個問題。而靜態型別語言,初始設計只是為了貼近機器語言,型別明確,就更容易翻譯為機器語言,因為機器語言嚴格區分型別
Int 只能和 int計算 float 只能和float計算,機器語言也只有整數和 有小數點的數這兩種型別。
後來,靜態型別定義 和 動態型別識別 已經成為了兩種設計原則與方法論,已經脫離了這個好處,和機器語言一點關係都沒有啦。

目前靜態型別定義語言主要的好處是語義明確,很多型別相關的錯誤,在編譯階段就會暴露出來,根本不需要到程式執行起來出錯來看。

但動態型別識別語言卻強調他們的簡潔,寫程式碼少,語言更接近人類語言,畢竟人類說話時是不帶著"型別"的

Int i=2+3;人類不會說 讓(整數)i的值改變為( 整數)2 加( 整數)3.

但是現在的機器語言會,大家都知道cpu跑分的時候會分別跑整數運算能力和浮點運算能力。說的就是機器運算不同型別的能力。

總結一下,靜態型別定義語言,由編譯器的偷懶開始,現在是為了更明確,為了編譯器更早的幫你發現問題。
其代價,就是你說話的時候,得多說出來型別。

你沒得選擇,但c#給了你一個變通的方式偷懶。

var i=2+3; 讓變數i的值等於整數2+整數3,幫我確定i的型別。

var 在c#裡用來告訴編譯器,幫我確定i的型別,他只能用於編譯器可以根據右邊的表示式幫你推斷出型別的情況。

這種情況十之八九,但有時候也會有些困擾,不建議你在學習初期寫一大堆的var,把型別認知的事情都推給編譯器。

中秋節到了,少說一點,下次聊函式和封裝。

哈庫拉瑪塔塔。

相關文章