C語(yǔ)言軟件編程經(jīng)驗(yàn)交流_第1頁(yè)
C語(yǔ)言軟件編程經(jīng)驗(yàn)交流_第2頁(yè)
C語(yǔ)言軟件編程經(jīng)驗(yàn)交流_第3頁(yè)
C語(yǔ)言軟件編程經(jīng)驗(yàn)交流_第4頁(yè)
C語(yǔ)言軟件編程經(jīng)驗(yàn)交流_第5頁(yè)
已閱讀5頁(yè),還剩63頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

C語(yǔ)言軟件編程之經(jīng)驗(yàn)交流1.這次報(bào)告比較局限于C語(yǔ)言,不會(huì)講太多其他高級(jí)語(yǔ)言比方C++,JAVA,PYTHON等等,剛進(jìn)實(shí)驗(yàn)室的學(xué)生我的建議是先學(xué)好C語(yǔ)言,掌握工程開(kāi)發(fā)中軟件的開(kāi)發(fā)目的,開(kāi)發(fā)流程,測(cè)試流程等。注意,做這個(gè)報(bào)告的目的是希望大家能夠開(kāi)發(fā)出高效的C程序,而不是讓大家開(kāi)發(fā)出復(fù)雜高難度高技巧的C程序。報(bào)告目的2.提綱一、C語(yǔ)言根底二、內(nèi)存管理三、常用技巧四、調(diào)試五、例如3.開(kāi)發(fā)軟件工欲善其事,必先利其器------?論語(yǔ)?牢牢打好根底,緊緊抓住核心,真正實(shí)現(xiàn)目的-----深入學(xué)習(xí)科學(xué)開(kāi)展觀編輯軟件:VC++6.0,VS20XX編程輔助軟件:msdn功能性輔助軟件:vcassistant,numegaboundschecker, intelvtune,sourceinsight推薦的資料:?高質(zhì)量C/C++編程指南(林銳)?、?Windows核心編程?、?linux高級(jí)程序設(shè)計(jì)?4.一、C語(yǔ)言根底在C語(yǔ)言中使用的詞匯分為六類(lèi):標(biāo)識(shí)符,關(guān)鍵字,運(yùn)算符,分隔符,常量,注釋符。1.1.1C語(yǔ)言詞匯5.標(biāo)識(shí)符只能是字母、數(shù)字、下劃線組成的字符串,并且其第一個(gè)字符必須是字母或下劃線。

以下標(biāo)識(shí)符是合法的:a,x,_3x,BOOK_1,sum5

以下標(biāo)識(shí)符是非法的:3s以數(shù)字開(kāi)頭; s*T出現(xiàn)非法字符*;-3x以減號(hào)開(kāi)頭;

〔1〕標(biāo)識(shí)符一、C語(yǔ)言根底6.在使用標(biāo)識(shí)符時(shí)注意以下幾點(diǎn):標(biāo)準(zhǔn)C不限制標(biāo)識(shí)符的長(zhǎng)度,但它受各種版本的C語(yǔ)言編譯系統(tǒng)限制,同時(shí)也受到具體機(jī)器的限制;在標(biāo)識(shí)符中,大小寫(xiě)是有區(qū)別的。例如BOOK和book是兩個(gè)不同的標(biāo)識(shí)符;標(biāo)識(shí)符雖然可由程序員隨意定義,但標(biāo)識(shí)符是用于標(biāo)識(shí)某個(gè)量的符號(hào)。因此,命名應(yīng)盡量有相應(yīng)的意義,以便閱讀理解,作到“顧名思義〞。intImgWidth;

〔1〕標(biāo)識(shí)符一、C語(yǔ)言根底7.1、匈牙利命名法:開(kāi)頭字母用變量類(lèi)型的縮寫(xiě),其余局部用變量的英文或英文的縮寫(xiě),要求單詞第一個(gè)字母大寫(xiě)。 intiMyAge;“i〞是int類(lèi)型的縮寫(xiě);

charcMyName[10];“c〞是char類(lèi)型的縮寫(xiě);

floatfManHeight;“f〞是float類(lèi)型的縮寫(xiě);2、駝峰規(guī)那么: 又叫小駝峰式命名法。

第一個(gè)單詞首字母小寫(xiě),后面其他單詞首字母大寫(xiě)。 intmyAge;

charmyName[10];

floatmanHeight;3.帕斯卡命名法: 又叫大駝峰式命名法。每個(gè)單詞的第一個(gè)字母都大寫(xiě)。

