為什麼現代程式語言通常對 null 深惡痛絕,卻鮮有特殊對待 0 的呢?

時間 2021-05-09 13:05:16

1樓:菜瓜程式猿

Null代表的是空指標,如何設計到記憶體相關的呼叫操作,很有可能程式會執行到Null變數時出錯。而0值作為常量,可以避免記憶體中空指標的存在,避免產生一些難以發現的bug

2樓:

這是因為這些語言的型別設計遺留問題。。。。

正常觀點看來兩個物件的比較應該先比較型別,比如

""==0is

False

# "" is a StringObject, 0 is an IntegerObject

{}==0is

False

==0isFalse

None==0

isFalse

False==0

isFalse

這就是第乙個麻煩,這個空值 None 它的型別是什麼呢。其實也不是那麼困難,比如就稱為 NoneObject。上面這個列表中有些取為真是無害的,還有一些則不。

然後對於數值型別的比較,有精度的約束限制:0==

0.00

isFalse

0.00==0

/100

isFalse

比如 0 是整型,乙個精確值,而 0.00 是乙個實數,帶有精度 3 , 0/100 是乙個精確表示式,不是原子物件,但也確實是乙個實數。

以上就是要區分整數,有理數,實數這三個數值子型別。同樣,正常來講這些例子是可以放鬆的,因為存在乙個機器精度限制,存在這種情形:0==

1*(10

**-1000)is

True

實數的比較應該在精度內進行:

0.00==-

0.00

isTrue

雖然我們知道 0.00 不是精確的,但是確實是可比較的所有部分。

實際上,0 再有害,也僅僅會出現在除法運算上,而且可以非常 Mathematical 的解決。比如定義:1/

0==Infinity

但是這個無窮不是無窮大,實際上它應該理解為不定方向的無窮大,可能是正無窮或者負無窮。只能說:1/

abs(0)

==inf

inf 就是常見意義上的無窮大。這樣就避免兩個 0 的問題,取代的是兩個無窮的問題(但這個稍微好些,在數軸上畢竟是在兩端的)。無窮代數到不是很困難。

以及定義:

eval(0

/0)==

Indetermined

也就是不定表示式,而不是通常的非數 NaN。NaN 當然是乙個壞的記號,因為所有符號都不是數,確切的 Infinity 和 inf 也都不是數。

實現了以上這些的符號系統就是可以避免題目中說的問題。

3樓:

0和null,都表示無,但他們的地位完全不一樣。

細想起來,題主這問題其實很有意思。

它們為什麼不一樣?

我想是因為他們在各自體系中所起的作用不同,抽象程度不同。

0表示無,它抽象程度非常高。古時候,0這個概念是被數學家(其實多數是教會的人)排斥的,認為這個概念根本不需要。但發展到現在,它在數學體系中所起的作用極其巨大,沒有它就沒有現代數學。

沒有0,就無法進行各種數學表達。可以說,它與其它數字融為了一體,成了整體邏輯不可分割的基礎部分,空集合可以對映到0,有東西但我們認為是空的集合也可以對映到0(零測度集)。而正負無限,和0這個概念差不多,但它們的抽象程度更高,高到無法在有限的物理表示中以一種與0對等的表示存在(只能是抽象的符號概念),別說有正負無限了,就算是高精度的浮點都很難表示,無理數更是無法表示,只能近似(想想1/3與圓周率在計算機表示時的區別)。

所以,這就出現了你說的正負無限的情形——作為物理有限的計算機,如何能以一種與0對等的方式表示無限呢?不可能。所以,出現操蛋的結果那簡直是一定的。

null也表示無,但它的抽象程度不如0,在它所處的體系中其地位遠遠比不上0在數學中的地位。它的含義是「乙個不存在的資料」,近似於物理概念了,只有用指標這樣的概念時,它才是有意義的,一旦指標有所指,這個概念就沒有用了。至少在目前來說,我們沒有必要去定義「乙個有所指的變數與乙個無所指的變數進行某種運算其結果有何性質」,但數學上這樣的定義卻是邏輯起點之一,如果你學過抽象代數、實分析一類就知道我在說什麼。

