程式設計思維訓練(一)

2021-06-10 07:57:03 字數 1666 閱讀 1677

最近以提問的形式發了幾條關於程式設計思維的微博,有的獲得了粉絲的響應,有些卻無人問津。今天突然想到可以將我對這些問題的思考整理成一篇博文,以便與大家分享。另外,我計畫以「程式設計思維訓練」為名寫一些系列文章,希望通過這類文章與讀者分享我在程式設計活動中的一些思考。

問:有一對記憶體管理函式memalloc和memfree,使用形式分別是:分配時為「void *p = memalloc (6)",釋放時為「memfree (&p)」。你能看出什麼問題嗎?有什麼建議?

答:一談到記憶體分配與釋放函式,我們很自然地會想到來自c庫的malloc和free函式。然而,memfree與free在入參型別的定義上卻存在很大的差別,前者需要傳入的是指標的指標,而後者所需的卻是指標。由於memfree函式的入參形式與free存在區別,這就容易造成使用者容易因為忽視這種區別而在初次使用時犯錯。

儘管memfree的函式引數定義成指標的指標存在一定的好處 — 可以在memfree函式中對所釋放記憶體的指標變數置null,但由於它違背了malloc/free的使用常識,因而不可取。我的建議是,定義api名稱時,應盡可能符合「常識」。

問:malloc與free是c庫中用於從堆中分配和釋放記憶體的函式。這兩個函式在命名上有什麼問題?如果給你重新命名的機會,你會如何做?

答:很顯然,malloc函式是「memory allocate」的簡寫,那相應的記憶體釋放函式應是「memory free」,如果採用一致的命名,free函式的名稱應是mfree。因此,c庫中的malloc/free函式存在命名一致性問題。

問:在linux作業系統中,所有的外設都位於/dev目錄之下以檔案的形式進行管理的,能否將socket也納入到/dev目錄之下呢?如果是你,你會如何做?為什麼要這樣做?

答:將外設放入/dev目錄,使得在linux中操作外設(或裝置)與操作檔案是相似的。這種設計一方面減少了api的數量,另一方面,使得程式設計師很容易掌握裝置的操控程式設計。然而,linux中的socket卻採用了完全不同的設計實現。

在linux中如要開啟乙個socket,則必須呼叫socket函式,且在函式中指定是流型別(stream),還是資料報型別(datagram),以及所需開啟的埠號。然而,從tcp/ip協議的角度來看,我們知道「流」對應的是tcp協議,而「資料報」對應的是udp協議。這種對映關係儘管簡單(但並不易懂),但不可避免的是,它仍然引入了「對映」這一行為(複雜化了)。

如果將socket也按目錄的方式進行管理,那麼開啟乙個socket也可以用open函式,且目錄結構可以考慮採用協議名進行組織。比如,採用「open (「/net/ipv4/tcp/3344」, o_creat)」的形式開啟乙個埠號為3344的tcp socket,而採用「open (「/net/ipv4/udp/3344」, o_creat)」的形式開啟乙個udp的socket。很顯然,這種方式並不需要引入「流」與「資料報」的概念,且簡少了api的數量。總體說來,基於目錄結構的socket設計將使得linux在概念上更加一致。

實際上,目前的linux中socket也是一種型別的fd(file descriptor),儘管造成目前的現狀有很多歷史原因,但它仍可以向前邁進一步。

本文出自李雲的部落格,請務必保留此出處:

程式設計邏輯思維訓練

問題區 1.你讓工人為你工作7天,給工人的回報是一根金條。金條平分成相連的7段,你必須在每天結束時給他們一段金條,如果只許你兩次把金條弄斷,你如何給你的工人付費?2.請把一盒蛋糕切成8份,分給8個人,但蛋糕盒裡還必須留有乙份。3.小明一家過一座橋,過橋時是黑夜,所以必須有燈。現在小明過橋要1秒,小明...

作為訓練思維方式的程式設計

原文 programming as a way of thinking現代程式語言的強大之處在於其具有強大的表現力 可讀性 簡潔性 精確性和可執行性的能力。艾倫.唐尼 於2017年4月26 從程式語言產生到現在,程式設計方式有了翻天覆地的改變,在fortran和c等第一代程式語言中,程式設計師的負擔...

Python 計算思維訓練 公式程式設計

本程式計算小球上拋在不同時間點的高度 v0 25 小球上拋的初速度 g 9.8 地球重力加速度 t int input 請在此新增實現 begin h 25 t 0.5 g t 2 print h end 本程式進行華氏溫度和攝氏溫度之間的轉換 請通過換算公式來計算相應的攝氏溫度值,需給出pytho...