intMyAge;

charMyName[10];

floatManHeight;一、C語(yǔ)言根底8.關(guān)鍵字是由C語(yǔ)言規(guī)定的具有特定意義的字符串,通常也稱(chēng)為保存字。用戶(hù)定義的標(biāo)識(shí)符不應(yīng)與關(guān)鍵字相同。C語(yǔ)言的關(guān)鍵字分為以下幾類(lèi):〔2〕關(guān)鍵字一、C語(yǔ)言根底類(lèi)型說(shuō)明符

用于定義、說(shuō)明變量、函數(shù)或其它數(shù)據(jù)結(jié)構(gòu)的類(lèi)型。如char,short,int,double等語(yǔ)句定義符

用于表示一個(gè)語(yǔ)句的功能。如for,if,else,while,switch等。預(yù)處理命令字

用于表示一個(gè)預(yù)處理命令。如#define#pragma等。9.C語(yǔ)言中運(yùn)算符與變量,函數(shù)一起組成表達(dá)式,表示各種運(yùn)算功能。運(yùn)算符由一個(gè)或多個(gè)字符組成,如>,<=,&&等?!?〕運(yùn)算符〔4〕分隔符在C語(yǔ)言中采用的分隔符有逗號(hào)和空格兩種。一、C語(yǔ)言根底10.〔5〕常量C語(yǔ)言中使用的常量可分為數(shù)字常量、字符常量、字符串常量、符號(hào)常量、轉(zhuǎn)義字符等多種。比方char*p=“helloworld〞;C語(yǔ)言中的常量是不接受程序修改的固定值?!?〕注釋符C語(yǔ)言的注釋符是以“/*〞開(kāi)頭并以“*/〞結(jié)尾的串,C++中使用“//〞注釋所在行。一、C語(yǔ)言根底11.什么是字節(jié)對(duì)齊,為什么要字節(jié)對(duì)齊?1.1.2字節(jié)對(duì)齊一、C語(yǔ)言根底12.〔1〕什么是字節(jié)對(duì)齊?現(xiàn)代計(jì)算機(jī)中內(nèi)存空間都是按照byte劃分的,從理論上講對(duì)任何類(lèi)型的變量的訪問(wèn)可以從任何地址開(kāi)始,但實(shí)際情況是在訪問(wèn)特定變量的時(shí)候經(jīng)常在特定的內(nèi)存地址訪問(wèn),這就需要各類(lèi)型數(shù)據(jù)按照一定的規(guī)那么在空間上排列,而不是順序的一個(gè)接一個(gè)的排放,這就是對(duì)齊。一、C語(yǔ)言根底13.〔2〕為什么要字節(jié)對(duì)齊?對(duì)齊的作用和原因:各個(gè)硬件平臺(tái)對(duì)存儲(chǔ)空間的處理上有很大的不同。一些平臺(tái)對(duì)某些特定類(lèi)型的數(shù)據(jù)只能從某些特定地址開(kāi)始存取。其他平臺(tái)可能沒(méi)有這種情況,但是最常見(jiàn)的是如果不按照適合其平臺(tái)的要求對(duì)數(shù)據(jù)存放進(jìn)行對(duì)齊,會(huì)在存取效率上帶來(lái)?yè)p失。比方有些平臺(tái)每次讀都是從偶地址開(kāi)始,如果一個(gè)int型〔假設(shè)為32位〕如果存放在偶地址開(kāi)始的地方,那么一個(gè)讀周期就可以讀出,而如果存放在奇地址開(kāi)始的地方,就可能會(huì)需要2個(gè)讀周期,并對(duì)兩次讀出的結(jié)果的上下字節(jié)進(jìn)行拼湊才能得到該int數(shù)據(jù)。一、C語(yǔ)言根底14.〔3〕大小端〔例程〕在計(jì)算機(jī)系統(tǒng)中,我們是以字節(jié)為單位的,每個(gè)地址單元都對(duì)應(yīng)著一個(gè)字節(jié),一個(gè)字節(jié)為8bit。對(duì)于位數(shù)大于8位的處理器,由于存放器寬度大于一個(gè)字節(jié),那么必然存在著一個(gè)如何將多個(gè)字節(jié)安排的問(wèn)題。所謂的大端模式,是指數(shù)據(jù)的低位保存在內(nèi)存的高地址中,而數(shù)據(jù)的高位,保存在內(nèi)存的低地址中;所謂的小端模式,是指數(shù)據(jù)的低位保存在內(nèi)存的低地址中,而數(shù)據(jù)的高位保存在內(nèi)存的高地址中一、C語(yǔ)言根底15.〔3〕大小端〔例程〕寫(xiě)一個(gè)C函數(shù),假設(shè)處理器是Big_endian的,那么返回0;假設(shè)是Little_endian的,那么返回1intcheckCPU(){ unionw { inta; charb; }c; c.a=1; return(c.b==1);}一、C語(yǔ)言根底16.〔3〕大小端〔例程〕采用Little-endian模式的CPU對(duì)操作數(shù)的存放方式是從低字節(jié)到高字節(jié),而B(niǎo)ig-endian模式對(duì)操作數(shù)的存放方式是從高字節(jié)到低字節(jié)序是所有成員都從低地址開(kāi)始存放。聯(lián)合體union的存放順序是所有成員都從低地址開(kāi)始存放。一、C語(yǔ)言根底17.//作者版權(quán)版本說(shuō)明,頭文件聲明,全局變量,函數(shù)聲明,預(yù)處理塊#include<stdlib.h>#include〞global.h〞voidoutput();//子函數(shù)聲明intmain(intargc,char*argv[]){ inti,j; unsignedchar*data;//定義局部變量 //分配數(shù)據(jù)空間,分配在堆上 data=(unsignedchar*)malloc(1000*sizeof(unsignedchar)); for(i…){} //調(diào)用子函數(shù) output(); //釋放分配空間 free(data);data=NULL;}voidoutput(){…}一、C語(yǔ)言根底18.#ifndefGRAPHICS_H(作用:防止graphics.h被重復(fù)引用)

#defineGRAPHICS_H

#include....(作用:引用標(biāo)準(zhǔn)庫(kù)的頭文件)

#include...(作用:引用非標(biāo)準(zhǔn)庫(kù)的頭文件)

voidFunction1(...);(作用:全局函數(shù)聲明)

classBox(作用:類(lèi)結(jié)構(gòu)聲明)

{};

#endif1.2.1頭文件一、C語(yǔ)言根底19.在頭文件中,用ifndef/define/endif結(jié)構(gòu)產(chǎn)生預(yù)處理塊,用#include格式來(lái)引用庫(kù)的頭文件。頭文件一般由三局部?jī)?nèi)容組成:1.2.1頭文件頭文件開(kāi)頭處的版權(quán)和版本聲明;預(yù)處理塊;函數(shù)和類(lèi)結(jié)構(gòu)聲明等。一、C語(yǔ)言根底20.頭文件的主要作用在于調(diào)用庫(kù)功能,對(duì)各個(gè)被調(diào)用函數(shù)給出一個(gè)描述,其本身不包含程序的邏輯實(shí)現(xiàn)代碼,它只起描述性作用,告訴應(yīng)用程序通過(guò)相應(yīng)途徑尋找相應(yīng)功能函數(shù)的真正邏輯實(shí)現(xiàn)代碼。用戶(hù)程序只需要按照頭文件中的接口聲明來(lái)調(diào)用庫(kù)功能,編譯器會(huì)從庫(kù)中提取相應(yīng)的代碼。1.2.1頭文件一、C語(yǔ)言根底21.注意:1)在.h文件中聲明的函數(shù),如果在其對(duì)應(yīng)的.c文件中有定義,那么我們?cè)诼暶鬟@個(gè)函數(shù)時(shí),不使用extern修飾符,如果反之,那么必須顯示使用extern修飾符;2)不要在.h文件中編寫(xiě)實(shí)現(xiàn)代碼,不要#include“.c〞文件。1.2.1頭文件一、C語(yǔ)言根底22.所有全局變量盡量以g_開(kāi)頭,并且盡可能聲明成static類(lèi)型;盡量杜絕跨文件訪問(wèn)全局變量.如果確實(shí)需要在多個(gè)文件內(nèi)訪問(wèn)同一變量,應(yīng)該由該變量定義所在文件內(nèi)提供GET/PUT函數(shù)實(shí)現(xiàn);全局變量必須要有一個(gè)初始值,全局變量盡量放在一個(gè)專(zhuān)門(mén)的函數(shù)內(nèi)初始化;如調(diào)用全局變量的函數(shù)少于三個(gè),考慮改為局部變量實(shí)現(xiàn)。1.2.2謹(jǐn)慎使用全局變量一、C語(yǔ)言根底23.在實(shí)際的軟件工程中,每個(gè)人負(fù)責(zé)的可能只是一個(gè)模塊,對(duì)全局變量的使用沒(méi)有小程序那樣簡(jiǎn)單,在使用全局變量的時(shí)候更要謹(jǐn)慎,跨模塊調(diào)用的全局變量使用時(shí)都需要申請(qǐng),而且定義必須明確。1.2.2謹(jǐn)慎使用全局變量一、C語(yǔ)言根底24.voidmain(intargc,char*argv[])1.2.3main函數(shù)一、C語(yǔ)言根底命令行界面的程序,通常都需要輸入命令行參數(shù)幫助程序執(zhí)行。假定有一個(gè)可執(zhí)行程序名為test.exe。運(yùn)行該程序的的命令行如下:test.exe帶命令行參數(shù)是同一行中的附加項(xiàng):test.exe–cTEST其中–c和TEST就是命令行參數(shù)。C程序通過(guò)使用main()的參數(shù)來(lái)讀取這些附加參數(shù)。25.main(intargc,char*argv[])這個(gè)函數(shù)中兩個(gè)參數(shù)的意義:argc記錄的是命令行中輸入?yún)?shù)的數(shù)目;argv是一個(gè)擁有argc個(gè)元素的字符串?dāng)?shù)組,每個(gè)元素保存一個(gè)命令行中輸入的參數(shù)。1.2.3main函數(shù)一、C語(yǔ)言根底26.