正是因為null概念的邊緣化,使得它可以被單獨提出來,甚至丟掉——沒有指標的語言中你甚至看不到null,因為這類語言抽象程度更高,它無須定義乙個比它抽象程度更低的概念也可以正常執行。但無論什麼語言,它的抽象程度不可能比數學更高,所以它丟不掉0。

把0從數字型別移除,形成新的型別?這相當於你把數學重新定義了一遍,然後你會發現你碰到無數的概念不一致導致的操蛋事,你自己也說了,正負無限、NaN這種操蛋事你想在0上再來一發?沒那個必要,——乙個抽象程度更低的事物,為何要去重新定義乙個抽象程度更高的事物?

造成這樣種要繞著彎解釋的結果,是因為我們人腦抽象程度太高了,而計算機作為只能用0和1對映我們思維以及現實世界(更多的是我們的思維)的工具,表達能力還不夠。

4樓:David Gao

個人感覺NULL,本身並非錯誤,而是使用不當產生的錯誤。

畢竟真是世界不是二值邏輯世界,其實還是存在三值邏輯的,真,假以及未確定。即便是在集合中還存在空集合。

所以作為乙個很工程的開發者,NULL和0本身就是兩個問題,並且NULL被特殊對待本身就是因為用錯的時候太多了。

利益相關:Fullstack CRUD Boy

5樓:pengyu zhu

我是業餘碼農

會用到python,access,Excel一次用access匯出到Excel再用python去post ,request

結果莫名程式不報錯,不終止,也不動,卡住了。

剛開始以為是本地檔案和區域網檔案的問題

後來發現卡住的地方Excel裡是個空單元格想起來access裡有null這個玩意

才知道伺服器為啥啊不響應返回資料也不報錯

這種倒霉問題對於小白來說控制變數都很難

業餘碼農傷不起啊

6樓:拼音

這樣做沒有必要。負數開平方在實數範圍內也沒有意義,但可以用虛數處理。也可以存在包括「除以0的結果」的運算體系。

而擴充套件之後的運算體系還會有它自己的特殊情況。

總之,0在語言層面上不是特殊的,NaN也不是。去掉null的必然結果,就是每個運算體系中(不僅限於數學體系)都會有自己的類似NaN的元素來表示無法處理的情況,也就是空物件模式。因為NaN這類物件是各自運算體系中的合法元素,用型別去特殊對待這些元素也就沒有意義了。

7樓:余弦

因為1、2、3、4、5……是數字,0也是數字。

而null講道理不算是物件,卻經常和物件型別的變數混在一起使用。

之所以使用null,不是基於型別系統的考慮,而是基於底層實現。由於物件型別的變數實質上是個引用,也就是記憶體位址,所以就沿用C的用法把位址0(null)拿來當做空值、預設值。

8樓:pansz

只是題主不知道而已。

C++ 的 0 ,不就是特殊型別麼。

C++ 規定 0 沒有型別,所有型別接收 0 值都視為假,非 0 值視為真。這樣在模版程式設計的時候可以使用 0 值作為某種任意型別的通用文字量。

C 語言的空指標是 NULL,而 C++ 的作者規定 C++ 語言的空指標是 0,可能很多人都不知道這個區別吧!畢竟為了相容 C ,你在 C++ 裡面用 NULL 也是能編譯通過的。

9樓:三才天地人

既然是程式語言,那麼就要從計算機角度考慮,而不是人類語言角度考慮。變數型別基本上有兩種型別,一種是值型別,一種是引用型別,對應的是記憶體的處理方式不同。null在引用型別中出現,代表空,是未給變數分配記憶體空間,0在值型別出現,代表值為0。

