摘錄:C 與 C++ 的真正區別在哪裏?

https://www.zhihu.com/question/28834538/answer/1654211948

C是中餐廚師的菜刀,做啥菜就那一把刀,切菜切肉切魚,都是這一把刀,刀工好的師傅,豆腐都能切成一朵花。無論你提什麼概念,都能用指針給你做出來,如果不行,那就用指向函數的指針,指針的指針,指向函數指針的指針。。。。

C++就是西餐廚師的刀,有一大堆不同款式的刀,切不同的東西得用不同的刀,每種刀還有不同的手法,顯得非常專業,高大上。

中廚刀,簡單,但深入高階難,難在複雜使用技巧,做啥都是這一把刀,要切出花來,刀工需要練的,一般人練不好。

西廚刀,複雜,但是使用難度相對低,需要掌握一堆刀的功能限制。但刀太多,功能干涉太多,沒準啥時候沒喫透就踩坑了。真正喫透也很難。

西餐廚師離開這些功能複雜的西廚刀,就會顯得手忙腳亂,如果只有一把中廚刀,甚至不會做菜了。

中餐廚師用這堆西廚刀,會不耐煩,最後還是挑出一把最順手的,當成中廚刀用,其他的閒置。

西餐廚師經常炫技方式就是這刀我會用,那刀我也會用,組合起來還會用。一大堆使用西廚刀的術語名詞和隱藏小技巧。

中餐廚師炫技方式就是,隨便你提啥需求,我都是用這一把刀給你切出來,刀工還強。

西餐廚師看不起中餐廚師,就一把刀,太簡陋,沒逼格。

中餐廚師看不起西餐廚師,一大堆刀,也沒見菜更好喫,而且那一堆西廚刀的功能,咱就一把中廚刀也能切出來。

是的,C++所有新特性,用C都能做出來,無論是面向對象還是函數式編程還是元編程。所以,不要再說C++是面向對象的,而C是面向過程的,這不是本質區別。但C腦補編譯器確實也不是輕鬆的活。

初級階段,C比C++容易學,畢竟語法簡單,關鍵詞少。

中級階段,C++更容易更強大。畢竟有強大的編譯器支持,只要掌握這些語言特性,就已能實現強大的高級功能。而C還需要腦補編譯器,才能實現面向對象等高級特性,不是每個人都能做到,大學課程也不教這些。

高級階段,C++可能變成語言發燒友,各種特性組合會成爲泥潭,牽扯極大的精力。而用C度過中階段後,更深入理解計算機和程序的哲學本質後,會有一種無所不能的感覺。C反而是束縛更少,更自由,更高效的工具。

一個C++高手,能準確掌握更多更復雜的高級語言特性組合,高效率響應業務需求,快速迭代,代碼優雅簡潔,魯棒性好,維護性好,擴展性好。

一個C高手,能掌握更多的基礎模塊實現方案,什麼無鎖消息隊列,內存管理,線程調度器,時鐘,各種算法庫,甚至不同風格的面向對象的架構,這都是自己純手工打造,然後根據業務需要定製這些基礎模塊的設計方案和參數,以追求應用業務的極致性能,和極致可靠。

C高手往往不太喜歡C++那一套,因爲很多東西不能自己掌控。這讓習慣掌控一切的C程序員覺得腳下有些發虛。

C++高手往往也不太喜歡C,因爲很多輪子要自己造。讓習慣快速響應迭代的C++程序員無比煩躁。

都是圖靈完備的語言。C能做到的,C++肯定能做,畢竟C++是C超集。而C++能做到的,其實C也能做到,只需要腦補一種編譯範式而已。

如果非要在哲學上說C和C++有什麼區別,那麼C是心法派,C++是語法派。

每當有新概念新範式出現,C++標準組織就會開發新特性新語法,以提供這種新範式。

而C則腦補一種新的心法(數據結構和算法)來解決,在語法層面儘量少增加特性,幾乎很少變化。

C和C++又有點像武俠之氣宗和劍宗

入門是氣宗C簡單,入門要學的東西少。而劍宗C++不僅要學氣宗的C,還需要學劍宗的這些++,入門就複雜一些。

修煉進展,是劍宗C++來的快,畢竟有一大堆現成的語法範式,不需要知其所以然,只需會用,就能發揮劍宗招式的威力。而氣宗C還要掌握一大堆基礎數據結構和算法以及設計範式,研究精深,知其所以然,才能真正發揮威力。

上限,是氣宗C來的高。等真正深入到高階編程,會發現每一種現成的語法範式和庫,某種意義上,便捷的另一面就是束縛。語言編譯器做的工作越多,庫越強大,編程束縛反而越大;而語法越少編譯器越簡單,反而自由度越高而且越穩定可靠,可供發揮的上限也越高。

對於以C爲主的高水平團隊,C現有的語法不是太少,而是多了,反而還要設定一些編程規範加以限制。所以一些真正經典優美的C代碼,往往都是樸實無華的,很少在語句技巧層面炫技。

以C++爲主的高水平團隊,也常常制定編程規範,對語法使用加以限制,限制可能比C更多。

一個團隊水平高低,從其編程規範就可見一斑。水平越高,往往規矩越多。