#include<stdio.h> intmain(intargc,char*argv[]) { inti; for(i=0;i<argc;i++) { printf("Argument%dis%s.\n",i,argv[i]); } return0; }1.2.3main函數(shù)一、C語(yǔ)言根底下面的程序演示argc和argv的使用:27.Argument0ishello.exe.Argument1isa.Argument2isb.Argument3isc.Argument4isd.Argument5ise.1.2.3main函數(shù)一、C語(yǔ)言根底運(yùn)行結(jié)果:假設(shè)上述代碼編譯為hello.exe,那么運(yùn)行:hello.exeabcde28.1.2.3main函數(shù)一、C語(yǔ)言根底在這個(gè)例子中,argc的值為6,命令行一共輸入了六個(gè)參數(shù):“hello.exe〞、“a〞、“b〞、“c〞、“d〞、“e〞對(duì)應(yīng)程序輸入為:argv[0]:repeat.exe,argv[1]:a,argv[2]:b,argv[3]:c,argv[4]:dargv[5]:e需要注意的是假設(shè)輸入?yún)?shù)作為數(shù)值使用時(shí),使用atoiatof進(jìn)行字符轉(zhuǎn)換看例程29.一、C語(yǔ)言根底1.3代碼編寫(xiě)標(biāo)準(zhǔn)從書(shū)寫(xiě)清晰,便于閱讀,理解,維護(hù)的角度出發(fā),在書(shū)寫(xiě)程序時(shí)應(yīng)遵循以下規(guī)那么:一個(gè)說(shuō)明或一個(gè)語(yǔ)句占一行。if,for,while,do占一行,執(zhí)行語(yǔ)句放后面并且使用大括號(hào),多用對(duì)齊。用{}括起來(lái)的局部,通常表示了程序的某一層次結(jié)構(gòu)。{}一般與該結(jié)構(gòu)語(yǔ)句的第一個(gè)字母對(duì)齊,并單獨(dú)占一行。低一層次的語(yǔ)句或說(shuō)明可比高一層次的語(yǔ)句或說(shuō)明縮進(jìn)假設(shè)干格后書(shū)寫(xiě)。以便看起來(lái)更加清晰,增加程序的可讀性。在編程時(shí)應(yīng)力求遵循這些規(guī)那么,以養(yǎng)成良好的編程風(fēng)格。多寫(xiě)注釋?zhuān)侠淼氖褂米⑨尶梢宰屇愕某绦蚩勺x性更高。30.一、C語(yǔ)言根底另外一些編程風(fēng)格說(shuō)明:程序塊要采用縮進(jìn)風(fēng)格編寫(xiě),縮進(jìn)少使用空格鍵;對(duì)齊多使用TAB鍵,少使用空格鍵;逗號(hào)、分號(hào)只在后面加空格。inta,b,c;比較操作符,賦值操作符“=〞,“+=〞,算術(shù)操作符“+〞,“%〞,邏輯操作符“&&〞,“&〞,位域操作符“<<〞,“^〞等雙目操作符的前后加空格;31.一、C語(yǔ)言根底另外一些編程風(fēng)格說(shuō)明:“!〞,“~〞,“++〞,“--〞,“&〞〔地址運(yùn)算符〕等單目操作符前后不加空格?!?>〞,“.〞前后不加空格。p->id=pid;//“->〞指針前后不加空格if、for、while、switch等與后面的括號(hào)間應(yīng)加空格,使if等關(guān)鍵字更為突出、明顯。if(a>=b&&c>d)32.一、C語(yǔ)言根底33.一、C語(yǔ)言根底1.4命名規(guī)那么使用匈牙利命名法,標(biāo)識(shí)符應(yīng)直觀意思明確盡量使用縮寫(xiě),如intiImgWidth;不要使用大小寫(xiě)來(lái)區(qū)分變量,如intx,X;局部變量不要與全局變量同名;常量使用大寫(xiě)字母,合理使用前綴,靜態(tài)變量加前綴s_,全局變量加前綴g_。34.一、C語(yǔ)言根底1.5表達(dá)式注意優(yōu)先級(jí)的的上下以及結(jié)合順序,多使用括號(hào)確定優(yōu)先級(jí)35.一、C語(yǔ)言根底1.5表達(dá)式注意if常用的條件判斷情況:布爾變量if〔flag〕if〔!flag〕整型變量if〔flag==0〕if〔flag!=0〕浮點(diǎn)變量if〔abs〔x-0〕<1e-5〕指針變量if〔p==NULL〕if〔p!=NULL〕if語(yǔ)句36.一、C語(yǔ)言根底1.5表達(dá)式注意以下幾點(diǎn):多重循環(huán)中,盡量將循環(huán)少的放在外層循環(huán)for〔i=0;i<N;i++〕,循環(huán)執(zhí)行N次,最大執(zhí)行到i=N-1,i最后執(zhí)行完等于Nswitch的每個(gè)case都加上break,最后加上default盡量少用goto循環(huán)語(yǔ)句37.從靜態(tài)存儲(chǔ)區(qū)域分配,在程序編譯的時(shí)候就已經(jīng)分配好,整個(gè)運(yùn)行期都存在。如全局變量和static變量。從棧上創(chuàng)立,從函數(shù)創(chuàng)立開(kāi)始存在,函數(shù)結(jié)束就釋放,效率高,但是分配大小有限。如函數(shù)內(nèi)部變量。從堆上分配,也稱(chēng)動(dòng)態(tài)內(nèi)存分配。使用malloc分配,需要手動(dòng)free釋放。使用靈活,容易出問(wèn)題。C語(yǔ)言中內(nèi)存分配區(qū)域:二、內(nèi)存管理38.二、內(nèi)存管理2.1常見(jiàn)內(nèi)存錯(cuò)誤沒(méi)有分配直接使用或者分配未成功卻使用了它;沒(méi)有初始化或者歸零就直接使用〔分配內(nèi)存后系統(tǒng)默認(rèn)值不一定是0〕;使用時(shí)內(nèi)存訪問(wèn)越界,使用完忘記釋放內(nèi)存,造成內(nèi)存泄漏;對(duì)已分配內(nèi)存的指針進(jìn)行賦值操作,原來(lái)分配內(nèi)存區(qū)域喪失,內(nèi)存泄漏;釋放了內(nèi)存卻繼續(xù)使用,指針在釋放后并不是變?yōu)镹ULL,仍然指向原來(lái)地址,成為“野指針〞。39.二、內(nèi)存管理2.2指針與數(shù)組數(shù)組在棧上和靜態(tài)存儲(chǔ)區(qū)域創(chuàng)立,其地址與容量分配后不可改變,但內(nèi)容可以改變;指針的特征是“可變〞,用于分配動(dòng)態(tài)內(nèi)存區(qū)域;不能直接對(duì)數(shù)組名進(jìn)行復(fù)制和比較,使用strcpy和strcmp;指針存儲(chǔ)的是動(dòng)態(tài)內(nèi)存區(qū)域的地址,可以直接傳遞地址,當(dāng)對(duì)兩塊動(dòng)態(tài)內(nèi)存區(qū)域復(fù)制或比較時(shí)使用memcpy和memcmp;數(shù)組的大小,需要加上最后面的‘\0’,可以使用sizeof獲得;指針使用sizeof獲得的是指針變量的字節(jié)數(shù);需要注意的是當(dāng)數(shù)組作為函數(shù)參數(shù)傳遞時(shí),自動(dòng)退化為該類(lèi)型的指針。40.二、內(nèi)存管理2.2指針與數(shù)組例子:41.二、內(nèi)存管理2.3指針指針的本質(zhì)是地址,指針變量本身作為普通存放器變量被存儲(chǔ),特別是該存放器地址內(nèi)存儲(chǔ)的是另一個(gè)存放器地址,該存放器地址內(nèi)存儲(chǔ)的數(shù)據(jù)是指針指向的數(shù)據(jù)。棧maininti=200;char*p;0x123456假設(shè)已給p分配空間0x123456p=0x123456i=2000x1234560x123452100*p=1000x2021120x202116&p=0x202116&i=0x202120200棧42.二、內(nèi)存管理2.3指針malloc在堆上分配動(dòng)態(tài)內(nèi)存區(qū)域,需要指定分配區(qū)域的大小,以字節(jié)作為單位。p=(char*)malloc(1*sizeof(char)); //分配到0x123456,存儲(chǔ)在棧地址0x202116的內(nèi)存地址中 *p=100;//修改0x123456中數(shù)值為100 //free將分配的動(dòng)態(tài)內(nèi)存區(qū)域釋放 free(p); //雖然0x123456該地址被標(biāo)志為已釋放,但是p內(nèi)存儲(chǔ)的仍然是0x123456,p成為野指針 p=NULL; //將0x202116內(nèi)數(shù)據(jù)改為0x00,該地址不可訪問(wèn)malloc與free:43.二、內(nèi)存管理當(dāng)子函數(shù)中使用指針時(shí),子函數(shù)執(zhí)行結(jié)束指針沒(méi)有free掉,此時(shí)指針變量釋放了,不代表它所指向的內(nèi)存自動(dòng)釋放了。當(dāng)內(nèi)存被釋放時(shí),不代表指針不存在了或者指針成為NULL指針。需要查找程序內(nèi)存泄漏。2.3指針需要注意的幾點(diǎn):44.三、常用技巧3.1宏的使用#defineceil_div(x,y)(x+y-1)/y宏執(zhí)行的是簡(jiǎn)單的替換作用,需要注意由操作符優(yōu)先級(jí)引起的問(wèn)題,多加括號(hào)。那么a=ceil_div(b&c,sizeof(int));將被轉(zhuǎn)化為:a=(b&c

