程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> [歡度國慶]為什麼我們今天還要學習和使用C++?(轉載),歡度國慶

[歡度國慶]為什麼我們今天還要學習和使用C++?(轉載),歡度國慶

編輯:C++入門知識

[歡度國慶]為什麼我們今天還要學習和使用C++?(轉載),歡度國慶


在各種新的開發語言層出不窮的今天,在Java和C#大行其道今天,我們為什麼還要學習和使用C++?現在學習C++將來有用嗎?學習C++要花費那麼多時間和精力,這一切都值得嗎?現在學習C++有錢途嗎?這幾乎是每一個C++的初學者都會問的問題,在選擇開發語言進行學習的時候,就像高考填報志願一樣,都會有些迷茫。下面這篇Herb Sutter的文章(其實是他在 C++ and Beyond 2011上的一次公開演講)很好地回答了這些問題。所有那些正在學習C++而又對C++的前途感到迷茫的同學,都值得一讀。本文系轉載,感謝原作者劉未鵬,感謝翻譯者waterwall。更重要的,感謝Herb Sutter。 在這裡,還有一篇關於這一演講的討論,也可以參考:http://www.cnbeta.com/articles/171221.htm 

 

為什麼C++?

 

 

劉未鵬(pongba) /文

waterwalk /譯

C++的羅浮宮(http://blog.csdn.net/pongba)

 

首先非常感謝waterwalk的辛勤翻譯:-) waterwalk把翻譯回貼在原文的下面了,為了方便閱讀我提取出來編輯以後重發一個帖子。這篇文章原本是想對最近C/C++爭論系統的整理一下一些思考的,但由於一開始的時候用英文寫了兩段,後來就干脆都用英文了,造成很多人閱讀的麻煩,在此抱歉。不過好在waterwalk翻譯了整篇文章,於是單獨貼在這裡:-) 

另,原文在這裡。

 

問題

為什麼用C++呢? 在你皺著眉頭離開之前,試著回答這個簡單的問題。效率,是麼?人人都知道這個。但情況是,當一個人開始討論編程語言或與其相關的話題時,他必須要非常明確而有針對性。為什麼呢?我來問你另一個問題:如果效率是人們使用C++的唯一理由,那麼為啥不直接用C呢?C被認為比C++效率更高(嗯嗯,我知道C沒有比C++的效率高多少,所以這裡別誤解我的意思,因為即使它們二者效率相同,剛才的問題依然存在)。 

迷思

我知道你又要說“更好的抽象機制”了,因為畢竟C++是要設計成一個更好的C的。C++沒有犧牲效率,同時又添加了這麼多高級特性。但問題是,“開發者們真的需要這些高級特性麼?”。畢竟我們一直聽人講KISS之類的東西。我們也都聽到有聲稱C比C++更KISS所以我們要用C雲雲。這種持續不斷的爭論將CC++之間的比較變成了一個大大的迷題(或者說是混亂)。令人驚訝的是,貌似的確有很多人更加傾向於用C,最大的理由就是C++實在是太難用對了。甚至Linus也這麼想。 

這種現象最大的影響就是當人們在C和C++之間權衡時,使人們傾向於使用C。而且一旦人們開始用C,他們很快就適應並滿足了(其實,在任何語言乃至任何人類活動中都有此現象,C++亦然,比如常常聽到有人說“XX語言我用了這麼多年,一直用得好好的”,照這種說法任何圖靈完備的語言還不都是能用來編程?)。於是即使他們還沒有試試C++,或者他們還沒成為好的C++程序員時,他們就開始聲稱C比C++更好了。然而其實呢,真實的答案往往總是取決於實際情況的。 

我說過“取決於實際情況”了麼?那到底實際情況是什麼呢?顯然,有些領域C是更好的選擇。例如設備驅動開發就不需要那些OOP/GP技巧。而只是簡單的處理數據,真正重要的是程序員確切地知道系統是如何運轉的,以及他們正在做什麼。那麼寫操作系統呢?我本人並沒有參與任何操作系統的開發,但我讀過不少操作系統代碼(大多是unix的)。我的感覺是操作系統很大一部分也不需要OOP/GP。 