當然,真正的高手,都是氣劍雙修的,在語法層面幾乎都是樸實無華,從不炫技,人家炫的是思想。


有人想聽Python是什麼刀。

嗯,竊以爲,Python更多像速凍食品。

速凍食品能快速的滿足需求填飽肚子,而不是餓着肚子還需要洗切烹飪,在底層原料處理環節消耗大量的時間精力。

Python最大優勢就是用起來方便。不是每個人都需要懂編譯器實現,各種算法的細節,各種指針的奇技淫巧。大部分人需要的只是快速方便的解決現實問題。

所以,與其說Python兼容面向對象和面向過程,不如說Python是面向問題的。

Python的編譯器,和大量的庫,都是用C/C++寫的,會熟練使用這些庫,也就站在了巨人的肩膀上,還不是一個,是一羣巨人。掌握這些,足以快速的解決多數問題。

那麼速凍食品就沒有逼格,手工現做就有逼格?其實也不是,一切從現實需求出發,能最快最好滿足需求的工具,就是最好的工具。

Python高手,會掌握大量的庫和設計範式,信手拈來,快速滿足需求。

而進階Python高手,還會自己用C來做庫,以在某些特殊場景下,突破開源庫的功能和規格束縛。


又有朋友問,JAVA,C#,VB,VBA是什麼刀?

這真當咱是刀匠嗎?還是鐵匠? 嗯 ? ~ o( ̄▽ ̄)o

好吧,所有的刀款式,這回一次性解決。

所有編程語言,本質上都是工具。

所有刀,本質上也是工具。

都是工具,工具間,自然有類似特徵,會有些相通之處。

理解這些有趣的相通之處,有利於我們快速的掌握一種新工具。而不是迷失在新工具的細節之中。

而這些有趣的相通之處,其實並不是孤立零散的。

掌握這些有趣相通之處的分佈規律,可以更深刻的理解這些相通之處。

然後,對新工具理解,就是二次方的深刻度。

就像練武,學會心法,招式訓練效果倍增。

而學會心法的心法,功力提升速度則加速到二次方。

二次方程,需要一個座標軸。

建立座標軸,首先需要一個零點,然後需要一個無窮遠。

從零點到無窮遠,就是一個數軸。

當你內心建立起這樣一個數軸,所謂心法的心法,就水落石出,一目瞭然,不需要別人告訴你特徵,打比方解釋給你聽,扯什麼中式菜刀和西式廚刀的故事。

你自己就可以發現規律。

你自己就可以打無數的比方,信手拈來。

那麼,編程語言的零點,在哪裏?

圖靈機

是的,圖靈機,是近幾十年來一切計算機技術的起點。

那麼,無窮遠,又在哪裏?

宇宙間萬事萬物的無限複雜度,不正是無窮遠嗎?

當我們從圖靈機出發,去解決宇宙間萬事萬物的無限複雜的過程,就是從零點到無窮遠的過程,就產生了數軸。

一旦有了數軸,所有的芯片架構和編程語言,都可以在這數軸上有一個位置,也就是座標。

當你俯瞰這些座標構成的散點圖,哦,原來如此,不過如此,就像魔術師的技巧被解密了。

讓我們出發。

圖靈機是零點,第一個點在哪裏?

馮諾依曼架構

圖靈機是數學理論上的抽象模型,而馮諾依曼架構個是可落地的工程計算架構。

實現馮諾依曼架構,需要一套指令集、一些指令集配套的寄存器、運算單元、地址總線、數據總線、內存等。然後,就可以開始機器碼的編程。

基於CPU指令集的機器碼編程,可比基於圖靈機的機器碼編程來的高效的多。

但,每一步效率的提升,都是拿自由兌換的。

指令集也不例外,有位寬的限制,有指令位寬的區別,有寄存器的區別,有精簡指令集複雜指令集區別,等等,等等。

指令集,正是編程遇到的第一次束縛。

所以,從馮諾依曼架構開始出發,有各種各樣的指令集。試圖用不同的實現折中,來換取不同的效率優化。

機器碼編程太累,就有了彙編。彙編跟機器碼幾乎是一一映射,無損壓縮。

彙編還是累,就有了一些初步的高級語言,如廣泛應用成熟的C。

C提供了函數,方便了程序設計,但卻剝奪了CPU寄存器的可見性,戴上了棧空間的束縛,等等。

C++提供了面向對象的語法便捷,但面向對象卻限制了指令交叉訪問數據的自由和效率。

Java等語言提供了內存管理便捷,但剝奪了程序自主內存管理的自由和效率。

面向宇宙萬物的無限複雜度,每一步編程效率的提升,都是拿自由兌換的,毫無例外。

當我們想要更大的便捷性和功能,就面向具體問題,以可以忍受的些許自由代價,來換取解決具體問題的範式,以此獲得效率的提升,也就是更高級的語言。

當我們想要更大的自由度,就向零點回退。

踩着前人的腳步,熟悉每一步自由換取便捷的手法,你心中就有了數軸。

有了數軸,你就可以俯瞰所有的語言、程序、和架構設計。

熟悉這一切,你甚至可以根據需要創造新的編程語言,新的設計範式。

就是這樣而已,沒什麼魔法。

本文完。

課後作業:

圖靈機真的是零點嗎?

這個軸的負數方向意味着什麼?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章