+sizeof(int)-1)/sizeof(int);由于+/-的優(yōu)先級(jí)高于&的優(yōu)先級(jí),那么上面式子等同于:a=(b&(c+sizeof(int)-1))/sizeof(int);為了防止這種情況發(fā)生,應(yīng)當(dāng)多寫(xiě)幾個(gè)括號(hào):#defineceil_div(x,y)(((x)+(y)-1)/(y))45.三、常用技巧3.1宏的使用函數(shù)變宏每行代碼最后都加行連接符“\〞,即使是空行也要加“\〞,最后一行代碼后面不需要加“\〞,每行“\〞最后不能有多余字符或者空格,返回的是最后一條語(yǔ)句的執(zhí)行結(jié)果。可以在宏函數(shù)內(nèi)定義變量,可以使用if等語(yǔ)句,可以在宏內(nèi)調(diào)用其他宏,可以使用指針。函數(shù)變宏可以加快程序運(yùn)行速度??蠢?6.三、常用技巧3.2運(yùn)行時(shí)間測(cè)量程序運(yùn)行過(guò)程中,我們經(jīng)常需要統(tǒng)計(jì)程序運(yùn)行時(shí)間。下面給出例如:#include<time.h>main(){ clock_tbegin,end; begin=clock(); end =clock(); double

duration; duration=(double)(end-begin)/CLOCKS_PER_SEC;

printf(“Timeis%2.1fseconds\n",duration); //#defineCLOCKS_PER_SEC1000 //事實(shí)上end–begin獲得的是毫秒計(jì)數(shù)}47.三、常用技巧3.2運(yùn)行時(shí)間測(cè)量Time()函數(shù)是獲得當(dāng)前系統(tǒng)時(shí)間用的,一般不用于計(jì)時(shí)。當(dāng)程序運(yùn)行時(shí)間太短時(shí),可以使用屢次執(zhí)行的方法來(lái)獲得??梢允褂酶_的運(yùn)行時(shí)間計(jì)數(shù)函數(shù):“QueryPerformanceCounter()〞“QueryPerformanceFrequency()〞48.三、常用技巧隨機(jī)數(shù)生成:#include<stdlib.h>#include<stdio.h>#include<time.h>voidmain(void){ inti;/*Seedtherandom-numbergeneratorwithcurrenttimesothat*thenumberswillbedifferenteverytimewerun.*/ srand((unsigned)time(NULL));/*Display10numbers.*/ for(i=0;i<10;i++) printf("%6d\n",rand());}Srand是產(chǎn)生偽隨機(jī)序列的種子,種子一樣產(chǎn)生的偽隨機(jī)序列一樣。RAND_MAX=0x7fffffffj=(int)(n*rand()/(RAND_MAX+1.0))產(chǎn)生一個(gè)0到n之間的隨機(jī)數(shù)49.三、常用技巧3.3文件操作文件的翻開(kāi)與關(guān)閉文件在進(jìn)行讀寫(xiě)操作之前要先翻開(kāi),使用完畢要關(guān)閉。翻開(kāi)文件實(shí)際上是建立文件的各種有關(guān)信息,并使文件指針指向該文件,以便進(jìn)行其它操作。關(guān)閉文件那么斷開(kāi)指針與文件之間的聯(lián)系,也就禁止再對(duì)該文進(jìn)行操作。在C語(yǔ)言中,文件操作都是由庫(kù)函數(shù)來(lái)完成的。 fp=fopen(“filename〞,“r〞);50.三、常用技巧對(duì)于文件使用方式有以下幾點(diǎn)說(shuō)明:文件使用方式由r,w,a,b,t,+六個(gè)字符拼成,各字符的含義是:r(read):讀w(write):寫(xiě)a(append):追加b(binary):二進(jìn)制文件+:讀和寫(xiě)凡用“r〞翻開(kāi)一個(gè)文件時(shí),該文件必須已經(jīng)存在,且只能從該文件讀出。用“w〞翻開(kāi)的文件只能向該文件寫(xiě)入。假設(shè)翻開(kāi)的文件不存在,那么以指定的文件名建立該文件,假設(shè)翻開(kāi)的文件已經(jīng)存在,那么將該文件刪去,重建一個(gè)新文件。51.三、常用技巧if((fp=fopen(“readme.txt","rb")==NULL)

