我們的生活離不開設計,或者說,幾乎所有的東西都是被設計出來的。今天我就寫點東西談一談設計和程序設計
一、石板路,下圖的設計恐怕大家都見過,這就是傳說中的“一步娘炮,兩步扯蛋”。

你說它好看嗎?確實好看,草叢中的小路,總是讓人覺得富有詩意。但只有走在上面才知道它設計的有多糟糕,更坑爹的還在于,有些石板路不是為了讓你由A到B,它偏偏讓去一個你不想去的地方,然后你又原路返回。這也是為什么很多有石板路的草坪總是被人踩出另一條路來。所以說,好看的程序并不一定就使用。
這一點就像i++與i=i+1,我們姑且不討論二者之間的誰效率更高,也不說i++和++i的區別。我們討論,到底是寫i++還是i=i+1呢?i++在書寫效率上是快一些,也美觀些,這是絕對的。比如下面這兩段代碼


我們更傾向于寫前者,那么后者就一無是處嗎?
當然不是,程序在調試的過程中,需要更改變量的增量(減量),有時候需要寫成i=i+2或i=i+3這種i=i+N的格式,因為需要這些測試。那么如果還是之前的i++結構,就不得不刪除從寫,所以說,實際調試中,i=i+1的寫法更直觀,更易于調試。
當然,如果你是出于習慣或者你的程序不需要這些調試,是沒必要糾結這些的。這里只研究那種寫法更適合調試,不討論其他。
二、左撇子和右撇子問題
下圖恐怕大家都遇到過,盡管現在少見了,因為網線插口都被設計到了左側,與之類似的還有手機側鍵,現在的手機側鍵有些在左側,有些在右側。這里要說一下羅永浩錘子手機的雙側鍵。
首先我們先來看看網線插口設計,幾年前我見過一些設計在右側的筆記本。這無疑讓右撇子很難受,那根網線會經常影響你的動作或者導致網線掉落。但現在少見了,大多數網線接口都設計在了左側。好像是方便了,那么實際呢,對于左撇子呢?現在很多接口如VGA、HDMI、網線接口都被設計到了左側,這是不利于左撇子的設計。當然作為設計者本身會考慮到,左撇子的用戶較少,只能為了滿足大多數人。是的,這沒錯,不可能專門為左撇子也設計一款筆記本。更何況,絕大多數左撇子都會用右手,特別是在中國,受家庭的管教。我們左撇子幾乎都用右手寫字,用右手使用鼠標。我作為左撇子(操作上更多喜歡左手),就覺得很多設計非常不近人情,但也只能和其他左撇子一樣,盡量去適應本來就是給右撇子的設計。
那么再看看手機,手機側鍵有些在左側(蘋果),有些在右側(諾基亞)。羅永浩的錘子手機是兩側都有的,聲稱是為了滿足左撇子和有撇子的操作問題。我到很想知道,羅永浩先生本人是左撇子還是右撇子。如果是右撇子,他可能嘗試過用左手操作左側側鍵的設計,這的確不方便(或者說不習慣),所以萌生雙側鍵的設計。但如果他本人就是左撇子,那么他應該會發現,即便是側鍵在左側,左撇子也可以像右撇子一樣熟練的操作左側側鍵。正如前文所說,左撇子們在生活中早已習慣了那些給右撇子設計的東西。雖然我沒玩過錘子手機,但我的確使用過左側側鍵和右側側鍵的手機,對于一個左撇子來說,我不覺得有左側側鍵和右側側鍵有多么不習慣。至于右撇子怎么想的,我不清楚,但我很多朋友和我一樣用的是諾基亞lumia系列(側鍵在右側),他們都是右撇子,我看用起來也很順暢,后來換為蘋果后(側鍵在左側),也沒抱怨過不方便。
所以個人認為,錘子手機的雙側按鍵有些雞肋,此觀點僅代表左撇子的個人觀點,不喜勿噴。
在程序設計中,也有這種類似的雞肋,我稱之為“不需要糾結的人為錯誤”。比如if(i==1)和if(1==i)。我是習慣性的寫if(i==1),有次我的朋友看到后,對此嗤之以鼻(他的編程水平確實比我高),我問他為何不認同這種寫法。他說,你寫成這樣,如果少打了一個“=”號,那邊就變成了if(i=1),成了賦值語句,判斷的條件就會永遠為“真”,容易導致出錯。但如果寫成if(1==i),即便是你少敲了一個“=”號,那么編譯器在編譯的時候會給你提示一個“leftside of asn-op not an lvalue”的Error(錯誤)。開始我聽了覺得很有道理,恨不得把自己寫過的所有程序都改為if(1==i)格式。后來,隨著閱歷的增長,覺得這種寫法完全是雞肋,很多程序員看了新手的程序(比如我那朋友就是看我的程序才引發出這個問題的)不是先考慮怎么解決問題,而是先挑你的毛病,這里不對,那里不對。如果看到你寫的是if(i==1)而不是if(1==i)他會先批評你。
那么這種批評對嗎?首先要確定的是,不管哪種寫法,少敲一個=號的概率是完全一樣的。所以說,沒有在本質上解決出現這種問題的方法。那么在編譯后呢?
在keil4版本下,如果在寫if(i==1)的時候真的少敲了一個“=”號,那么程序執行的結果肯定是會出錯的,這個沒疑問,那么這個錯誤就真的那么難以發覺嗎?真實的情況是,當你把if(i==1)寫成if(i=1)時,執行build后,keil會給出一個“constant in condition expression”的Warning(警告),雙擊這個Warning,會給自動指示到這個if(i=1)這個有問題的地方。

所以說,少打一個=號的情況是容易產生,但還不至于說不易于被發現(少敲一個符號的概率是一樣的)。只能說,Error和Warning比起來,前者更讓程序員關注,也更容易找到錯誤。我不否認連我自己都懶得管Warning這種警告,但隨著閱歷的增加和責任心的成長,不管是Error還是Warning,我都會重視。一個合格的程序員,他不會忽略掉這種“constant in condition expression”的警告信息,因為它不是“uncalled segment….”
再后來,我又知道,這是編譯器本身的問題,就是所謂的“人為錯誤”。因為一個合理的編譯器應該不允許你寫出if(i=1)這種格式(雖然它給出了警告),但條件語句里面本來就應該是表達式而不是賦值語句,它給出一個Error(錯誤)到合理些。這是編譯器本身的設計失誤,而if(1==i)這種寫法又不能讓你完全改掉少打一個=號的問題,何必去糾結這些“人為錯誤”呢,也因此我把這種情況稱之為“不需要糾結的人為錯誤”。我沒必要為前人的錯誤買單。
說到這,在單片機領域,程序員更多都是判斷“真”或“假”。如果真的想避免輸錯符號帶來的麻煩,寫成if(i)這種格式好很多吧!我不覺得if(1==i)比if(i)多高明,因為它本身就是解決一個本不應該有的錯誤。
三、各種插座


對于這些設計,估計大家和我一樣,忍受很久了。但這不能把錯誤全部歸咎于插座設計師上,有時候很多插頭的設計本身就不合理。比如現在市面上各種外觀的U盤,它本身就不方便插入,除了好看,還是好看。我欣賞好看的東西,但不能忽略實用,何況,那些設計的樸實無華的優盤,本身也具備美感。
至于為何會出現這種坑爹設計,我不知道。我們可以容忍一些設計的不足,但一個設計總不能讓大多數人都覺得X蛋吧?!也許作為設計者本身,他是想做好事—一個插板可以插兩種插頭,結果事與愿違。
在編程中,就有人喜歡搞這種設計(不針對初學者),因為程序員本身很難具備包容心態,就好比一個是設計插板的,一個是設計插頭的。假如這個情況發生在一個插頭設計師身上,他肯定會說插板設計的不合理,可發生在插板設計師身上呢?他肯定會罵那個坑爹的插頭設計者。這有點曹丕的“文人相輕”的意思。這里我好奇一下,同一家公司出的插座(插板)和插頭,會不會出現不能插入的情況呢?因為我從沒這樣配置過插線板和插頭。希望有知道的朋友告訴我一下。
這里我要說的是程序員的狹隘性(包括我自己也有),程序員本身很難面面俱到,TA的程序不見得就很好,但卻很難坐下來去研究其他程序員的想法。我之前的兩個例子恐怕就會引起一些程序員的誤解。他們有自己的一套理論來解釋i++和i=i+i(有效率上的,有美觀上的),只有少部分人清楚它們只是寫法的不同,甚至有人看到這個,就會想到++i(盡管我沒討論++i)。總之,當你的代碼(程序設計、觀點)與別人相抵觸時,你最先批判的是別人,而不是先認清本質,我不覺得我的觀點全對,但和我討論的,有多少是研究問題本身呢?程序語言不是達爾文的進化論,不能說“存在即有道理”,它是人設計的,編譯器也是人設計的,這就難免出現設計錯誤,不是所有存在的東西都有道理,王垠甚至認為,自增自減(i++,i--)本身就是錯誤的設計。
同樣的,作為插座和插板,他們都是人設計的,也一樣會存在問題。如果說插板設計師的這種設計錯誤只是讓你少用一個插頭,那么程序員的這種類似失誤就是一種災難。
本文涉及到的程序僅限于keil4下的C51編譯環境。本文內容純屬個人觀點,難免有不足之處,希望高手予以指出,本人將不勝感激!