![C程序員從校園到職場_第1頁](http://file4.renrendoc.com/view10/M03/26/23/wKhkGWWL82GAAIkbAACP6fUbTGQ402.jpg)
![C程序員從校園到職場_第2頁](http://file4.renrendoc.com/view10/M03/26/23/wKhkGWWL82GAAIkbAACP6fUbTGQ4022.jpg)
![C程序員從校園到職場_第3頁](http://file4.renrendoc.com/view10/M03/26/23/wKhkGWWL82GAAIkbAACP6fUbTGQ4023.jpg)
![C程序員從校園到職場_第4頁](http://file4.renrendoc.com/view10/M03/26/23/wKhkGWWL82GAAIkbAACP6fUbTGQ4024.jpg)
![C程序員從校園到職場_第5頁](http://file4.renrendoc.com/view10/M03/26/23/wKhkGWWL82GAAIkbAACP6fUbTGQ4025.jpg)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
C程序員從校園到職場第1第2第3第4第5第6第7第8第9第10SQL語句和Shell命令第11附錄A同行評審第1章 概述本章介紹C語言的發(fā)展歷史和主要特點,以及實際項目工作中軟件開發(fā)工程師常用到的工具軟件。C語言的發(fā)展歷史C語言之父C語言是1972年由美國貝爾實驗室的計算機科學(xué)家DennisRitchie(丹尼斯·里奇)設(shè)計發(fā)明的。因此,DennisRitchie被譽為“C語言之父”(他已于2011年10月9日去世,享年70歲)。圖1.1所示的人物就是DennisRitchie。圖1.1 “C語言之父”DennisRitchieDennisRitchie曾在哈佛大學(xué)學(xué)習(xí)物理學(xué)和應(yīng)用數(shù)學(xué),1967年進入貝爾實驗室工作。作為計算機科學(xué)家,在他身上有很多可貴的、值得我們學(xué)習(xí)的品格,例如:第一,他對所做的事十分有興趣;第二,跳出舒適區(qū)工作,不斷挑戰(zhàn)自己;第三,有創(chuàng)新思維,不拘泥于條條框框;第四,喜歡分享,不藏匿自己的核心技術(shù)。DennisRitchie對計算機科學(xué)的貢獻主要有以下幾個方面:第一,作為“C語言之父”,他最大的貢獻當然是發(fā)明了C語言;第二,1973年他與KenThompson合作,把UNIX90%以上的內(nèi)容用C語言改寫,因此也被譽為“UNIX之父”;第三,1978年他與BrianW.Kernighan一起出版了名著TheCProgrammingLanguage(《C程序設(shè)計語言》),此書已被翻譯成多種語言,成為C語言方面最權(quán)威的教材之一?;贒ennisRitchie的杰出成就,1983年他與KenThompson一起獲得了圖靈獎。1999年,DennisRitchie和KenThompson因為在發(fā)展C語言和UNIX操作系統(tǒng)方面所做出的貢獻一起榮獲了美國國家技術(shù)獎?wù)?。C語言的演進作為在國際上廣泛使用的計算機編程語言,C語言的發(fā)展簡史如圖1.2所示。C語言到底有多少人在用?C語言的受歡迎程度如何?如圖1.3所示為CodeForge網(wǎng)站公布的2014年11月“我最喜愛的編程語言”排行榜。這個排行榜來自2014年11月對56000多名軟件工程師的問卷調(diào)查。該排行榜非常清楚地反映了在世界不同國家和地區(qū)各種編程語言的流行程度,可供軟件工程師及IT相關(guān)行業(yè)人士參考。從圖1.3可以看出,在全球范圍內(nèi),C語言的受歡迎程度位居排行榜的榜首。因此,C語言使用得非常廣泛。圖1.2 C語言的發(fā)展簡史圖1.3 2014年11月“我最喜愛的編程語言”排行榜C語言的主要特點C語言是一種功能強大的、被廣泛應(yīng)用的面向過程的編程語言,可用于編寫系統(tǒng)軟件和應(yīng)用軟件。C語言的主要特點如圖1.4所示。如圖1.4所示,C語言的諸多特點使其越來越受到廣大軟件開發(fā)人員的青睞,也使其成為了使用人數(shù)最多的計算機編程語言之一。學(xué)習(xí)好C語言,對于深入學(xué)習(xí)計算機科學(xué)的其他課程都是很有好處的。圖1.4C語言的主要特點常用工具軟件有一次,我打開電視機準備隨便看看,無意中被一部戰(zhàn)爭片吸引住了。成千上萬的戰(zhàn)士搭起云梯,想攻破一座城池。但是城樓上面的敵人負隅頑抗,拼了命地阻擊進攻。雙方的傷亡都很慘重,但城就是攻不下來。眼看剩下的人不多了,突然不知從什么地方開出一輛坦克,兩炮就把城門轟開了。戰(zhàn)士們趁勢攻入城中,將敵人全部殲滅了。這類電視劇比較常見,相信大家看了不止一次。但是,我看完之后,那個場景還一直留在我的腦海里。成千上萬的人不如一輛坦克來得直接,說明了什么問題呢?我立馬想到了一句俗語:工欲善其事,必先利其器。的確,工具對于軟件開發(fā)工程師來說,真的是很重要。好的工具能夠提高開發(fā)的效率,進而縮短產(chǎn)品的研發(fā)周期。那么,在實際的軟件研發(fā)項目中,軟件開發(fā)工程師常用的工具軟件有哪些呢?MicrosoftVisualStudio/MicrosoftVisualC++6.0MicrosoftVisualStudio(VS)是美國微軟公司的開發(fā)工具包系列產(chǎn)品。它是一個較為完整的開發(fā)工具集,包括了整個軟件生命周期中所需要的大部分工具,如集成開發(fā)環(huán)境(IDE)等。MicrosoftVisualC++6.0(VC或者VC6.0),是微軟推出的一款C++編譯器,將“高級語言”(如C、C++等)翻譯為“機器語言”的程序。它是一個功能強大的可視化軟件開發(fā)工具,已成為大多數(shù)專業(yè)程序員進行軟件開發(fā)的首選工具之一。現(xiàn)在的最新版C++編譯器集成在MicrosoftVisualStudio2015軟件里面。用MicrosoftVisualC++6.0軟件打開的代碼如圖1.5所示。圖1.5 用MicrosoftVisualC++6.0軟件打開的代碼鑒于使用MicrosoftVisualStudio/MicrosoftVisualC++6.0進行軟件開發(fā)的人員很多,有熱心人士為其開發(fā)了一款叫做VisualAssistX的插件。VisualAssistX是一款非常好的MicrosoftVisualStudio/MicrosoftVisualC++6.0插件,支持C、C++、Java等語言,能夠自動識別各種關(guān)鍵字、系統(tǒng)函數(shù)、成員變量,同時能夠自動給出輸入提示、標示錯誤、更正大小寫錯誤等,有助于提高開發(fā)效率。SourceInsightSourceInsight是一個面向項目開發(fā)的程序編輯器和代碼瀏覽器,它擁有內(nèi)置的對C、C++、Java等程序的分析。它能夠分析你的源代碼,并自動為你顯示有用的上下文信息。SourceInsight不僅是一個強大的程序編輯器,還提供了最快速的對源代碼的導(dǎo)航信息。該工具被視為如今最好用的語言編輯器之一。用SourceInsight軟件打開的代碼如圖1.6所示。圖1.6 用SourceInsight軟件打開的代碼Notepad++Notepad++是一款很有特色的Windows環(huán)境下免費開源的代碼編輯器。除了可以用來制作一般的純文字說明文件之外,也十分適合用作代碼程序的編輯器。Notepad++極具特色的一個功能就是語法的高亮度顯示,方便了對關(guān)鍵詞語的閱讀。它支持的語言包括C、C++、Java等。用Notepad++軟件打開的代碼如圖1.7所示。圖1.7 用Notepad++軟件打開的代碼AraxisMerge/BeyondCompareAraxisMerge當程序代碼比較多(成千上萬行)的時候,我們想要了解最新代碼與之前某個時期的代碼的不同之處,并不是一件容易的事情。這樣,代碼比較工具就應(yīng)運而生了。AraxisMerge和BeyondCompare是兩款用得較多的代碼比較工具。AraxisMerge是一個可視化的文件比較、合并和同步的軟件,能夠方便地被軟件工程師用于快速精確地比較不同版本的源文件。此外,它還能被用于進行版本和質(zhì)量控制。用AraxisMerge軟件進行代碼比較如圖1.8所示。BeyondCompareBeyondCompare是一套由ScooterSoftware推出的軟件,主要用于文件之間的比較。對于軟件開發(fā)工程師來說,它可以用來發(fā)現(xiàn)不同版本代碼或文檔的不同,使用起來非常方便。圖1.8 用AraxisMerge軟件進行代碼比較用BeyondCompare軟件進行代碼比較如圖1.9所示。圖1.9 用BeyondCompare軟件進行代碼比較Evernote(印象筆記)Evernote(印象筆記)是2012年5月10日由Evernote公司推出的一款產(chǎn)品,具有儲存重要資料、剪輯網(wǎng)頁、圖片搜索等功能。對于軟件開發(fā)工程師來說,Evernote可用于記錄閱讀過的重要技術(shù)書籍的筆記、在工作過程中的一些想法,以及軟件實踐或論文等。Evernote軟件的界面如圖1.10所示。圖1.10 Evernote軟件的界面FTP工具(如FileZilla等)在工作過程中,我們會不時地需要用FTP工具來上傳或下載一些東西。FileZilla是軟件開發(fā)工程師用得較多的FTP工具之一。FileZilla是一款免費的、開源的FTP軟件,分為客戶端版本和服務(wù)器版本兩種。它具備所有的FTP軟件功能,使用起來非常方便、快捷,曾在2002年11月獲選為當月最佳推薦專案。FileZilla軟件的操作界面如圖1.11所示(在使用的時候,需要輸入正確的主機IP地址、用戶名和密碼,端口號一般使用默認的21)。圖1.11 FileZilla軟件的操作界面UltraEdit在實際的軟件開發(fā)過程中,UltraEdit也是一款經(jīng)常會使用到的工具軟件。它是一款功能十分強大的文本編輯器,可以用于編輯文本、十六進制、ASCII碼等。當然,用它來編寫C/C++代碼也是十分方便的。用UltraEdit軟件打開代碼之后的界面如圖1.12所示。好的工具對于軟件開發(fā)工程師來說,就像優(yōu)良的戰(zhàn)斗武器對于戰(zhàn)士一樣重要。善于利用優(yōu)秀的工具,可節(jié)省開發(fā)時間、提高我們辦事的效率,進而提高軟件產(chǎn)品的質(zhì)量。因此,掌握一些常用軟件的使用方法是非常重要的。圖1.12 用UltraEdit軟件打開代碼小結(jié)本章對C語言的發(fā)展歷史、C語言的主要特點,以及軟件開發(fā)工程師常用到的工具軟件進行了詳細的介紹。本章對后續(xù)章節(jié)起到了一個拋磚引玉的作用。第2章學(xué)校到職場踏出校門,對于我們整個學(xué)習(xí)生涯來說,只是“萬里長征走出了第一步”。為了使得之后學(xué)習(xí)和工作的道路走得更加順暢,我們需要認清自身所學(xué)知識的不足,我們需要破除一些有關(guān)軟件開發(fā)的錯誤觀念,我們更需要在學(xué)校里面就未雨綢繆地開始培養(yǎng)工作所需的一些技能。認清自身不足我在走出校門的時候非?!拜p狂”,認為自己在學(xué)校里面已經(jīng)學(xué)得夠多了,工作就只是“小菜一碟”。但在工作中屢次碰壁之后,我才發(fā)現(xiàn)自己當時的很多想法都是不成熟的。我們踏上工作崗位,一切幾乎都要從零開始。對于大家“非常熟悉”的C語言來說,我們在學(xué)校里面學(xué)到的只是皮毛,遠遠不能滿足實際軟件開發(fā)工作的要求。我們在學(xué)校里面學(xué)到的典型的C語言程序如下:#include<stdio.h>voidmain(){floatfac(intn);intn;floaty;printf("inputanintegernumber:");scanf("%d",&n);y=fac(n);printf("%d!=%10.0f\n",n,y);}floatfac(intn){floatf;if(n<0){}
printf("n<0,dataerror!");if(n==0||n==1)f=1;f=fac(n-1)*n;return(f);}對于以上程序,至少存在如下幾個問題。第一,變量命名不規(guī)范,而且沒有初始化。對于該程序,main函數(shù)里的變量n、y,fac函數(shù)里變量f的命名均不規(guī)范,不能讓人一眼就看出它是什么意思、要做什么操作。這對于一小段程序來說,影響還不是很大,但如果代碼行數(shù)達到數(shù)千行甚至上萬行,那么閱讀起來就比較的費力。另外,以上3個變量只是定義了,并沒有初始化,這在實際項目中也是不允許的。第二,函數(shù)的命名不規(guī)范,且沒有在主函數(shù)開始之前進行聲明。本程序中的fac函數(shù)要做什么操作?通過閱讀代碼,我們知道該函數(shù)的功能是計算一個整數(shù)的階乘。在實際項目數(shù)調(diào)用者的內(nèi)部來對被調(diào)函數(shù)進行聲明,而是將聲明放在外部,最好新建一個頭文件(.h文件)來對程序里出現(xiàn)的函數(shù)進行聲明。第三,程序代碼排版不工整,“if…else”語句書寫不規(guī)范。在fac函數(shù)中,代碼的排版不工整。第一個if語句下面的大括號應(yīng)該與“if”關(guān)鍵字保持在同一列上,第二個“else”關(guān)鍵字應(yīng)該與第二個“if”關(guān)鍵字保持在同一列上,“f=1;”和“f=fac(n-1)*n;”應(yīng)該再縮進4個空格。另外,“if”和“else”關(guān)鍵字下面的執(zhí)行語句不管有多少行,都應(yīng)該用“{}”括起來,以方便閱讀。第四,程序注釋過少,函數(shù)開頭沒有注釋。一般說來,在程序的關(guān)鍵語句的前面或右邊,都應(yīng)該添加適當?shù)淖⑨專@對程序的理解有輔助的作用。函數(shù)fac的前面應(yīng)該加注釋,說明此函數(shù)的功能、輸入/輸出參數(shù)、返回值、修改記錄等。在整個程序的開頭也要添加版本信息、修改記錄等注釋信息,以方便日后查閱。第五,程序中出現(xiàn)了“printf”、“scanf”和“main”函數(shù)。這是大家都習(xí)以為常的,但在實際的項目中,幾乎不可能出現(xiàn)這3個函數(shù)。因為很多公司都有自己的開發(fā)平臺,而且代碼都達到數(shù)千行,甚至上萬行,再加上大部分都不是基于VC開發(fā)的,你在哪里去輸入,又在哪里去看輸出呢?我一進公司,最開始看到程序,就想去找“printf”、“scanf”和“main”,但這是徒勞的,因為根本就沒有。關(guān)于輸入/輸出,開發(fā)中會有專門的消息處理流程來處理,大家需要知道的就是一個完整的代碼工程中不一定非要有上面的3個函數(shù)(但本書為了給大家介紹C語言的相關(guān)知識,在程序仍然使用這3個函數(shù))。短短的幾十行代碼,就出現(xiàn)了這么多大家“沒有想到”的問題。看到以上的分析,也許你會很驚慌:我以前的C語言難道是白學(xué)了?非也!我舉這個例子,不是為了給大家當頭一棒,讓大家覺得軟件開發(fā)是多么高深和艱難。我只是想說明,對于C語言,我們還有很多不知道的東西,即使是自己知道的,也與階段,而后才逐漸去改變了自己“根深蒂固”的觀念?!爸e能改,善莫大焉”??!破除錯誤觀念要讓我們做事情的能力能夠有所提升,觀念的轉(zhuǎn)變是關(guān)鍵。從學(xué)生轉(zhuǎn)變?yōu)槁殬I(yè)人的過程是很艱難的,因為我們要與自己積累了多年的“老毛病”作斗爭,這些“老毛病”包括:做事拖拉、不守時、不遵守規(guī)則、怕吃苦等。就像發(fā)射火箭衛(wèi)星了。所謂“萬事開頭難”,也就是這個道理。那么,要想掌握工作中C語言的基本技能,我們需要破除哪些錯誤觀念呢?如圖2.1所示。圖2.1 我們需要破除的錯誤觀念錯誤觀念一:我的C語言學(xué)得很好。很多剛走出學(xué)校的、準備從事軟件開發(fā)的人都持有這樣的觀念,因為他們在學(xué)??荚嚩嫉昧烁叻帧5敕ㄊ敲篮玫?,現(xiàn)實是殘酷的。真正到了工作崗位,你就會發(fā)現(xiàn),自己在學(xué)校學(xué)的那些知識是十分有限的,根本不足以應(yīng)對工作。例如,C語言中的指針、結(jié)構(gòu)體、異常保護這些,學(xué)校里面講得很少或者不深入,大家也沒有太注意,只是應(yīng)付了考試,但工作中我們需要時時與它們打交道。你還說自己學(xué)得好嗎?因此,為了個人的技術(shù)積累和職業(yè)發(fā)展,我們一定要謙虛,要虛心學(xué)習(xí)。錯誤觀念二:編程是很簡單的事情。持這種觀點的人,也是受到了學(xué)校教育的影響,因為書本上面的代碼都很短,而且比較簡單。但在工作中,也這么簡單嗎?非也。我總結(jié)了一下,教材上的程序與實際工作中的程序至少有以下幾點不同。第一,代碼行數(shù)的多少。教材中的代碼一般為幾十行,多則一兩百行,大家當然會覺得簡單;而工作中的代碼少則幾千行,多則上萬行,兩者根本不是同一個數(shù)量級的。我最開始拿到程序的時候,腦袋就暈了:怎么這么多代碼呢?我從沒看到過。第二,變量及函數(shù)的命名。這是兩者的最大不同,也是“專業(yè)”和“業(yè)余”的重要區(qū)別。在教材中,經(jīng)常的命名有這幾個:“inti;”、“char*p;”、“floatf;”、“intf(inta,intb)”等,大家都已經(jīng)習(xí)以為常了。但變量及函數(shù)的命名不能想當然。這在后續(xù)的章節(jié)中會有詳細的說明。第三,程序的注釋。附近,一定要有注釋。不僅如此,注釋的寫法也有多種,在不同的地方,寫法是不一樣的。簡短而清晰的注釋可以提高大家閱讀代碼的速度,進而提高了工作效率。第四,輸入/輸出語句。在教材上,幾乎每個程序都有“scanf”和“printf”這兩個函數(shù),用于讀入和輸出數(shù)據(jù),大家用得是津津有味,如果哪個程序沒有這兩個函數(shù),反而會覺得奇怪。但在實際的項目代碼中,幾乎不存在這兩個函數(shù)的,而代之以其他方式來進行輸入和輸出。在剛開始的時候,你也許會覺得難以接受,但慢慢熟悉之后,你就會知道這是什么原因了。第五,程序的樣式。解,認為編程只注重功能,其他什么的都可以“隨心所欲”。但在工作中,對于程序的版式、布局都是有嚴格規(guī)定的,哪里應(yīng)該縮進(以及縮進幾個空格)里應(yīng)該留空行,都是要注意的。這就像一個人一樣,光說自己肚子里“有貨”還不行,還需要注意外表,要讓大家看起來覺得很舒服,所謂的“內(nèi)外兼修”,就是這個道理。錯誤觀念三:我只要把代碼寫好就行了,其他的就不用管了。大家也許會認為,開發(fā)工程師只負責(zé)寫程序,其他的什么測試啊、寫文檔啊,就不必自己操心了。其實不然。在工作中,開發(fā)工程師的工作是很多的,編寫代碼只是一小部分。在編寫代碼之前,我們要對軟件進行詳細設(shè)計;在代碼寫完之后,不能馬上把它交給測試人員來測試。很多新手寫完代碼就了事,這是不對的。我們要首先進行自測,這會花費比較長的時間,甚至比寫代碼的時間還要長很多,等自測無誤之后,才能正式提交。除了寫代碼和自測,我們還要編寫相關(guān)的開發(fā)文檔。你也許會認為寫文檔是文檔工程師的事情,非也,這是開發(fā)工程師要干的。另外,我們從開始寫代碼到最后提交,都要嚴格遵守項目的管理流程,不能放任自流,要在規(guī)則之下來做事情。錯誤觀念四:公司會安排好我的職業(yè)道路。每個人進入公司,都會有相應(yīng)的入職培訓(xùn),這其實就是公司對應(yīng)屆畢業(yè)生進行所謂的“洗腦”的過程。培訓(xùn)老師會給大家講,公司是多么多么好,公司會針對每個員工制定好培養(yǎng)計劃,讓大家在適合自己的職業(yè)軌道上發(fā)展。但是,當你發(fā)現(xiàn)坐在你旁邊的員工已經(jīng)入職10年,可是還做著和你一樣的工作時,你對公司美好的幻想瞬間就破滅了。確實,不管是在學(xué)校,還是在工作單位,我們不要指望學(xué)?;蚬灸軌?qū)⑽磥淼牡缆方o安排好,而要靠自己不斷地努力去實現(xiàn)自身的價值??茖W(xué)技術(shù)日新月異,新的軟件開發(fā)技術(shù)層出不窮。從事軟件開發(fā)這一行,我們就要馬不停蹄地學(xué)習(xí),任何寄希望于他人或公司的想法都是不可取的?!澳サ恫徽`砍柴工”,在樹立了正確的觀念之后,我們學(xué)習(xí)工作中的C語言就容易多了。工作所需軟技能的培養(yǎng)在新員工剛進入公司的時候,一般都會有一段時間的試用期,也叫做培訓(xùn)期。對于大部分IT企業(yè)來說,這個試用期大體分為3個階段:第一階段,企業(yè)文化、辦事流程、公司業(yè)務(wù)范圍等的培訓(xùn);第二階段,工作所需專業(yè)知識的培訓(xùn);第三階段叫做“以師帶徒”,也就是由一位老員工帶著來從事具體的開發(fā)工作。但是,我們不能奢望通過這個短短的培訓(xùn)期就能夠?qū)⒐ぷ髦兴璧募寄苋空莆?,因為學(xué)習(xí)重在長期的積累,個人習(xí)慣的改變更是一個漫長而痛苦的過程。這就需要我們在學(xué)校里面就有目的性地培養(yǎng)工作所需的方方面面的東西??偟恼f來,工作所需的一些軟技能(即除專業(yè)技能之外的一些影響個人工作和發(fā)展的技能)如圖2.2所示。圖2.2 工作所需的一些軟技能那么,我們?nèi)绾卧趯W(xué)校里面有針對性地培養(yǎng)如圖2.2所示的各種能力呢?第一,對于實踐性較強的一些課程(如程序設(shè)計課程、算法課程、網(wǎng)絡(luò)課程、數(shù)據(jù)庫課程等),一定不能只求考試通過,要多問為什么、多動手編寫程序。有一位學(xué)弟發(fā)來郵件向我咨詢一些問題,其中有個問題是這樣的:看書學(xué)技術(shù)的時候有時還是很有成就感的,特別是敲代碼實現(xiàn)一些小的算法的時候,感覺很舒服。但是看得時間長了偶爾就會感覺枯燥,耐不住寂寞。想必很多人都有類似的感觸。我的答復(fù)是這樣的:如果你在學(xué)校寫點程序就會覺得枯燥的話,在工作中你會覺得更枯燥。如果你從事軟件開發(fā)工作,那么幾乎每天都要和程序打交道,需要相當大的韌性才能堅持得住。如何才能既學(xué)到技術(shù),又不感覺到枯燥呢?根據(jù)我個人的經(jīng)驗,可以參考圖2.3。圖2.3 一個學(xué)習(xí)的良性循環(huán)打個比方來說,你要學(xué)習(xí)C語言,那么首先要選一本好的參考書,對于書上的程序或課后的習(xí)題,你要親自敲到電腦里面來運行。慢慢熟悉之后,你對編程會有一些心得體會,這時你就可以將這些心得體會寫成博客發(fā)表出去。寫博客又會促使你去學(xué)習(xí)新的東西,別人的評論也會讓你受益。如此不斷地循環(huán)(根據(jù)個人的經(jīng)驗這是一個良性循環(huán)),自身能力會不斷提高,你會發(fā)現(xiàn)學(xué)習(xí)技術(shù)是一件很有趣的事情。如果你覺得書本上的題目太簡單,可以利用我們最強大的老師(網(wǎng)絡(luò))去尋找一些實際的軟件開發(fā)項目來做。此外,很多開源社區(qū)也是一個很不錯的選擇?!皢柷堑们迦缭S,為有源頭活水來”,我們只有不斷地輸入和輸出知識,才能讓自身充滿活力。第二,適當?shù)貐⒓右恍┥鐖F活動或集體活動,利用假期(如寒假或暑假)到外面去做兼職。末了。通過恰當?shù)募媛毤吧鐖F活動,我們不僅能夠?qū)W到一些書本上沒有的知識(夠看到書本知識在實際中的應(yīng)用),動。第三,打好專業(yè)基礎(chǔ),在高年級的時候爭取能夠到企業(yè)里面去實習(xí)。絕大部分學(xué)生在學(xué)校學(xué)習(xí)的最終目的是就業(yè),也就是要走出校門,進入企業(yè)。因此,如果你在畢業(yè)之前能夠有一段到企業(yè)里面去實習(xí)的經(jīng)歷,那么這必將豐富你的人生經(jīng)歷,讓你在畢業(yè)求職的路上快人一步。能夠去單位實習(xí),從側(cè)面來說也是對你在校學(xué)習(xí)成果的一種認可。因此,大家一定要將自己的專業(yè)課學(xué)好,讓企業(yè)認為你是一個可以培養(yǎng)的人。通過一份比較有份量的實習(xí),我們不僅能夠?qū)W到專業(yè)知識、企業(yè)運作流程,還能夠提高自己的動手能力、表達能力、團隊協(xié)作能力等,同時也可以為自己的簡歷增加亮點。李開復(fù)老師也多次強調(diào)了大學(xué)生實習(xí)的重要性。小結(jié)本章作為一個過渡章節(jié),從認清自身所學(xué)C語言知識的不足入手,接著讓大家破除幾個有關(guān)軟件開發(fā)的錯誤觀念,然后讓在校學(xué)生有意識地培養(yǎng)工作所需的一些軟技能。認清自身的不足讓人謙虛,破除錯誤觀念讓人不惑,培養(yǎng)技能讓人信心百倍。現(xiàn)在,我們可以正式開啟軟件項目實踐中C語言的學(xué)習(xí)征程了。第3章 程序的樣式在《高質(zhì)量程序設(shè)計指南(C++/C語言)》中,作者說:可以把程序的版式比喻為“書法”,好的“書法”先看到的便是程序的排版,我們的第一印象便是程序?qū)懙檬枪ふ€是凌亂。都說第一印象很重要,為了給大家留下好的第一印象,我們一定要注重程序的版式。此外,好的注釋能夠幫助讀者更快地理解程序,提高工作效率。也許是因為工作比較忙的緣故,很多軟件工程師不喜歡為自己的程序?qū)懽⑨專J為這樣做是沒有必要的。那么,如果給他一份毫無注釋的代碼,他會有什么樣的感受呢?在程序中,優(yōu)美的、得當?shù)淖⑨屇軌蚱鸬藉\上添花的作用,更能夠體現(xiàn)出一個工程師的專業(yè)素質(zhì)。因此,寫注釋實在是很有必要的。本章介紹頭文件、源文件(也被稱作定義文件)的樣式,空格、空行、大括號的使用和注釋的書寫。本章中的示例代碼均是基于開發(fā)項目實踐中的編碼規(guī)范來編寫的。頭文件頭文件起到一個輔助的作用,簡要地反應(yīng)出本程序的基本功能。采用以下的樣式來書寫頭文件:/***************************************************************版權(quán)所有(C)2015,公司(或個人)名稱。*文件名稱:內(nèi)容摘要:其他說明:當前版本:作 者:完成日期:*修改記錄1:修改日期:修改內(nèi)容:*修改記錄2:修改日期:修改內(nèi)容:#ifndef_XXX_H //防止頭文件被重復(fù)引用#define_XXX_H/**************************************************************相關(guān)宏定義**************************************************************//**************************************************************相關(guān)結(jié)構(gòu)體定義**************************************************************//**************************************************************源程序中出現(xiàn)的函數(shù)聲明#endif說明:在頭文件開始的地方,一定要有注釋。這里的注釋主要是版權(quán)、版本、作者等相關(guān)在單位為軟件產(chǎn)品寫的每一行代碼都要有版權(quán)聲明,這也是對一個職業(yè)人的基本要求。的。為了便于理解,我們會將很多諸如數(shù)字等信息用宏來代替,就像C語言課上我們用“PI”來代表圓周率的值一樣。此時,就需要在頭文件中對源文件中需要用到的宏進行定義,并給出適當?shù)淖⑨?,方便理解。在實際的C語言程序中,結(jié)構(gòu)體是經(jīng)常會用到的。例如,某個消息結(jié)構(gòu)體包含了很的所有結(jié)構(gòu)體。在學(xué)校里,很多人都不習(xí)慣對函數(shù)進行聲明。為了防止函數(shù)在沒有定義之前就被引數(shù)后面一定要寫上恰當?shù)淖⑨?。源文件源文件文件是程序的核心,所有的工作都是在該文件里面完成的。采用以下的樣式來書寫源文件?***************************************************************版權(quán)所有(C)2015,公司(或個人)名稱。*文件名稱:內(nèi)容摘要:其他說明:當前版本:作 者:完成日期:*修改記錄1:修改日期:修改內(nèi)容:*修改記錄2:修改日期:修改內(nèi)容:***************************************************************//**************************************************************頭文件引用**************************************************************//**************************************************************全局變量定義**************************************************************//**************************************************************函數(shù)實現(xiàn)**************************************************************/說明:函數(shù)頭部的版權(quán)、版本、作者等相關(guān)的信息與頭文件的類似,也是必不可少的。函數(shù)包括進來。怎么辦呢?辦法就是引用定義這些函數(shù)的頭文件,像我們很熟悉的“#include<stdio.h>”。當源程序中的函數(shù)比較多時,會出現(xiàn)很多函數(shù)都需要使用同一個變量的情況,這就何?函數(shù)是程序的核心,我們開頭做了那么多的工作,都是為實現(xiàn)函數(shù)功能服務(wù)的。那部的注釋可采用如下的樣式:/**********************************************************************功能描述:輸入?yún)?shù):輸出參數(shù):其他說明:修改日期 版本號 修改人 修改內(nèi)容* YYYYMMDD XXX Name YYY***********************************************************************/“YYYYMMDD”表示“年月日”,“XXX”是創(chuàng)建或修改函數(shù)時的版本號,“Name”是函數(shù)創(chuàng)建或修改人的名字,“YYY”是對函數(shù)修改內(nèi)容的簡要描述(如果該函數(shù)是第一次創(chuàng)建,那么“YYY”就可以寫成“創(chuàng)建”)。在實際的開發(fā)工作中,很多軟件程序都比較復(fù)雜,其中涉及的宏定義、結(jié)構(gòu)體、函數(shù)等非常多,大家一定要按照規(guī)范的頭文件及源文件的樣式來書寫程序,以利于代碼的閱讀及后期維護。本書中的大部分示例程序針對的是具體的知識點,因此與實際開發(fā)工作中的很多程序相比,要簡單很多。為了便于說明,本書大部分示例程序都以源文件的形式呈現(xiàn),文件中代碼布局的先后順序為:文件說明、頭文件引用、數(shù)據(jù)類型或結(jié)構(gòu)體定義、函數(shù)聲明、函數(shù)實現(xiàn)??崭窈涂招性诔绦虼a中,如果善用空格和空行,可使程序的版式更加的優(yōu)美。本小節(jié)說明空格和空行的使用方法??崭裨贑語言的關(guān)鍵字(像if、for、while、switch等)之后要留有空格,以突出該關(guān)鍵字;在函數(shù)名之后不要留空格,緊跟左括號“(”間,要留有空格,如Function(x,y,z)。賦值操作符、算術(shù)操作符、比較操作符、邏輯操作符、位域操作符等,如“=”、“+=”、“>=”、“<=”、“+”、“*”、“%”、“&&”、“||”、“<<”,“^”等二元操作符的前后應(yīng)當加空格。但一元操作符如“!”、“~”、“++”、“??”、“&”(地址運算符)等前后不加空格。在一行代碼的結(jié)尾之后不要留空格。在代碼中,使用空格進行縮進(一般縮進為4個空格),不要使用制符表(即Tab鍵來縮進??招锌招衅鹬指舫绦蚨温涞淖饔茫m當?shù)目招袑⑹钩绦虻牟季指忧逦?。在每個函數(shù)定義結(jié)束之后都要加空行(兩個函數(shù)之間建議添加兩個以上的空行)。隔關(guān)系不是很大的代碼段。大括號在C語言中,大括號“{}”是一類比較特殊的符號。如果能夠在適當?shù)牡胤嚼盟墒勾a看起來非常整潔,也能夠從側(cè)面看出一個編程人員的專業(yè)素養(yǎng)。那么,在C語言中,大括號應(yīng)該用在哪些地方呢?初始化數(shù)組變量在實際的軟件開發(fā)項目中,變量在使用前應(yīng)初始化,防止未經(jīng)初始化的變量被引用。對于數(shù)組變量來說,恰當?shù)某跏蓟瘶永缦拢篶harszString[100]={0};定義了一個名為szString的包含100個字節(jié)的數(shù)組變量,并將該數(shù)組中每個變量的初始值賦為0。定義和初始化結(jié)構(gòu)體變量結(jié)構(gòu)體變量的定義方法樣例如下:typedefstruct{……}T_Struct;該結(jié)構(gòu)體變量的初始化樣例如下:T_StructtStruct={0};很多開發(fā)人員都不注重對結(jié)構(gòu)體變量進行初始化,這是不對的。要牢記的是,任何變量在使用前,都應(yīng)進行初始化。用在if、else、elseif、for、while、do等語句中在實際的軟件開發(fā)項目中,if、else、elseif、for、while、do等語句用得較多,對這些語句的書寫要求如下。自占一行,執(zhí)行語句不得緊跟其后。不論執(zhí)行語句有多少都要加這樣做的目的是便于閱讀,同時也有利于代碼的維護。假設(shè)定義了兩個整型變量iIntVal1和iIntVal2,如果iIntVal1的值小于iIntVa2,那么就將iIntVal2的值賦給iIntVal1,則正反示例為:反例:if(iIntVal1<iIntVal2)iIntVal1=iIntVal2;這樣寫出來的程序可讀性很差,不利于對流程的跟蹤及對版本的維護。正例:if(iIntVal1<iIntVal2){iIntVal1=iIntVal2;}該代碼和反例中的代碼相比,簡潔清晰,讓人一目了然。程序的分界符“{”和“}”齊。之內(nèi)的代碼塊使用縮進規(guī)則對齊(一般縮進4個空格)。同樣以兩個整型變量iIntVal1和iIntVal2的比較來說明,正例如上面(1)所示。反例:if(iIntVal1<iIntVal2){iIntVal1=iIntVal2;}該代碼看起來給人一種很凌亂的感覺,不便于閱讀和維護。用在switch語句中switch語句也經(jīng)常出現(xiàn)在產(chǎn)品代碼中,要想寫出邏輯清晰、可閱讀性強的switch語句,需要遵循以下規(guī)則。一定要加上default分支,即使case分支已經(jīng)將全部情況都包括了。這樣做是為了防止其他代碼閱讀者誤以為漏寫了default分支,也可表現(xiàn)出開發(fā)人員思維的全面性。一個case分支和default分支要用括起來,中的內(nèi)容需要縮進(一般縮進4個空格)。這樣做可使程序邏輯清晰,可讀性更好。假設(shè)定義了一個整型變量iSwitchFlag,可取值1、2、3,用switch語句對每種可取值的情況分別進行處理,則正反示例為:反例:switch(iSwitchFlag){ //“{”沒有和switch對齊case1: //“case”沒有縮進{ //“{”沒有和case對齊DoSomething1(); //縮進空格數(shù)太多break; //“break;”沒有和上一條語句對齊} //“}”沒有和本case語句的“{”對齊case2:{DoSomething2();break;}case3:DoSomething3(); //沒有用“{}”將語句括起來,且case執(zhí)行結(jié)束后無break;//缺少了default分支}以上反例中的switch語句可讀性很差,不利于代碼的維護。正例:switch(iSwitchFlag){case1:{DoSomething1(); //縮進4個空格break;}case2:{DoSomething2(); //縮進4個空格break;}case3:{DoSomething3(); //縮進4個空格break;}default: //一定要有default分支{DoNothing();break;}}正例中的代碼邏輯清晰,有利于代碼的修改和維護。break語句要寫到“{}”如下的代碼是不規(guī)范的:switch(iSwitchFlag){case1:{DoSomething1();}break; //break語句放到了“{}”外面,不規(guī)范case2:{DoSomething2();}break;case3:{DoSomething3();}break;default:{DoNothing();}break;}用在函數(shù)中大家都知道,一個函數(shù)中的所有語句是包括在“{}”之中的。除此之外,“{}”在函數(shù)之中還有其他用武之地。分隔功能關(guān)聯(lián)不大的語句塊在某些函數(shù)中,可能包含了很多功能,但這些功能之間的關(guān)聯(lián)性很小,可以當作獨立的代碼來對待。這時,可以用“{}”將這些不同功能的代碼塊區(qū)分開來,增強代碼的可讀性,也便于對函數(shù)的維護和修改。假設(shè)有一個函數(shù)ExampleFun,包含了3個較為獨立的功能A、B和C,則可以如下組織該函數(shù)的代碼。voidExampleFun(void){//功能A代碼塊開始{//功能A的實現(xiàn)代碼}//功能A代碼塊結(jié)束//功能B代碼塊開始{//功能B的實現(xiàn)代碼}//功能B代碼塊結(jié)束//功能C代碼塊開始{//功能C的實現(xiàn)代碼}//功能C代碼塊結(jié)束}這樣的代碼具有自說明性,便于閱讀和維護。突出添加或修改的代碼在代碼行數(shù)較多的函數(shù)中,如果要添加或修改的代碼量很少,即與原本已有的代碼比起來,顯得“很渺小”。這時,可以用“{}”方便閱讀及對代碼進行走查等。同樣以函數(shù)ExampleFun為例來說明,如下所示:voidExampleFun(void){…………//修改或添加代碼塊開始{//修改或添加的代碼}//修改或添加代碼塊結(jié)束…………}這樣,不管是代碼編寫者,還是代碼閱讀者,都很容易發(fā)現(xiàn)代碼的改動,閱讀或維護起來也比較的容易??偟恼f來,善于在代碼中運用“{}”,可以使得程序的樣式更加美觀。這樣也可以增強代碼的規(guī)范性,進而提高代碼質(zhì)量及工作的效率。注釋在程序中,注釋并非可有可無,軟件開發(fā)人員應(yīng)該將注釋置于與代碼等同的地位上。那么,如何正確書寫注釋呢?在C語言程序中,注釋的書寫有兩種方式,一種是用“//”來標注,一種是用“/…/”來標書寫,或?qū)Χ嘈写a進行添加、刪除時,可以采用第二種方式。方。閱讀和理解。要盡量避免在注釋中使用縮寫,特別是不常用的縮寫,以讓人產(chǎn)生疑惑。性。如果注釋不再有用,那么要刪除掉。巧妙或復(fù)雜的代碼段前要添加注釋,比較隱晦的地方要在代碼適當?shù)奈恢锰砑幼⑨尅5降资鞘褂弥形倪€是英文對代碼進行注釋呢?對于常用的代碼編輯器(如SourceInsight、MicrosoftVisualStudio等)來說,中英文的注釋均能夠正確顯示。因此,書寫注釋要遵循“內(nèi)容重于形式”的原則,要在恰當?shù)牡胤绞褂们‘數(shù)淖⑨?。小結(jié)本章從程序給人的第一印象入手,介紹了頭文件和源文件的樣式、空格、空行、大括號的使用和注釋的書寫。當我們看到排版工整、注釋規(guī)范的代碼時,會不自然地產(chǎn)生繼續(xù)讀下去的想法,這也在無形中提高了工作的效率。因此,注意程序的樣式是十分重要的。堅持不懈地努力。廣大的軟件開發(fā)工程師在提高自己編程水平的同時,也要注重編程規(guī)范,讓自己的代碼更易于閱讀和維護。第4章 變量和函數(shù)路人甲到電信營業(yè)廳去交電話費,給營業(yè)員說要充50塊錢,那個營業(yè)員問了一句“Howmuch?”于是便以不是很流利的口語說了一句“FiftyYUAN”。那個營業(yè)員一頭霧水地看著他,說道“電話號碼多少?”路人甲這才恍然大悟,原來是問我電話號碼多少,而非多少錢。不要讓別人感到疑惑。這個原理同樣適用于軟件開發(fā)過程,適用于編寫代碼的過程。我們在編寫程序的過程中,要保證自己寫的每一行代碼都表意準確,讓別人一看就能夠明白,特別是對于變量和函數(shù)的命名。某些不規(guī)范的變量命名,諸如“inti,j;”、“charc;”等,嚴重影響了工作的效率。本章首先介紹實際軟件開發(fā)項目中的數(shù)據(jù)類型,然后介紹變量和函數(shù)的命名規(guī)范,最后介紹一類特殊變量——靜態(tài)變量的使用。數(shù)據(jù)類型大家都知道,要定義一個變量是很容易的。要定義整型變量,直接用“inti;”語句就可以了;要定義字符型變量,直接用“charc;”就可以了。確實,這能夠達到定義變量的目的,但在實際工作中卻沒有這么簡單。在實際工作中,我們需要對一些基本數(shù)據(jù)類型進行重定義(規(guī)范化),才能夠滿足編程規(guī)范的要求,才能夠用于定義變量。本節(jié)以整型和字符型的重定義來進行說明。整型整型,以在內(nèi)存中占數(shù)據(jù)位數(shù)來劃分,包括短整型(shortint)、整型(int)和長整型(longint);以有無符號來劃分,包括無符號整型(unsigned)和有符號整型(signed)。各類整型的重定義規(guī)則如圖4.1所示。圖4.1 各類整型的重定義規(guī)則從圖4.1可以看出,各類整型的重定義規(guī)則如下。對于無符號短整型,其重定義為:typedefunsignedshortintUINT16;對于有符號短整型,其重定義為:typedefsignedshortintINT16;對于無符號整型,其重定義為:typedefunsignedintUINT32;對于有符號整型,其重定義為:typedefsignedintINT32;對于無符號長整型,其重定義為:typedefunsignedlongULONG;對于有符號長整型,其重定義為:typedefsignedlongLONG;通過以上重定義之后,我們就可以用UINT16、INT16、UINT32、INT32、ULONG和LONG來代替相應(yīng)的整型類型了。這里拿UINT32來說明:“U”代表“unsigned”,“INT”代表“int”,“32”表示“32位”,從這個定義一眼就可以看出這表示32位的無符號整型數(shù)據(jù)類型,如果要定義這樣的一個變量X,用“UINT32X;”語句就可以了。字符型在C語言中,字符型和整型可以相互轉(zhuǎn)換。因此,也可以用類似的辦法來重定義字符型。字符型分為有符號和無符號兩種類型,它們的重定義規(guī)則如圖4.2所示。圖4.2 各類字符型的重定義規(guī)則從圖4.2可以看出,各類字符型的重定義規(guī)則如下。對于無符號字符型,其重定義為:typedefunsignedcharUINT8;對于有符號字符型,其重定義為:typedefsignedcharINT8;由于一個字符型變量在內(nèi)存中占據(jù)一個字節(jié),因此可以用8位來表示。通過我們的重定義,也能夠很清楚地看出來。如果要定義一個無符號字符型變量Y,用“UINT8Y;”語句就可以了。在實際的開發(fā)項目中,其他數(shù)據(jù)類型的重定義也可以參照整型和字符型的重定義來完成。對基本數(shù)據(jù)類型進行重定義也就是在進行代碼編寫的規(guī)范化。在大型代碼文件中,按照這個規(guī)范編寫的程序閱讀起來比較方便,同時也易于理解,提高了工作效率,讓讀者一看到就覺得十分專業(yè)。此外,這樣做也會間接提升開發(fā)工程師在客戶心中的地位,能夠獲得他們比較好的評價。變量及函數(shù)函數(shù)是程序的核心,而變量又是函數(shù)的核心。程序的各種操作,其實就是對函數(shù)中變量進行的操作。變量及函數(shù)命名規(guī)范與否,直接影響到了代碼的質(zhì)量。因此,對變量及函數(shù)進行規(guī)范化的命名具有很重要的意義。本節(jié)以一個實際的例子來為大家展示如何命名變量和函數(shù)是恰當?shù)摹_@里用2.1節(jié)中出現(xiàn)的程序代碼為例,將該代碼按照編碼規(guī)范修改后,如下所示:/***************************************************************版權(quán)所有(C)2015,ZhouZhaoxiong。*文件名稱:example.c內(nèi)容摘要:用于示范變量和函數(shù)的規(guī)范化命名其他說明:無當前版本:V1.0作 者:周兆熊*完成日期:20150120****************************************************************/#include<stdio.h>typedefsignedintINT32; //重定義數(shù)據(jù)類型typedeffloat FLOAT; //重定義數(shù)據(jù)類FLOATProcessFactorial(INT32iInputValue); //函數(shù)聲明INT32main(void); //函數(shù)聲明/**********************************************************************功能描述:主函數(shù)輸入?yún)?shù):無輸出參數(shù):無其他說明:無修改日期 版本號 修改人 修改內(nèi)容* *20150120 V1.0 周兆熊 創(chuàng)建***********************************************************************/INT32main(void){INT32iInputValue =0;FLOATfResult =printf("inputanintegernumber:");scanf("%d",&iInputValue);fResult=ProcessFactorial(iInputValue); //調(diào)用求階乘的函數(shù)printf("%d!=%10.0f\n",iInputValue,fResult);return0;}/**********************************************************************功能描述:求一個數(shù)的階乘輸入?yún)?shù):iInputValue-輸入值輸出參數(shù):無返回值:求階乘后的結(jié)果其他說明:無修改日期 版本號 修改人 修改內(nèi)容* *20150120 V1.0 周兆熊 創(chuàng)建***********************************************************************/FLOATProcessFactorial(INT32iInputValue){FLOATfResult =0.0;//先判斷輸入值是否小于0if(iInputValue<0){printf("iInputValue<0,dataerror!");return-1;}else{if(iInputValue==0||iInputValue==1)//0和1的階乘是1{fResult=1;}else{fResult=ProcessFactorial(iInputValue-1)*iInputValue;//執(zhí)行遞歸調(diào)用}return(fResult);}}該代碼和2.1節(jié)中的代碼相比,是不是有很大的不同?有關(guān)變量和函數(shù)的命名,我們要遵循以下原則。變量命名和函數(shù)命名應(yīng)具備描述性,不要過度縮寫。變量的命名應(yīng)該使用名詞,如fResult;函數(shù)的命名應(yīng)該使用“命令性”動詞,如ProcessFactorial。不管是函數(shù)還是變量,它們的命名只有一個原則:讓讀者一眼就能夠看出它們表達的意思。如ProcessFactorial函數(shù),一看到它,就大概能夠明白這是在求階乘;iInputValue變量,表示輸入值;fResult的費心解釋。為了讓讀者看到一個變量就知道其類型,在變量的最前面,通常會有一個標識類型的字母。如iInputValue中的第一個字母“i”表示這是一個整型變量(“i”代表“int”),fResult中的第一個字母“f”表示這是一個浮點型變量(“f”代表“float”)。這樣做,也是為了更進的時間,可謂是“大家皆方便”。函數(shù)的功能要單一,不要設(shè)計多用途的函數(shù);函數(shù)體的規(guī)模要小,將函數(shù)內(nèi)的代碼行數(shù)控制在項目規(guī)定的范圍之內(nèi)。此外,要盡量避免函數(shù)帶有“記憶”該產(chǎn)生相同的輸出。懂的代碼,不是好代碼,也無法體現(xiàn)出一個編程人員的水平。對于函數(shù)的調(diào)用,需要注意以下幾點。代碼檢查工具(如Pclint)是很容易發(fā)現(xiàn)的。如果確實需要傳入該參數(shù),可使用強制數(shù)據(jù)類型轉(zhuǎn)換。對于有返回值的函數(shù),盡量在被調(diào)用的時候?qū)Ψ祷刂颠M行處理。在實際的軟件開發(fā)沒有對返回值進行處理,這是不規(guī)范的。例如,定義一個返回整型值的函數(shù)ExampleFun,如下所示:intExampleFun(…){//執(zhí)行代碼return0;}而調(diào)用代碼如下:……ExampleFun(…);……沒有考慮到返回值。規(guī)范的做法是:同樣定義一個整型變量,用于表示該函數(shù)的返回值,如下代碼所示:intiRetVal=0;……iRetVal=ExampleFun(…);……很多開發(fā)人員認為寫代碼很枯燥,其實不然。如果你每天寫出來的代碼排版不工整、變量和函數(shù)命名不規(guī)范,當然會覺得枯燥。也許你昨天寫的代碼,今天就不知道它們是什么意思了。但如果你時刻牢記編程規(guī)則,寫出“自己能夠說話的代碼”(即排版工整,變量和函數(shù)的命名很恰當),那么你就不會覺得這份工作很枯燥,反而會覺得它很有趣。這可能就是所謂的“編程境界”吧。“熟能生巧”,只有通過不斷地練習(xí),我們才能夠懂得編寫代碼的訣竅,也才能夠?qū)懙贸龊玫摹⒏哔|(zhì)量的代碼。靜態(tài)變量及其應(yīng)用在實際的軟件開發(fā)中,有一類變量非常特殊,它就是靜態(tài)變量。該變量用關(guān)鍵字static進行聲明,主要應(yīng)用于函數(shù)中。說靜態(tài)變量特殊,是因為該變量的值具有“記憶性”,即本次函數(shù)調(diào)用時使用的變量值是上一次函數(shù)執(zhí)行結(jié)束時該變量的值。該變量的重要用途之一便是生成唯一序列號。唯一序列號的形式為:“Time+N”。其中,“Time”表示時間,而“N”表示流水號,其實就是一個靜態(tài)變量的值。每次調(diào)用序列號生成函數(shù)的時候,“N”的值都不同,這樣可以保證序列號的唯一性。以下代碼展示了唯一序列號的生成過程,其中序列號的樣式為:MMDDHHMISSXXXXXX(即“月日時分秒流水號”的形式)。/**********************************************************************版權(quán)所有(C)2014,ZhouZhaoxiong。*文件名稱:SerialNo.cpp文件標識:無內(nèi)容摘要:用于演示序列號的創(chuàng)建方法其他說明:無當前版本:V1.0作 者:周兆熊*完成日期:20141122**********************************************************************/#include<afxinet.h>//數(shù)據(jù)類型typedefunsignedchar UINT8;typedefunsignedchar typedefunsignedint UINT32;typedefsigned int INT32;//時間信息結(jié)構(gòu)體typedefstruct{UINT8 second; //0-59UINT8 minute; //0-59UINT8 hour; //0-23UINT8 day; //1-31UINT8 month; //1-12UINT16year; //1994-2099UINT8 week; //1-7UINT8 Count10ms; //0-99}ClockStruc;//函數(shù)聲明voidGetCurTime(ClockStruc*pCurrentTime); //獲取當前時INT32CreateSerial(UINT8*pSerialID,UINT32iSerialSize);INT32main(void); //主函數(shù)/**********************************************************************功能描述:獲取當前時間輸入?yún)?shù):無輸出參數(shù):pCurrentTime-當前時間結(jié)構(gòu)體其他說明:無修改日期 版本號 修改人 修改內(nèi)容* *20141122 V1.0 周兆熊 創(chuàng)建**********************************************************************/voidGetCurTime(ClockStruc*pCurrentTime){SYSTEMTIMEtCurrentTime;GetLocalTime(&tCurrentTime);pCurrentTime->month =(UINT8)tCurrentTime.wMonth;pCurrentTime->day =(UINT8)tCurrentTime.wDay;pCurrentTime->hour =(UINT8)tCurrentTime.wHour;pCurrentTime->minute =(UINT8)tCurrentTime.wMinute;pCurrentTime->second =(UINT8)tCurrentTime.wSecond;pCurrentTime->week =(UINT8)tCurrentTime.wDayOfWeek;if(pCurrentTime->week==0) //表示星期天{pCurrentTime->week=7;}}/**********************************************************************功能描述:創(chuàng)建序列號輸入?yún)?shù):iSerialSize-序列號長度輸出參數(shù):pSerialID-序列號返回值:0-成功-1-失敗其他說明:序列號的樣式:MMDDHHMISS_XXXXXX修改日期 版本號 修改人 修改內(nèi)容* *20141122 V1.0 周兆熊 創(chuàng)建***********************************************************************/INT32CreateSerial(UINT8*pSerialID,UINT32iSerialSize){ClockStruc tClock ={0};**static****UINT32****iTailNum**=**0**;if(NULL==pSerialID){printf("CreateSerial:inputparameterisNULL.\n");return-1;}GetCurTime(&tClock);_snprintf((char*)pSerialID,iSerialSize,"%02d%02d%02d%02d%02d_%06d",tClock.month,tClock.day,tClock.hour,tClock.minute,tClock.second,iTailNiTailNum++;if(iTailNum>999999){iTailNum=0;}return0;}/****************************************************************功能描述:主函數(shù)輸入?yún)?shù):無輸出參數(shù):無返回值:0-執(zhí)行成功-1-執(zhí)行失敗其他說明:無修改日期 版本號 修改人 修改內(nèi)容* *20141122 V1.0 周兆熊 創(chuàng)建****************************************************************/INT32main(void){UINT32iLoopFlag =0; //該變量用于表示循環(huán)標志INT32iRetValue =0; //該變量用于表示調(diào)用CreateSerial函數(shù)返回的值UINT8szSerialID[50{0}; //該變量用于存放生成的序列號//生成10個序列號,并打印出來for(iLoopFlag=0;iLoopFlag<10;iLoopFlag++){iRetValue=CreateSerial(szSerialID,sizeof(szSerialID));if(iRetValue!=0){printf("execCreateSerialfailed.\n");return-1;}printf("第%d個序列號為:%s\n",iLoopFlag+1,szSerialID);}return0;}程序的運行結(jié)果如圖4.3所示。圖4.3 唯一序列號的生成結(jié)對于此示例程序,說明如下:在實際軟件開發(fā)項目的程序中,生成序列號中的時間會有各種不同的樣式,如“YYYYMMDDHHMISS”(年月日時分秒)、“HHMISS”(時分秒)等,這要根據(jù)實際的軟件需求來決定。GetLocalTime函數(shù)來生成序列號中的時間,該函數(shù)用來獲取當?shù)氐漠斍跋到y(tǒng)日期和時間。本程序中的流水號(即序列號中下劃線后面的部分)是用靜態(tài)變量iTailNum的。在調(diào)用CreateSerial函數(shù)的過程中,這個變量會不斷增長,在達到了最大值999999之后,又從0開始,如此周而復(fù)始。這樣設(shè)計,確保了每一個序列號的唯一性。小結(jié)看過電視劇《楚漢傳奇》的人應(yīng)該對一個場面有印象。當劉邦第一次去找項羽幫忙的時種差別移植到軟件開發(fā)上來,就是“業(yè)余”與“專業(yè)”的差別。這個比喻雖然可能有點不恰業(yè)與否的表現(xiàn)。本章介紹了數(shù)據(jù)類型,變量和函數(shù)的命名規(guī)范及靜態(tài)變量的使用。掌握了這些基礎(chǔ)知識之后,我們才能夠更加深入地學(xué)習(xí)實際軟件開發(fā)項目中的C語言知識。第5章 內(nèi)存操作在實際的軟件開發(fā)項目中,內(nèi)存操作隨處可見,這也是程序編寫的難點所在。如果內(nèi)存操作處理不好,極易造成程序崩潰,并耗費大量的時間來排查問題。本章介紹4組與內(nèi)存操作相關(guān)的函數(shù)及其用法。這4組函數(shù)是:memset和memcpy、strcat和strncat、strcpy和strncpy、strcmp和strncmp。memset和memcpymemset函數(shù)原型voidmemset(voiddest,intc,size_tcount);函數(shù)作用在MSDN中,該函數(shù)的作用描述為:Setsbufferstoaspecifiedcharacter,即:將緩存設(shè)定為一個專門的字符。對照函數(shù)原型,就是將已開辟內(nèi)存空間dest的首count個字節(jié)的值設(shè)為c。示例代碼/***************************************************************版權(quán)所有(C)2014,ZhouZhaoxiong。*文件名稱:memset.c內(nèi)容摘要:用于測試memset函數(shù)其他說明:無當前版本:V1.0作 者:周兆熊*完成日期:20141121****************************************************************/#include<string.h>#include<stdio.h>typedefsignedcharINT8; //重定義數(shù)據(jù)類型typedefsignedintINT32; //重定義數(shù)據(jù)類型/**********************************************************************功能描述:主函數(shù)輸入?yún)?shù):無輸出參數(shù):無返回值:0-執(zhí)行完成其他說明:無修改日期 版本號 修改人 修改內(nèi)容* *20141121 V1.0 周兆熊 創(chuàng)建***********************************************************************/INT32main(void){INT8szTestStr[100]="AAAAAAAAAA";printf("Theoriginalstringis:%s\n",szTestStr);memset(szTestStr,'B',5); //調(diào)用memset函數(shù)printf("Thechangedstringis:%s\n",szTestStr);return0;}該程序的輸出結(jié)果如圖5.1所示。圖5.1 memset函數(shù)的示例程序輸出結(jié)該程序?qū)⒃址那?個字符設(shè)為B。重要應(yīng)用除了對指定位置設(shè)定值之外,該函數(shù)還可以用于內(nèi)存空間初始化、內(nèi)存復(fù)制、清空一個結(jié)構(gòu)類型的變量或數(shù)組等。memcpy函數(shù)原型voidmemcpy(voiddest,constvoid*src,size_tcount);函數(shù)作用在MSDN中,該函數(shù)的作用描述為:Copiescharactersbetweenbuffers,即:在緩存之間復(fù)制字符。對照函數(shù)原型,memcpy函數(shù)用來復(fù)制src所指的內(nèi)存內(nèi)容的前count個字節(jié)到dest所指的內(nèi)存地址上。示例代碼/***************************************************************版權(quán)所有(C)2014,ZhouZhaoxiong。*文件名稱:memcpy.c內(nèi)容摘要:用于測試memcpy函數(shù)其他說明:無當前版本:V1.0作 者:周兆熊*完成日期:20141121****************************************************************/#include<string.h>#include<stdio.h>typedefsignedcharINT8; //重定義數(shù)據(jù)類型typedefsignedintINT32; //重定義數(shù)據(jù)類型/**********************************************************************功能描述:主函數(shù)輸入?yún)?shù):無輸出參數(shù):無返回值:0-執(zhí)行完成其他說明:無修改日期 版本號 修改人 修改內(nèi)容* *20141121 V1.0 周兆熊 創(chuàng)建***********************************************************************/INT32main(void){INT8szTestStr[100]="AAAAAAAAAA";INT8szCopyStr[100]="BBBBBBBBBB";printf("Theoriginalstringis:%s\n",szTestStr);memcpy(szTestStr+1,szCopyStr+5,3); //調(diào)用memcpyprintf("Thechangedstringis:%s\n",szTestStr);return0;}該程序的輸出結(jié)果如圖5.2所示。圖5.2 memcpy函數(shù)的示例程序輸出結(jié)果該程序?qū)⒃址牡诙€到第四個字符設(shè)為B。重要說明src和dest所指內(nèi)存區(qū)域不能重疊,函數(shù)返回值為指向dest的指針。在實際的開發(fā)項目中,memset與memcpy函數(shù)經(jīng)常同時使用,即先用memset函數(shù)來初始化某數(shù)組或結(jié)構(gòu)體變量,然后用memcpy函數(shù)將內(nèi)容復(fù)制到被初始化的變量中。例如,定義一數(shù)組變量szStringContent,要將“zhou”復(fù)制到szStringContent中去,則示例代碼如下:charszStringContent[1024]={0};……memset(szStringContent,0x00,sizeof(szStringContent));memcpy(szStringContent,"zhou",strlen("zhou"));……strcat和strncat在實際的軟件開發(fā)項目中,程序經(jīng)常會對字符串進行操作。為此,C函數(shù)庫中提供了一些用來對字符串進行處理的函數(shù),使用起來非常的方便。但由于字符串都有長度,如果隨意對不同的字符串進行連接和復(fù)制等操作,就可能出現(xiàn)意想不到的后果。因此,在實際開發(fā)中,十分強調(diào)對字符串處理函數(shù)進行異常保護。本節(jié)介紹strcat和strncat的使用方法,5.3節(jié)和5.4節(jié)分別介紹strcpy和strncpy、strcmp和strncmp的使用方法。strcat函數(shù)的作用是連接兩個字符數(shù)組中的字符串。在MSDN中,其定義為:char*strcat(char*strDestination,constchar*strSource);Remarks:ThestrcatfunctionappendsstrSourcetostrDestinationandterminateststrcat函數(shù)將strSource字符串拼接到strDestination后面,最后的返回值是拼裝完成之后的字符串strDestination。這里有一個問題,如果字符串strSource的長度大于strDestination數(shù)組的長度,就會出現(xiàn)數(shù)組越界的錯誤,程序就會崩潰。如下代碼所示:/***************************************************************版權(quán)所有(C)2014,ZhouZhaoxiong。*文件名稱:StrcatTest.c內(nèi)容摘要:用于測試strcat函數(shù)其他說明:無當前版本:V1.0作 者:周兆熊*完成日期:20141121****************************************************************/#include<stdio.h>#include<string.h>typedefsignedcharINT8; //重定義數(shù)據(jù)類型typedefsignedintINT32; //重定義數(shù)據(jù)類型/**********************************************************************功能描述:主函數(shù)輸入?yún)?shù):無輸出參數(shù):無返回值:0-執(zhí)行完成其他說明:無修改日期 版本號 修改人 修改內(nèi)容* *20141121 V1.0 周兆熊 創(chuàng)建***********************************************************************/INT32main(void){INT8szStrDestination[10]="Hello";INT8szStrSource[10] ="Hello123";//先打印源字符串和目的字符串printf("Thesourcestringis:%s\n",szStrSource);printf("Thedestinationstringis:%s\n",szStrDestination);strcat(szStrDestination,szStrSource); //調(diào)用strcat函數(shù)//打印拼裝完成之后的字符串printf("Thechangeddestinationstringis:%s\n",szStrDestination);return0;}在該段代碼中,szStrDestination數(shù)組的長度小于szStrSource中字符串的長度,當利用strcat函數(shù)進行字符串的連接操作時,異常就出現(xiàn)了。執(zhí)行代碼后彈出的異??蛉鐖D5.3所示。圖5.3 strcat測試程序異常提示框為了解決這個問題,在使用strcat函數(shù)之前,需要先對字符串和字符數(shù)組的長度進行比較,讓字符串函數(shù)進行安全的連接操作,即保證最終字符串的長度不超過目的字符數(shù)組的長度。按照此思路編寫的代碼如下所示:/***************************************************************版權(quán)所有(C)2014,ZhouZhaoxiong。*文件名稱:StrcatTest.c內(nèi)容摘要:用于測試strcat函數(shù)其他說明:無當前版本:V1.0作 者:周兆熊*完成日期:20141121**************
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 湘教版數(shù)學(xué)八年級下冊《4.3一次函數(shù)的圖象與性質(zhì)》聽評課記錄3
- 人教版地理八年級上冊第三章《中國的自然資源》聽課評課記錄1
- 生態(tài)管護合同(2篇)
- 環(huán)境科學(xué)崗位中介合同(2篇)
- 北師大版歷史九年級上冊第16課《殖民地獨立運動》聽課評課記錄
- 湘教版數(shù)學(xué)九年級下冊《1.2二次函數(shù)y=a^2 b c的圖象與性質(zhì)(5)》聽評課記錄4
- 北師大版歷史八年級下冊第10課《偉大的歷史轉(zhuǎn)折》聽課評課記錄
- 【部編版】道德與法治九年級下冊6.1《學(xué)無止境》聽課評課記錄
- 吉林省七年級數(shù)學(xué)下冊第7章一次方程組7.3三元一次方程組及其解法聽評課記錄1新版華東師大版
- 初三年級組工作計劃范文
- DB61∕T 1854-2024 生態(tài)保護紅線評估調(diào)整技術(shù)規(guī)范
- GA 2139-2024警用防暴臂盾
- DL∕T 5810-2020 電化學(xué)儲能電站接入電網(wǎng)設(shè)計規(guī)范
- 北京三甲中醫(yī)疼痛科合作方案
- QCT957-2023洗掃車技術(shù)規(guī)范
- 新外研版高中英語選擇性必修1單詞正序英漢互譯默寫本
- 自愿斷絕父子關(guān)系協(xié)議書電子版
- 2023年4月自考00504藝術(shù)概論試題及答案含解析
- 美麗的大自然(教案)2023-2024學(xué)年美術(shù)一年級下冊
- 成都特色民俗課件
- 花城版音樂四下-第四課-認知音樂節(jié)奏(教案)
評論
0/150
提交評論