我不覺得有什麼深惡痛絕的,只是程式設計師本身的問題,從語言設計上看,很合理。換句話說應該是程式設計師對null出現的問題深惡痛絕,因為這個設計是面向計算機的,而不是面向人類的。

10樓:

零是「業務」領域(數值計算)本身的問題,null是程式語言設計的問題。

「業務」本身的問題你想怎麼迴避?那要去改「業務規則」了。

11樓:石志尹

只要不把null納入數學範疇,null就非常好處理。但你若果把0這種天然屬於數學範疇的挑出來,那麼一大堆命題需要你重新定義(其實把除法範疇動一下就行)。

一般相容做法是把null態射到單位元,作等價的行為。類似null->0,null->""等。

而npe出現是沒分清範疇導致的,null. field這樣的行為(或者說這樣語法設計)實際只存在非null物件範疇。

有人提出先天把null納入範疇,若果要滿足null,則要態射到新範疇,舉例(.) null _ = null。然而這種實際上並不好固定,如getOrElse更多是使用單位元,所以含null範疇交給使用者定義最好。

12樓:羅宸

想做來著, 但是不好做, 畢竟對於計算機科學家來說, 0 和 1 和 2 沒有什麼區別, 所以乙個有審美的計算機科學家是不會特殊對待0的, 而是要設計一種型別系統, 可以允許你只包含乙個型別中的任意子集, 並將它當做乙個新的型別, 例如 . 參考 Liquid Haskell: https:

//ucsd-progsys.github.io/liquidhaskell-blog/

.所以在這樣的型別系統下面, 整數除法的型別將不再是粗糙的Int->

Int->

Int而是精確的

Int->

->Int(題外話, 即便做出來會用的人也少, 畢竟大家都偏愛JS, Go這種簡單無腦的...

13樓:Belleve

因為寫乙個能區分 0 和非 0 的 typing system 很難

這樣說吧,對於 null 相關的邏輯推理只是判斷「是否是 null」,也因此比較容易在現有的 Typing system 裡面去實現。而對於數值,除了是否為 0 外,還有更多的邏輯命題需要處理(如大小關係,牽涉到陣列越界檢查),這也會使得 Typing 變得急劇複雜起來。

14樓:池龍

因為NULL不好用。

NULL表達的「沒有」的意思可以在邏輯上用0代替:比如某個以數字來索引的序列,我們可以設計為第乙個專案是的索引是1,給相應的變數傳入0則代表沒有對應專案。

NULL除了表達「沒有」之外沒有其它作用,而引入NULL則導致程式必須做出額外的處理:先判斷是不是NULL才能使用其參與運算。

所以沒必要增加額外的定義。

古代語言比現代語言複雜嗎,為什麼?

黃益暉 偽命題 語言的複雜性是靠設計能力決定的,你的問題是達爾文範疇。也就是說,又開始你怎麼設計就是什麼樣子。設計語言的基本工作是 指物指事,抽象具象,時序。對這些工作怎麼設計關係複雜性。古人語言從無到有,然後就有許多語言,有設計好的或設計不好的,不好的沒人用,好的多人用。然後就是現在留下來的相對好...

為什麼總有程式語言之爭?

Mimosa 語言之爭本身是很正常的事,但是問題在於很多參與爭論的人不能直面各種問題,有些人對程式語言的認同程度達到信仰的地步,容不得別人提問題 提缺點。相信很多人提問題,並不是要全面否定語言本身 而是就事論事,比較全面認識程式語言,揚長補短,方便更好的使用,當然,有時候也有恨鐵不成鋼的成分。很多程...

為什麼我們需要程式語言圖靈完備?

Qian Chen 額,確實不需要啊。記得資料庫的第一課就說了SQL不是圖靈完備的啊。只不過要達到圖靈完備太容易了,比如有無限個格仔的算盤就是圖靈完全的。 hhhhhhhhh 我覺得是不需要程式語言是圖靈完備的。就我現在的了解來說,現實生活中的問題需要的程式要不然是停機的,要不然是無限重複某停機程式...