{

printf("\nerroronopenc:\\hzk16file!");

exit(1);

}假設(shè)要向一個(gè)已存在的文件追加新的信息,只能用“a〞方式翻開(kāi)文件。但此時(shí)該文件必須是存在的,否那么將會(huì)出錯(cuò)。在翻開(kāi)一個(gè)文件時(shí),如果出錯(cuò),fopen將返回一個(gè)空指針值NULL。在程序中可以用這一信息來(lái)判別是否完成翻開(kāi)文件的工作,并作相應(yīng)的處理。52.三、常用技巧文件的讀寫(xiě)對(duì)文件的讀和寫(xiě)是最常用的文件操作。在C語(yǔ)言中提供了多種文件讀寫(xiě)的函數(shù):字符讀寫(xiě)函數(shù):fgetc和fputc字符串讀寫(xiě)函數(shù):fgets和fputs數(shù)據(jù)塊讀寫(xiě)函數(shù):fread和fwrite格式化讀寫(xiě)函數(shù):fscanf和fprinf行操作。53.三、常用技巧文件的讀寫(xiě)在文件內(nèi)部有一個(gè)位置指針,用來(lái)指向文件的當(dāng)前讀寫(xiě)字節(jié)。在文件翻開(kāi)時(shí),該指針總是指向文件的第一個(gè)字節(jié)。使用fgetc函數(shù)后,該位置指針將向后移動(dòng)一個(gè)字節(jié)。應(yīng)注意文件指針和文件內(nèi)部的位置指針不是一回事。文件指針是指向整個(gè)文件的,文件內(nèi)部的位置指針用以指示文件內(nèi)部的當(dāng)前讀寫(xiě)位置,每讀寫(xiě)一次,該指針系統(tǒng)自動(dòng)向后移動(dòng)。54.三、常用技巧計(jì)算文件長(zhǎng)度的程序例如longfilesize(FILE*stream){longcurpos,length;curpos=ftell(stream);fseek(stream,0L,SEEK_END);length=ftell(stream);fseek(stream,curpos,SEEK_SET);returnlength;}進(jìn)行二進(jìn)制文件讀寫(xiě)時(shí),翻開(kāi)方式后面加“b〞55.四、調(diào)試編程出現(xiàn)error時(shí),從第一個(gè)error處開(kāi)始解決錯(cuò)誤,可能是很小的書(shū)寫(xiě)錯(cuò)誤引起的。warning也需要關(guān)注,有時(shí)候會(huì)導(dǎo)致程序運(yùn)行錯(cuò)誤發(fā)生。程序出現(xiàn)BUG時(shí),單步跟蹤,查看變量,查看內(nèi)存,查看棧調(diào)用,可以邊編輯邊跟蹤。參加適宜的斷點(diǎn),使用條件斷點(diǎn)。程序調(diào)試結(jié)束后需要查找內(nèi)存泄露,標(biāo)準(zhǔn)代碼書(shū)寫(xiě)。使用assert,只有條件滿(mǎn)足才繼續(xù)向下執(zhí)行,在release下不會(huì)編譯該語(yǔ)句。程序編寫(xiě)完成不一定是完全正確的,需要進(jìn)行測(cè)試并進(jìn)行跟蹤調(diào)試。56.四、調(diào)試4.1條件斷點(diǎn)我們?cè)谡{(diào)試的時(shí)候希望程序在某個(gè)斷點(diǎn)處只有在滿(mǎn)足一定的條件下中斷,在不滿(mǎn)足條件的時(shí)候正常運(yùn)行,可以為程序調(diào)試帶來(lái)極大的便利。例如57.四、調(diào)試4.2內(nèi)存泄漏查找養(yǎng)成好的代碼寫(xiě)作標(biāo)準(zhǔn),掌握內(nèi)存管理概念,減少不標(biāo)準(zhǔn)代碼內(nèi)存泄漏可能性。是否內(nèi)存泄露:運(yùn)行可執(zhí)行文件,使用任務(wù)管理器查看內(nèi)存占用情況是否一直增加。比較簡(jiǎn)單但是顯示不一定精確。使用NumegaBounderChecker軟件查找,程序中參加exit(0)強(qiáng)制中斷,Debug至該代碼行程序異常中斷時(shí)查看內(nèi)存泄露報(bào)告。例如58.四、調(diào)試4.3watch跟蹤調(diào)試時(shí)多使用watch窗口,在watch窗口內(nèi)可以進(jìn)行有限運(yùn)算,注意watch運(yùn)算帶來(lái)的影響。例如59.四、調(diào)試4.4C程序優(yōu)化首先要確定優(yōu)化目標(biāo),然后尋找優(yōu)化方法。查找程序運(yùn)行瓶頸,使用IntelVtune查看各局部運(yùn)行時(shí)間,一步步進(jìn)行優(yōu)化?,F(xiàn)在CPU,GPU開(kāi)展方向都是多核,并行計(jì)算越來(lái)越方便,為優(yōu)化提供了更多解決方案。任務(wù)級(jí)并行,使用多線程發(fā)揮多核優(yōu)勢(shì)。指令級(jí)并行,使用MMX,SSE,SSE2等指令集。參看Vtune使用指南60.五、例如5.1軟件設(shè)計(jì)算法思想,思路清楚,注意細(xì)節(jié)質(zhì)量控制,代碼高效,風(fēng)格良好測(cè)試調(diào)試,測(cè)試全面,調(diào)試認(rèn)真軟件設(shè)計(jì)過(guò)程關(guān)鍵局部:在編寫(xiě)軟件程序之前,首先要明確你要解決的問(wèn)題,軟件只是思想的實(shí)現(xiàn),不能通過(guò)編程來(lái)獲得思想。所以在編寫(xiě)之前就需要對(duì)問(wèn)題有透徹的理解,對(duì)解決問(wèn)題的方法有清晰的思路,要考慮到可能遇到的所有問(wèn)題,同時(shí)要考慮到軟件的可靠性穩(wěn)定性等。61.五、例如5.1軟件設(shè)計(jì)在編寫(xiě)軟件程序之前,首先要明確你要解決的問(wèn)題,軟件只是思想的實(shí)現(xiàn),不能通過(guò)編程來(lái)獲得思想。所以在編寫(xiě)之前就需要對(duì)問(wèn)題有透徹的理解,對(duì)解決問(wèn)題的方法有清晰的思路,要考慮到可能

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論