但是,這就表示在所有效率重要的領域,C都是比C++更好的選擇麼?未必。

 

答案

讓我們一個一個來分析。 

首先,當人們關注效率時,有2種效率——時間效率(例如OS,運行時庫,實時應用程序,high-demanding的系統)和空間效率(例如各種嵌入式系統)。但是,這樣的分類並不能幫我們決定用C還是C++,因為C和C++的時空效率都很高。真正影響選擇語言的因素是業務邏輯(這裡的“業務邏輯”並非表示“企業應用業務”)。例如,使用OOP/GP來表達邏輯(或者說代碼的結構)好呢,還是就只用數據和過程好呢? 

據此觀點,我們可以把應用程序大致分為兩類(當然前提是關注的是C/C++而不是java/C#/ruby/erlang等等):底層應用程序和高層應用程序。這裡底層是指像OB/OO和GP沒啥用處的地方, 其余歸到高層。顯然,在所有C/C++應用的領域(這些領域需要C/C++的效率),屬於高層的應用有很多(可以看看Bjarne Stroustrup在他主頁上的列表)。在這些領域中,抽象至少是和效率一樣重要的。而這些正是C++適用的場合。 

等等還有。即使在程序員不需要高級抽象的領域,也不是就絕對用不到C++。為啥呢?僅僅是因為你的代碼中沒有用類或模板並不意味著不能用以類或模板實現的庫。因為有如此眾多方便的C++庫(還有即將到來的tr1/tr2),我覺得有充分的理由在這些領域中使用C++——你可以在編碼時僅使用C++中的C核心(以任何你喜歡的方式來KISS),同時還能用強大的C++(比如STL容器、算法和tr1/tr2的組件)。 

最後,我認為人們還常常忽略了一點——有時KISS是建立在抽象上的。我覺得Matthew Wilson在他新書《Extended STL,卷1》的序言中對此做了很好的闡釋。他寫了2段代碼,一段用C,另一段用C++: 

// in C
DIR*  dir = opendir(".");
if(NULL != dir)
{
  struct dirent*  de;
  for(; NULL != (de = readdir(dir)); )
  {
    struct stat st;
    if( 0 == stat(de->d_name, &st) &&
        S_IFREG == (st.st_mode & S_IFMT))
    {
         remove(de->d_name);
    }
  }

  closedir(dir);
}

// in C++
readdir_sequence entries(".", readdir_sequence::files);
std::for_each(entries.begin(), entries.end(), ::remove);
 
//而在C++09裡面更簡單:
// in C++09
std::for_each(readdir_sequence(".", readdir_sequence::files), ::remove);

 

也就是說,我認為即使一個人在自己的代碼裡不需要類或模版,他也有理由用C++,因為他用的那些方便的C++庫用到了類和模板。如果一個高效的容器(或智能指針)能把你從無聊的手動內存管理中解放出來,為啥還要用那原始的malloc/free呢?如果一個更好的string類(我可沒說std::string,地球人都知道那個不是C++中能做出的最好的string類)或正則表達式類能把你從一坨一坨的、你看都不想看的處理字符串的代碼中解脫出來,那麼為啥還要手動去做這些事呢?如果一個 "transform"(或"for_each")能夠用一行代碼把事情漂亮搞定,為啥還要手寫一個for循環呢?如果高階函數能滿足你的需要,那麼為啥還要用笨拙的替代方法呢?(OK,我知道,最後兩個需要C++加入lambda支持才真正擺脫雞肋的罵名——這正是C++0x的任務嘛) 

總之,我認為KISS並不等同於原始KISS意味著用最適合的工具來做事情,這裡最合適的意思是工具能夠幫你以盡量直接簡潔的方式來表達思想,同時又不降低代碼的可讀性,另外還保持代碼容易理解。

 

真正的問題

人們可能會說,相較於被正確使用而言,C++(遠遠)更容易被錯誤使用。而相比而言,C程序的復雜性更容易管理和控制。在C++中,一個普通程序員很可能會寫出一堆高度耦合的類,很快情況就變得一團糟。但這個其實是另外一個問題。在另一方面,這種事情也很可能發生在任何一門面向對象語言中,因為總是有程序員在還沒弄懂什麼是HAS-AIS-A前,就敢於在類上再寫類,疊床架屋的一層一層摞上去。他們學會了在一門特定的語言中如何定義類,如何繼承類的語法,然後他們就認為自己已經掌握了OOP的精髓了。另一方面,這一問題在C++中更為嚴重,因為C++有如此眾多的偶然復雜性在阻礙設計;而且C++又是如此靈活,很多問題在C++中都有好幾種解決辦法(想想那麼多的GUI庫吧),於是在這些選擇中進行權衡本身就成了一個困難。C++中的非本質復雜性是其歷史包袱使然,而C++0x正是要努力消除這些非本質復雜性(在這方面C++0x的工作的確做得很不錯)。對於設計來說,靈活性不是個壞事情——可以幫助好的設計者作出好的設計。如果有人抱怨說這個太費腦細胞了,那可能是這個設計者本身的問題,而不能怪語言。可能就不該讓他來作設計。如果你擔心C++的高級特性會把你的同事引入歧途,把項目搞砸,那你也許應該制定一份編碼標准並嚴格推行(或者你也可以遵循C++社群這些年積攢下來的智慧,或者在必要時,只使用C++中的CC with class那部分),而不是因為有風險就躲開C++(其實這些風險可以通過一些政策來避免的),因為那樣的話,你就沒法用那些C++的庫了。 

另一方面,其實一個更為重要的問題是一個心理學問題——如果一門語言中存在某個奇異的特性或旮旯,那麼遲早總會有人發現的,總會有人為之吸引的,然後就使人們從真正有用的事情中分心出來(這有點像Murphy法則),更不用說那些有可能對真正問題帶來(在某種程度上)漂亮的解決方案的語言旮旯了。人們本性上就容易受到稀有資源的誘惑。奇技淫巧是稀有資源,於是奇技淫巧便容易吸引人們的注意力,更別說掌握一個技巧還能夠讓那人在他那圈子裡感覺非常牛了。退一萬步,你會發現,即使是一個廢柴技巧也能引起人們足夠的興趣來。

C++中有多少陰暗角落呢?C++中又有多少技巧呢?總的來說,C++中,有多少非本質復雜性呢?(懂一定C++的人一定知道我在說什麼) 

平心而論,近年來(現代C++中)發現的大多數技巧或(如果你願意稱之為)技術實際上都是由實際需求驅動的,尤其是需要實現高度靈活而又普遍適用(generic)的類庫 (例如boost中的那些玩意)。而這些技巧也的確(在某種程度上)提供了對實際問題的漂亮解決方案。讓我們來這麼想一下,如果你處於一個兩難境地:要麼用那些奇技淫巧來做點很有用的東西,要麼不做這樣其他人也就沒得用。你會如何選擇呢?我知道boost的英雄們選擇了前者——不管多麼困難多麼變態多麼龌龊,把它做出來! 

但所有這些爭論都不能改變一個事實我們理應享有一個語言,能夠讓我們用代碼清晰的表達思想。以boost.function/boost.bind/boost.tuple為例,variadic templates可以大大簡化這幾個庫的實現(減至幾乎是原先1/10的代碼行數),同時代碼也(遠遠)更加簡潔易懂。Auto,initializer-list,rvalue-reference,template-aliasing,strong-typed enums,delegating-constructors,constexpr,alignments,inheriting-constructors,等等等等,所有這些C++0x的特性,都有一個共同目的——消除語言中多方面的非本質復雜性或語言中的尴尬之處。 

正如Bjarne Stroustrup所說,很顯然C++太過復雜了,很顯然人們被嚇壞了,並且時不時就不用C++了。但“人們需要相對復雜的語言去解決絕對復雜的問”。我們不能通過減少語言特性而使其更加強大。復雜的特性就連模板甚至多繼承這樣的也是有用的——如果你正好需要它們,而且如果你極其小心使用,不要搬起石頭砸自己的腳的話。其實在所有C++的復雜性當中,真正阻礙了我們的是非本質復雜性(有人稱之為“尴尬之處”),而不是語言所支持的編程范式(其實也就3個而已)。而這也正是我們應該擁抱C++0x的重要原因,因為C++0x正是要消除那些長期存在的非本質復雜性,同時也使得那些奇技淫巧不再必要(很顯然,目前這些技巧堆積如山,翻翻那些個C++的書籍,或者瞅瞅boost庫,你就知道我在說啥了),這樣我們就能夠直觀清晰的表達思想

 

結論

C++難用,更難用對。所以當你決定用它時,要小心,要時刻牢記自己的需求所要達到的目的。這裡有一個簡單的指南:

我們需要高效率麼?

如果需要,那麼

我們需要抽象麼(請仔細思考這一點,因為很難評估使用C++高級特性是否能夠抵消誤用這些機制的風險正確的回答取決於程序員的水平有多高,遵循哪種編碼標准以及編碼標准執行得如何,等等)?

如果是,那麼用C++吧。如果不是,那麼,

我們需要用C++庫來簡化開發麼

如果是,那就用C++吧。但同時必須時刻牢記你在做什麼——如果你的代碼不需要那些“漂亮的”抽象,那就別試圖使用以免陷入其中。別只是因為你在.cpp文件中寫代碼以及你用的是C++編譯器就要用類啊、模板啊這些東西

如果不是,那就用C,不過你又會想為啥不僅僅使用C++中屬於C的那部分核心呢?還是老原因:人們很容易就陷入到語言的“漂亮”特性中去了,即使他們還不知道這些特性是否有用我都記不清有多少次自己寫了一大堆的類和繼承,到最後反倒要問自己要這麼些個類和繼承做什麼呀?。所以,如果你能堅持只用C++CC with class的那部分並遵循“讓簡單的事情保持簡單”的理念;或者你需要把C代碼遷移到C++中來的話,那麼就用C++吧,但要十分小心。另一方面,如果你既不需要抽象機制,也不需要C++庫,因為事情非常簡單,不需要方便的組件例如容器和字符串,或者你已認定C++能夠給項目帶來的好處微乎其微,不值得為之冒風險,或者干脆就沒那麼多人能用好C++,那麼可能你還是只用C的好

底線是:讓簡單的事情保持簡單(但同時也請記住:簡單性可以通過使用高級庫來獲得);必要時才使用抽象(切記不可濫用;遵循好的設計方法和最佳實踐)。

 


內容對於歡度國慶的作文

偉大的祖國
金風送爽,天高雲淡,在這個花果飄香的季節裡,我們迎來了祖國六十一歲的生日,能與大家同祝國慶,我感到非常快樂。在這裡,我要自豪地對祖國母親說:我愛你,中國!
啊!黃河長江,奔騰萬裡,你們哺育了一個多麼輝煌的民族!五千年的輝煌歷史,飲譽四海的華夏文明,足以讓人歎為觀止。哦,祖國,涓涓流貫的河川是你飄逸的長發,綿亘悠久長的山岳是你硬朗的脊梁。你有滿山遍野的寶藏,你有秀麗多姿的山水,你有金碧輝煌的故宮,你有蜿蜓伸展的萬裡長城,縱有千古,橫有八荒。你還有很多很多。。。。。。在你遼闊的土地上,一代又一代的炎黃子孫用自己的雙手創造了燦爛的東方文明。
但是,我們不會忘記,中華民族也曾幾經滄桑、幾經痛苦,我們的祖國母親也曾倍受欺凌與污辱。我們忘不了園明園的火光,忘不了扣在每個中國人頭上的“東亞病夫”的帽子,忘不了公園門口“華人與狗不得入內”的牌子,忘不了南京三十萬同胞的鮮血染紅了長江。大地在呻吟,黃河在哭泣,然而中國人民永遠也不會被壓垮。
虎門銷煙揭開了中華兒女反侵略的序幕。太平天國的旗幟、戊戌變法的驚雷,義和團戰士的大刀、辛亥革命的槍聲,無一不向全世界表明:中華民族不可辱,中國人民不可欺。五四運動的吶喊,中國共產黨的成立,更似驚雷劃破夜空。從南昌到井岡山、從延安到西柏坡,“星星之火,可以燎原”。中國人民硬是用小米加步槍打出了一個燦爛的新中國,我們這個東方巨人終於又站起來了!
走過61年的風風雨雨,經過59年的勵精圖治,我們的祖國巍然屹立於世界的東方。中國人民正享受著從未有過的太平盛世。中國特色社會主義的航船正劈波斬浪,昂首前行!
同學們,我們中國已經很強大,但是不能忘記,我們的統一大業還沒有完成,國際反華勢力亡我之心不死,日本對我國的釣魚島垂涎三尺,更不能忘記,1999年我國使館的被炸,同胞的鮮血告訴我們:我們還不夠強大。
前進中的艱難險阻,激發著我們的豪情斗志新的千年,新的世紀,新的起點,十六大給我們吹響了進軍的新號角,億萬中國人民正向著新的目標奮進。
同學們,我們是祖國和民族的未來,我們生在一個偉大的時代。同學們,努力吧,中華民族的偉大復興將在我們手中實現。祖國啊,母親!請相信,我們一定不會辜負歷史的重托,新的《中華交響曲》將在我們手中演奏出更精彩更輝煌的樂章!就象李大钊期望的那樣:“讓中華民族五千年的正氣在青春的火焰中再現!讓華夏神州五千年的雄健國魂在青春的火焰中再生!!!”
以前,在我還不懂事時,每年的國慶節也會讓我很高興,那是因為國慶節要放長假,我可以和伙伴們痛痛快快地玩,和爸爸媽媽一起去旅游。現在我長大了,我知道了1949年的十月一日,毛主席在天安門城樓上向全世界宣布:“中華人民共和國成立,中國人民從此站起來了。”我還知道了為了這一天,無數先輩付出了鮮血和生命,也正是無數的鮮血和生命換來了我們今天的和平與美好生活。今年的“十•一”是祖國61歲生日,此時,我的心裡充滿了感激、敬佩,也為祖國的美麗、強大感到無比的驕傲和自豪。
我曾經在課外書中看到過一些介紹舊中國的文章,舊中國是一個被外國瞧不起的國家,處處受人欺辱,中國人還被稱為“東亞病夫”。舊中國也曾經派運動員參加過奧運會,可是連半決賽都沒進入,更別說拿獎牌了。那時各國的報紙都嘲笑中國人,給中國運動員畫了一幅手捧鴨蛋的漫畫……然而,一百年後的今天,有誰還會說我們是“東亞病夫”?有誰還會嘲笑我們?中國的健兒在奧運賽場上向全世界展現了他們的力量和風采,創造了一個個輝煌。尤其是今年奧運會賽場上,田徑運動員劉翔的那一枚沉甸甸的金牌,更是讓我們驕傲、自豪,他不僅僅是中國的......余下全文>>
 

歡度國慶節的手抄報要清楚今天就要好的高分

畫一個國旗,五顆星寫題目,在裡面寫資料。畫一個中華人民共和國的徽章,然後畫一些雲,在裡面寫資料,可以自己畫一些小動物或者一些名人。最好用彩鉛上色!
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved