版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
機(jī)器語(yǔ)言計(jì)算1+1101110000000000100000000000001010000000100000000匯編語(yǔ)言MOVAX,1101110000000000100000000ADDAX,1000001010000000100000000BASIC語(yǔ)言PRINT1+1C語(yǔ)言#include<stdio.h>main(){ printf("%d\n",1+1);}C語(yǔ)言的創(chuàng)世紀(jì)一切從一個(gè)叫“SpaceTravel”的電子游戲開(kāi)始……為了讓他的游戲能在PDP-7上運(yùn)行,KenThompson用匯編語(yǔ)言給PDP-7寫(xiě)了一個(gè)操作系統(tǒng)——UNIX匯編太不好用了,Thompson需要高級(jí)語(yǔ)言試驗(yàn)了一些高級(jí)語(yǔ)言,包括Fortran,都不理想他在BCPL基礎(chǔ)上,自己設(shè)計(jì)了一個(gè)B語(yǔ)言UNIX開(kāi)始發(fā)展,B也不夠用了DennisRitchie加入,把B改造成C開(kāi)始用C重寫(xiě)UNIXRitchie和Thompson在開(kāi)發(fā)UNIX接受美國(guó)國(guó)家技術(shù)勛章C程序設(shè)計(jì)語(yǔ)言是一種高級(jí)語(yǔ)言高級(jí)語(yǔ)言并不是“高級(jí)”,只是相對(duì)低級(jí)語(yǔ)言,在一個(gè)高的級(jí)別上進(jìn)行編程歷史悠久,戰(zhàn)勛卓著誕生于上世紀(jì)70年代初,成熟于80年代(C89),修訂與90年代(C99)很多重量級(jí)軟件都是用C寫(xiě)的上天入地,無(wú)所不能幾乎沒(méi)有不能用C寫(xiě)出來(lái)的軟件,沒(méi)有不支持C的系統(tǒng)很多流行語(yǔ)言、新生語(yǔ)言都借鑒了它的思想、語(yǔ)法從C++,到Java,再到C#,還有php等C語(yǔ)言的祖師爺
DennisM.Ritchiecs.bell-labs/who/dmr//Ritchie漫畫(huà)像Cisquirky,flawed,andanenormoussuccess.計(jì)算機(jī)基本工作過(guò)程整個(gè)過(guò)程的執(zhí)行者是硬件,但硬件是受軟件控制的編程,就是編寫(xiě)軟件,使硬件按照人的意圖工作編譯運(yùn)行編譯過(guò)程程序員(Programmer)編寫(xiě)程序源代碼(SourceCode)編譯器(Compiler)把源代碼轉(zhuǎn)換為可被計(jì)算機(jī)理解的機(jī)器代碼(MachineCode),并把機(jī)器代碼以可執(zhí)行文件(ExecutableFile)的形式保存在磁盤(pán)上軟件的運(yùn)行計(jì)算機(jī)把機(jī)器代碼讀入到內(nèi)存(Memory),由CPU運(yùn)行這些代碼,讀取輸入(Input),產(chǎn)生輸出(Output),完成程序員預(yù)定的功能編譯語(yǔ)言一種編譯語(yǔ)言對(duì)應(yīng)一種編譯器程序員按照該語(yǔ)言的語(yǔ)法編寫(xiě)程序源代碼,把自己的意圖融入到代碼中編譯器讀入源代碼,把程序員的意圖轉(zhuǎn)換成可執(zhí)行程序,供他人使用C語(yǔ)言可執(zhí)行程序編譯器解釋運(yùn)行解釋運(yùn)行過(guò)程程序員編寫(xiě)程序源代碼解釋器讀入源代碼,并執(zhí)行源代碼解釋運(yùn)行的語(yǔ)言特點(diǎn)執(zhí)行速度慢好學(xué)易用先編譯、后解釋把源代碼編譯成更容易解釋的中間代碼,然后再解釋運(yùn)行C程序設(shè)計(jì)語(yǔ)言第1章觀(guān)其大略Hello,World#include<stdio.h>main(){ printf("hello,world\n");}超級(jí)無(wú)敵考考你:
如何把“hello”和“world”分別打印在兩行?hello.c打印華氏溫度與攝氏溫度對(duì)照表計(jì)算公式:
C=(5/9)(F-32)打印華氏溫度與攝氏溫度對(duì)照表#include<stdio.h>/*對(duì)fahr=0,20,...,300
打印華氏溫度與攝氏溫度對(duì)照表*/main(){
int
fahr,celsius;
int
lower,upper,step;
lower=0;/*溫度表的下限*/
upper=300;
/*溫度表的上限*/
step=20;/*步長(zhǎng)*/
fahr
=lower;
while(fahr<=upper){
celsius=5*(fahr-32)/9;
printf("%d\t%d\n",fahr,celsius);
fahr=fahr+step;
}}fc1.c代碼風(fēng)格#include<stdio.h>/*對(duì)fahr=0,20,...,300
打印華氏溫度與攝氏溫度對(duì)照表*/main(){
int
fahr,celsius;
int
lower,upper,step;
lower=0;/*溫度表的下限*/
upper=300;
/*溫度表的上限*/
step=20;/*步長(zhǎng)*/
fahr
=lower;
while(fahr<=upper){
celsius=5*(fahr-32)/9;
printf("%d\t%d\n",fahr,celsius);
fahr=fahr+step;
}}fc1.c更簡(jiǎn)單、精確的對(duì)照表打印程序#include<stdio.h>#defineLOWER0/*表的下限*/#defineUPPER300/*表的上限*/#defineSTEP20/*步長(zhǎng)*//*打印華氏-攝氏溫度對(duì)照表*/main(){
intfahr;
for(fahr=LOWER;fahr<=UPPER;fahr=fahr+STEP) printf("%3d#%6.1f\n", fahr, (5.0/9.0)*(fahr-32));}fc2.c字符輸入輸出c=getchar()從鍵盤(pán)讀入一個(gè)字符,賦值給變量cputchar(c)把c輸出到屏幕拷貝的基本思想:
讀一個(gè)字符
while(該字符不是文件結(jié)束指示符)
輸出剛讀進(jìn)的字符
讀下一個(gè)字符拷貝(Copy)#include<stdio.h>/*用于將輸入復(fù)制到輸出的程序;第1個(gè)版本*/main(){
intc;
c=getchar();
while(c!=EOF){ putchar(c); c=getchar(); }}copy1.c一個(gè)更好的版本#include<stdio.h>/*用于將輸入復(fù)制到輸出的程序;第2個(gè)版本*/main(){
intc; while((c=getchar())!=EOF) putchar(c);}copy2.c計(jì)算行數(shù)#include<stdio.h>/*統(tǒng)計(jì)輸入的行數(shù)*/main(){ intc;
longnl; nl=0;
while((c=getchar())!=EOF) {
if(c=='\n') nl++; } printf("%d\n",nl);}counter.c加法器#include<stdio.h>/*計(jì)算輸入的兩個(gè)整數(shù)的和*/main(){
inta,b; printf("Pleaseinputtwointegers:"); scanf("%d%d",&a,&b); printf("Sum=%d\n",a+b);}add.c平均分#include<stdio.h>/*計(jì)算某科成績(jī)的平均值*/#defineTOTAL_NUMBER10/*總?cè)藬?shù)*/main(){
floatsum=0,score[TOTAL_NUMBER];
inti; printf("Input%dscores:\n",TOTAL_NUMBER);
for(i=0;i<TOTAL_NUMBER;i++) { scanf("%f",&score[i]); sum=sum+score[i]; } printf("Average=%f\n",sum/TOTAL_NUMBER);}average.c函數(shù)(Function)前面使用了系統(tǒng)提供的函數(shù):printf,scanf,getchar,putchar使用函數(shù)時(shí),我們不用知道這個(gè)函數(shù)內(nèi)部是如何運(yùn)作的,只按照我們的需要和它的參數(shù)形式調(diào)用它即可我們也可以定義自己的函數(shù)“一個(gè)程序應(yīng)該是輕靈自由的,它的函數(shù)就象串在一根線(xiàn)上的珍珠?!保ā毒幊讨馈罚﹑ower函數(shù)/*power:求底的n次冪;n>=0*/intpower(intbase,intn){ inti,p;
p=1;
for(i=1;i<=n;++i) p=p*base;
returnp;}power.cpower函數(shù)的調(diào)用(Call)#include<stdio.h>intpower(intbase,intn);/*測(cè)試power函數(shù)*/main(){
intm,n; m=power(2,1); n=power(-3,3); printf("%d%d\n",m,n);
return0;}power.c這一章我們學(xué)到了#include<stdio.h>#definemain()printf(),scanf()getchar(),putchar()<=,>=,==,!=int,long,float數(shù)組while,for,if代碼風(fēng)格注釋、縮進(jìn)、空行、命名……函數(shù)C程序設(shè)計(jì)語(yǔ)言第2章類(lèi)型、運(yùn)算符與表達(dá)式標(biāo)識(shí)符(Identifiers)用戶(hù)自定義的符號(hào)叫標(biāo)識(shí)符如變量名、函數(shù)名、宏和類(lèi)型名標(biāo)識(shí)符由字母、數(shù)字和下劃線(xiàn)組成,大小寫(xiě)敏感不可以是數(shù)字開(kāi)頭標(biāo)識(shí)符要直觀(guān),能表達(dá)它的功能下劃線(xiàn)和大小寫(xiě)通常用來(lái)增強(qiáng)可讀性variablenamevariable_name,VARIABLE_NAMEVariableName,variableName關(guān)鍵字(keyword)不可作為標(biāo)識(shí)符int,float,for,while,if等(教材164頁(yè))某些功能的變量采用習(xí)慣命名如:for語(yǔ)句所采用的循環(huán)變量習(xí)慣用i,j,k基本數(shù)據(jù)類(lèi)型(DataType)int整數(shù),在目前絕大多數(shù)機(jī)器上占4個(gè)字節(jié)TC2中是2個(gè)字節(jié)所占字節(jié)數(shù)取決于機(jī)器字長(zhǎng)float單精度浮點(diǎn)數(shù),一般是4個(gè)字節(jié)長(zhǎng)double雙精度浮點(diǎn)數(shù),一般是8個(gè)字節(jié)長(zhǎng)char字符,一般是1個(gè)字節(jié)長(zhǎng)用來(lái)表示256個(gè)ASCII字符,或者0~255的整數(shù)數(shù)據(jù)類(lèi)型修飾符shortshort
int,短整數(shù),一般2個(gè)字節(jié)長(zhǎng)。通常簡(jiǎn)寫(xiě)為shortlonglong
int,長(zhǎng)整數(shù),一般是4個(gè)字節(jié)長(zhǎng)。通常簡(jiǎn)寫(xiě)為longlong
double,高精度浮點(diǎn)數(shù),一般是10個(gè)字節(jié)長(zhǎng)。signed用來(lái)修飾char、int、short和long,說(shuō)明他們是有符號(hào)的整數(shù)(正整數(shù)、0和負(fù)整數(shù))。一般缺省都是有符號(hào)的,所以這個(gè)修飾符通常省略u(píng)nsigned用來(lái)修飾char、int、short和long,說(shuō)明他們是無(wú)符號(hào)的整數(shù)(正整數(shù)和0)超出取值范圍會(huì)怎樣?TC2中int的范圍是-32767~32767如果我們給它一個(gè)小于-32767或者大于32767的數(shù)會(huì)如何呢?現(xiàn)場(chǎng)編程測(cè)驗(yàn)……小蛇能吞下大象嗎?溢出(Overflow)造成的危害一臺(tái)安裝了Windows95/98的機(jī)器,如果連續(xù)運(yùn)行49.7天沒(méi)有重新啟動(dòng),可能死機(jī)原因:Windows自啟動(dòng)時(shí)刻起,有一個(gè)計(jì)數(shù)器,記錄系統(tǒng)已經(jīng)運(yùn)行了多少毫秒。這個(gè)計(jì)數(shù)器是個(gè)unsigned
long類(lèi)型的變量unsigned
long的最大值是:4294967295一天有24*60*60*1000=86400000毫秒4294967295/86400000=49.71026961805……當(dāng)49.7天的時(shí)候,此計(jì)數(shù)器會(huì)溢出,引起死機(jī)浮點(diǎn)數(shù)的陷阱#include<stdio.h>main(){
floatf; f=123.456;
if(f==123.456) printf("fisequalto123.456indeed.");
else printf("Infact,fisequalto%f\n",f);}運(yùn)行結(jié)果會(huì)是什么?float.c浮點(diǎn)數(shù)的陷阱float的精度低,較易發(fā)生精度帶來(lái)的相等性判斷問(wèn)題double精度高,這個(gè)問(wèn)題發(fā)生的概率小一些,但也存在解決辦法:
if(fabs(f–123.456)<1E-5)
……根據(jù)精度要求設(shè)定使用變量要注意不要對(duì)變量所占的字節(jié)數(shù)想當(dāng)然用sizeof獲得變量或者數(shù)據(jù)類(lèi)型的長(zhǎng)度用ANSIC定義的宏確定數(shù)據(jù)的表示范圍,解決溢出問(wèn)題sizeof.c常數(shù)(Constant)整型常數(shù)123、456123456123l、123L、123456l、123456L浮點(diǎn)常數(shù)123.45、456.781e-2、4.5e3123.45f、456.78F、1e-2f、4.5e3F123.45l、456.78L、1e-2l、4.5e3L八進(jìn)制與十六進(jìn)制常數(shù)以數(shù)字“0”開(kāi)始的整型常數(shù)是八進(jìn)制數(shù)010和10大小不一樣因?yàn)榘诉M(jìn)制并不常用,所以此種表示法比較少見(jiàn),因而常被用錯(cuò)以“0x”或者“0X”開(kāi)始的整型常數(shù)是十六進(jìn)制A~F和a~f用來(lái)表示十進(jìn)制的10~150x11,0x05,0xFA,0xFF十六進(jìn)制的形式比較常用,尤其在進(jìn)行位一級(jí)的控制的時(shí)候字符常數(shù)字符常數(shù)的表示方法'a','A','5','%','$'……單引號(hào)內(nèi)只能有一個(gè)字符,除非用“\”開(kāi)頭就是一個(gè)普通整數(shù),也可以參與各種數(shù)學(xué)運(yùn)算每個(gè)字符具有一個(gè)0~255之間的數(shù)值,可從ASCII表查出注意:'5'和5的區(qū)別,A和'A'的區(qū)別字符的數(shù)學(xué)運(yùn)算在密碼學(xué)內(nèi)用得比較多ascii.c字符常數(shù)轉(zhuǎn)義字符一些特殊字符(無(wú)法從鍵盤(pán)輸入或者在C語(yǔ)言里有它用)用轉(zhuǎn)義字符表示轉(zhuǎn)義的思想在網(wǎng)絡(luò)協(xié)議和文件格式中經(jīng)常使用字符串(String)常數(shù)用雙引號(hào)括住的由0個(gè)或多個(gè)字符組成的字符序列"Iamastring"""表示空字符串轉(zhuǎn)義字符也可以在字符串中使用引號(hào)只作為字符串開(kāi)始和結(jié)束的標(biāo)志C語(yǔ)言?xún)?nèi)部用'\0'表示字符串的結(jié)束除注釋外,是唯一可以出現(xiàn)中文的地方"x"和'x'是不同的<string.h>里定義了一系列專(zhuān)門(mén)的字符串處理函數(shù)枚舉(Enumeration)常數(shù)一個(gè)幾乎被遺忘的角色從程序來(lái)窺其一斑
enumweeks{MON,TUE,WED,THU,FRI,SAT,SUN};
enumweekstoday,tomorrow;
today=MON;tomorrow=today+1;
if(tomorrow==TUE)printf("TomorrowisTuesday.\n");
elseprintf("TomorrowisNOTTuesday.\n");enum.c變量聲明變量必須“先定義,后使用”所有變量必須在第一條可執(zhí)行語(yǔ)句前定義聲明的順序無(wú)關(guān)緊要一條聲明語(yǔ)句可聲明若干個(gè)同類(lèi)型的變量,變量名之間用逗號(hào)分隔變量定義后,即占用內(nèi)存,可向其存入各種數(shù)據(jù),并可通過(guò)變量名使用數(shù)據(jù)聲明變量,是初始化變量的最好時(shí)機(jī)不被初始化的變量,其值為危險(xiǎn)的隨機(jī)數(shù) charesc='\\'; inti=0; intlimit=MAXLINE+1; floateps=1.0e-5;常量用const修飾定義的變量為常量const
inti=0;常量只能在定義時(shí)賦值,然后不能再改變其值常數(shù)、常量、宏和枚舉,都可以用來(lái)表示一個(gè)永遠(yuǎn)不會(huì)改變的數(shù)前者不建議直接使用,而用后三者代替后三者的工作機(jī)理是完全不同的,達(dá)到的效果也不盡相同計(jì)算機(jī)只會(huì)計(jì)算任何事物都要被表示成數(shù)字和公式的形式后,才能被計(jì)算機(jī)計(jì)算(被計(jì)算機(jī)處理)事物到數(shù)字和公式的轉(zhuǎn)換過(guò)程叫數(shù)學(xué)建模因?yàn)椋菏挛镌谟?jì)算機(jī)內(nèi)的處理都是一種計(jì)算又因?yàn)椋河?jì)算就要有操作數(shù)、運(yùn)算法則和計(jì)算結(jié)果所以:事物在計(jì)算機(jī)內(nèi)的處理都有操作數(shù)、運(yùn)算法則和計(jì)算結(jié)果計(jì)算結(jié)果你可以留用,也可以忽略算術(shù)運(yùn)算符+,-,*,/加、減、乘、除運(yùn)算四則混合運(yùn)算中,先算乘除,后算加減,
先算左,后算右%求余運(yùn)算C語(yǔ)言中的運(yùn)算關(guān)系運(yùn)算符>,>=,<,<=,==,!=大于,大于等于,小于,小于等于,等于,不等于關(guān)系運(yùn)算符運(yùn)算出的結(jié)果為0和10,表示假,即該關(guān)系不成立1,表示真,即該關(guān)系成立在所有涉及到真假判斷的地方,0表示假,非0表示真找別扭inta=1;
if(a==0)
printf("OK");inta=0;
if(a==0)
printf("OK");inta=1;
if(a=0)
printf("OK");inta=0;
if(a=0)
printf("OK");==和=inta;
a=0;
a==1;inta;
a==0;
a=1;一定要分清==和=下面用法能起點(diǎn)小作用:inta=0;
if(0==a)
printf("OK");inta=0;
if(0=a)
printf("OK");編譯出錯(cuò)邏輯運(yùn)算符邏輯運(yùn)算也被稱(chēng)為布爾(Boolean)運(yùn)算,運(yùn)算結(jié)果也是1和0&&與運(yùn)算(a>b&&b>c);a大于b,并且b大于c||或運(yùn)算(a>b||b>c);a大于b,或者b大于c!求反(!a);如果a是0,結(jié)果非0;如果a是非0,結(jié)果是0并不改變a的值類(lèi)型轉(zhuǎn)換在進(jìn)行賦值操作時(shí),會(huì)發(fā)生類(lèi)型轉(zhuǎn)換將取值范圍小的類(lèi)型轉(zhuǎn)為取值范圍大的類(lèi)型是安全的反之是不安全的如果大類(lèi)型的值在小類(lèi)型能容納的范圍之內(nèi),則平安無(wú)事但是,浮點(diǎn)數(shù)轉(zhuǎn)為整數(shù),會(huì)丟失小數(shù)部分(非四舍五入)反之,轉(zhuǎn)換后的結(jié)果必然是錯(cuò)誤的,具體結(jié)果與機(jī)器和實(shí)現(xiàn)方式有關(guān)。避免如此使用字符串與數(shù)值類(lèi)型之間的轉(zhuǎn)換inti="123"這樣用是不行地atof(),atoi(),atol()把字符串轉(zhuǎn)為double,int和long定義在stdlib.h中sprintf()可以用來(lái)把各種類(lèi)型的數(shù)值轉(zhuǎn)為字符串定義在stdio.h中自動(dòng)類(lèi)型轉(zhuǎn)換兩個(gè)同種數(shù)據(jù)類(lèi)型的運(yùn)算結(jié)果,還是該類(lèi)型兩個(gè)不同種數(shù)據(jù)類(lèi)型的運(yùn)算結(jié)果,是兩種類(lèi)型中取值范圍更大的那種long
double>double>float>long>int>short>char只要兩者中有一個(gè)是unsigned,就都轉(zhuǎn)為unsigned再計(jì)算把數(shù)據(jù)賦值給另外一種類(lèi)型變量也會(huì)發(fā)生自動(dòng)類(lèi)型轉(zhuǎn)換從小到大,順利轉(zhuǎn)換從大到小,發(fā)出警告(好的編譯器會(huì)給出)類(lèi)型強(qiáng)轉(zhuǎn)可以通過(guò)“(類(lèi)型)表達(dá)式”的方式把表達(dá)式的值轉(zhuǎn)為任意類(lèi)型強(qiáng)轉(zhuǎn)時(shí),你必須知道你在做什么強(qiáng)轉(zhuǎn)與指針,并稱(chēng)C語(yǔ)言?xún)纱笊衿?,用好了可以呼風(fēng)喚雨,用壞了就損兵折將屠龍
刀倚天劍加一和減一運(yùn)算符i++,i--,++i,--i++讓參與運(yùn)算的變量加1,--讓參與運(yùn)算的變量減1運(yùn)算符為后綴,先取i的值,然后加/減1運(yùn)算符為前綴,先加/減1,然后取i的值在一行語(yǔ)句中,使用加1或者減1運(yùn)算的變量只能出現(xiàn)不僅可讀性差,而且因?yàn)榫幾g器實(shí)現(xiàn)的方法不同,容易導(dǎo)致不同編譯器運(yùn)行效果不一樣,貽害無(wú)窮位操作運(yùn)算符&按位與運(yùn)算|按位或運(yùn)算^按位異或運(yùn)算<<按位左移運(yùn)算>>按位右移運(yùn)算~按位求反賦值運(yùn)算符賦值運(yùn)算的結(jié)果是被賦值變量賦值后的值a=b=c=0;下面兩個(gè)語(yǔ)句是等價(jià)的i=i+2;i+=2;+、-、*、/、%、<<、>>、&、^、|運(yùn)算符都可以按此種方式處理這種形式看起來(lái)更直觀(guān),而且執(zhí)行效率一般也能更高一些條件表達(dá)式把a(bǔ)和b中的最大值放入z中if(a>b)
z=a;
else
z=b;
z=(a>b)?a:b;
此種表達(dá)式切忌用得過(guò)于繁雜優(yōu)先級(jí)()[]->.!~++--+-*&(類(lèi)型)sizeof*/%+-<<>><<=>>===!=&^|&&||?:=+=-=*=/=%=&=^=|=<<=>>=,優(yōu)先級(jí)能背下優(yōu)先級(jí)表的人鳳毛麟角腦細(xì)胞太寶貴了,不能用來(lái)死記硬背用括號(hào)來(lái)控制運(yùn)算順序更直觀(guān)、方便,并減少出錯(cuò)的概率先算乘除,后算加減,有括號(hào)就先算括號(hào)里的括號(hào)太多,有時(shí)候不清晰注意用空格做好分隔實(shí)在不行就拆分表達(dá)式C程序設(shè)計(jì)語(yǔ)言第3章控制流三種基本結(jié)構(gòu)順序結(jié)構(gòu)、選擇結(jié)構(gòu)、循環(huán)結(jié)構(gòu)已經(jīng)證明,任何程序均可只用這三種結(jié)構(gòu)實(shí)現(xiàn)B?hm,Corrado,andJacopiniGuiseppe.
"Flowdiagrams,Turingmachinesandlanguageswithonlytwoformationrules."
CommunicationofACM,9(5):366-371,May1966.只用這三種結(jié)構(gòu)的程序,叫結(jié)構(gòu)化程序程序“必須”符合結(jié)構(gòu)化規(guī)則流程圖順序結(jié)構(gòu)選擇結(jié)構(gòu)truefalsetruefalse循環(huán)結(jié)構(gòu)語(yǔ)句塊(Block){}括住的若干條語(yǔ)句構(gòu)成一個(gè)語(yǔ)句塊語(yǔ)句塊內(nèi)可以定義變量變量必須在語(yǔ)句塊的開(kāi)頭定義變量?jī)H在定義它的語(yǔ)句塊內(nèi)(包括下層語(yǔ)句塊)有效(scope.c)同一個(gè)語(yǔ)句塊內(nèi)的變量不可同名,不同語(yǔ)句塊可以同名(homonym.c)各司其職、下層優(yōu)先盡量不要在下層語(yǔ)句塊內(nèi)定義變量,也盡量不要定義同名變量語(yǔ)句塊可以用在任何可以使用語(yǔ)句的地方,但沒(méi)有道理要亂加語(yǔ)句塊if-else選擇結(jié)構(gòu)的一種最常用形式if(表達(dá)式)
語(yǔ)句塊1;
else
語(yǔ)句塊2;
語(yǔ)句塊3表達(dá)式值非0時(shí),執(zhí)行語(yǔ)句塊1,然后語(yǔ)句塊3;
表達(dá)式值為0時(shí),執(zhí)行語(yǔ)句塊2,然后語(yǔ)句塊3else部分可以沒(méi)有。當(dāng)表達(dá)式值為0時(shí),直接執(zhí)行語(yǔ)句3if-else嵌套使用時(shí),注意else和誰(shuí)配套的問(wèn)題if.c表達(dá)式!=0?YN語(yǔ)句塊1語(yǔ)句塊2語(yǔ)句塊3else-ifif的一種擴(kuò)展if(表達(dá)式1)
語(yǔ)句塊1;
elseif(表達(dá)式2)
語(yǔ)句塊2;
elseif(表達(dá)式3)
語(yǔ)句塊3;
…………
else
語(yǔ)句塊4;
語(yǔ)句塊5;else部分可以沒(méi)有表達(dá)式1!=0?YN語(yǔ)句塊1語(yǔ)句塊2語(yǔ)句塊5表達(dá)式2!=0?表達(dá)式3!=0?語(yǔ)句塊3N語(yǔ)句塊4NYYswitch多路選擇switch(表達(dá)式){
case
整型常數(shù)1:
語(yǔ)句1;
case
整型常數(shù)2:
語(yǔ)句2;
…………
default:
語(yǔ)句3;
}default可以沒(méi)有現(xiàn)場(chǎng)編程完成計(jì)算器……不要忘記breakswitch和else-if的比較else-if比switch的條件控制更強(qiáng)大一些else-if可以依照各種邏輯運(yùn)算的結(jié)果進(jìn)行流程控制switch只能進(jìn)行==判斷,并且只能是整數(shù)判斷switch比else-if更清晰兩者都要盡量避免用得過(guò)多、過(guò)長(zhǎng),尤其不要嵌套得太多它們大大增加程序的分支,使邏輯關(guān)系顯得混亂,不易維護(hù),易出錯(cuò)循環(huán)——while,forwhile(表達(dá)式)
語(yǔ)句塊;for(表達(dá)式1;表達(dá)式2;表達(dá)式3)
語(yǔ)句塊;whilewhile(表達(dá)式)
語(yǔ)句塊1;
語(yǔ)句塊2;只要表達(dá)式的值為非0,就重復(fù)執(zhí)行語(yǔ)句塊1,直到表達(dá)式值為0時(shí)止,開(kāi)始執(zhí)行語(yǔ)句塊2表達(dá)式!=0?YN語(yǔ)句塊1語(yǔ)句塊2forfor(表達(dá)式1;表達(dá)式2;表達(dá)式3)
語(yǔ)句塊;首先執(zhí)行表達(dá)式1。如果表達(dá)式2的值為非0,就重復(fù)執(zhí)行語(yǔ)句塊和表達(dá)式3,直到表達(dá)式2的值為0時(shí)止相當(dāng)于:
表達(dá)式1;
while(表達(dá)式2){
語(yǔ)句塊;
表達(dá)式3;
}for的所有表達(dá)式均可省略表達(dá)式2!=0?YN語(yǔ)句塊表達(dá)式3表達(dá)式1注意在for和while語(yǔ)句之后一般沒(méi)有分號(hào)有分號(hào)表示循環(huán)體就是分號(hào)之前的內(nèi)容,即循環(huán)體不存在while(i<100);
i++;for(i=0;i<100;i++);
printf("%d",i);for通常有一個(gè)循環(huán)變量控制循環(huán)的次數(shù),不要在循環(huán)體內(nèi)改變這個(gè)變量循環(huán)——do-whiledo
語(yǔ)句塊1;
while(表達(dá)式);
語(yǔ)句塊2;首先執(zhí)行語(yǔ)句,然后判斷表達(dá)式的值。如果表達(dá)式為0,繼續(xù)向下執(zhí)行,否則,再次執(zhí)行語(yǔ)句,再次判斷表達(dá)式的值語(yǔ)句塊1會(huì)被執(zhí)行至少一次表達(dá)式!=0?YN語(yǔ)句塊1語(yǔ)句塊2選擇三種循環(huán)的一般思路如果循環(huán)次數(shù)已知,用for如果循環(huán)次數(shù)未知,用while如果循環(huán)體至少要執(zhí)行一次,用do-while只是思路,不是定律break和continue對(duì)for、while、do-while循環(huán)進(jìn)行內(nèi)部手術(shù)break,退出循環(huán)continue,中斷此次循環(huán)的執(zhí)行,開(kāi)始下一次break和continue少用為妙它們?cè)黾恿搜h(huán)執(zhí)行的分支,break更增加了循環(huán)的出口它們可以用來(lái)處理程序異常,而盡量不要用來(lái)處理正常流程C程序設(shè)計(jì)語(yǔ)言第4章函數(shù)與程序結(jié)構(gòu)函數(shù)(function)和模塊(module)函數(shù)是C語(yǔ)言中模塊化編程的最小單位可以把每個(gè)函數(shù)看作一個(gè)模塊若干相關(guān)的函數(shù)可以合并作一個(gè)“模塊”main()printf()scanf()power()putchar()getchar()main()stdio:printf()scanf()putchar()getchar()mymdl:power()函數(shù)的分類(lèi)函數(shù)生來(lái)都是平等的,沒(méi)有高低貴賤之分,只有main()稍微特殊一點(diǎn)點(diǎn)庫(kù)函數(shù)ANSIC定義的標(biāo)準(zhǔn)庫(kù)函數(shù)符合標(biāo)準(zhǔn)的C語(yǔ)言編譯器必須提供這些函數(shù)函數(shù)的行為也要符合ANSIC的定義第三方庫(kù)函數(shù)由其它廠(chǎng)商自行開(kāi)發(fā)的C語(yǔ)言函數(shù)庫(kù)不在標(biāo)準(zhǔn)范圍內(nèi),能擴(kuò)充C語(yǔ)言的功能自定義函數(shù)自己編寫(xiě)的函數(shù)包裝后,也可成為函數(shù)庫(kù),供別人使用函數(shù)定義(definition)類(lèi)型函數(shù)名(類(lèi)型參數(shù)1,類(lèi)型參數(shù)2,……)
{
函數(shù)體;
return
表達(dá)式;
}返回值類(lèi)型標(biāo)識(shí)符參數(shù)表返回值函數(shù)出口函數(shù)定義(definition)函數(shù)是這樣的一種運(yùn)算:函數(shù)名說(shuō)明運(yùn)算規(guī)則參數(shù)是運(yùn)算的操作數(shù)返回值是運(yùn)算的結(jié)果當(dāng)函數(shù)執(zhí)行到return語(yǔ)句或}時(shí),函數(shù)的運(yùn)算停止。程序從當(dāng)次調(diào)用函數(shù)的地方繼續(xù)執(zhí)行函數(shù)可以有多個(gè)return,但最好只有一個(gè)且是最后一行用void定義返回值類(lèi)型函數(shù)沒(méi)有運(yùn)算結(jié)果,沒(méi)有返回值return語(yǔ)句之后不需要任何表達(dá)式用void定義參數(shù),表示沒(méi)有參數(shù)參數(shù)表里的參數(shù)(叫形式參數(shù),parameter)也是函數(shù)的語(yǔ)句塊內(nèi)的變量函數(shù)調(diào)用(call)函數(shù)名(表達(dá)式1,表達(dá)式2,……);調(diào)用一個(gè)函數(shù)之前,先要對(duì)其返回值類(lèi)型、函數(shù)名和參數(shù)進(jìn)行聲明(declare)不對(duì)函數(shù)進(jìn)行聲明是非常危險(xiǎn)的函數(shù)定義也有聲明函數(shù)的效果調(diào)用函數(shù)時(shí),提供的表達(dá)式(叫實(shí)際參數(shù),argument)和該函數(shù)的形式參數(shù)必須匹配數(shù)目一致類(lèi)型一一對(duì)應(yīng)(會(huì)發(fā)生自動(dòng)類(lèi)型轉(zhuǎn)換)表達(dá)式的值賦值給對(duì)應(yīng)的參數(shù)返回值可以按需處理realeql.c函數(shù)調(diào)用的過(guò)程函數(shù)的每次執(zhí)行都會(huì)建立一個(gè)全新的獨(dú)立的環(huán)境在“?!敝袨楹瘮?shù)的每個(gè)變量(包括形式參數(shù))分配內(nèi)存把實(shí)際參數(shù)的值復(fù)制給形式參數(shù)開(kāi)始執(zhí)行函數(shù)內(nèi)的第一條語(yǔ)句函數(shù)內(nèi)的代碼在這個(gè)獨(dú)立的環(huán)境內(nèi)工作函數(shù)退出時(shí)求出返回值,將其存入一個(gè)可以被調(diào)用者訪(fǎng)問(wèn)的地方(x86中通常使用EAX寄存器)收回分配給所有變量(包括形式參數(shù))的內(nèi)存程序控制權(quán)交給調(diào)用者,調(diào)用者拿到返回值,將其作為函數(shù)調(diào)用表達(dá)式的結(jié)果main()、printf()和scanf()
特殊嗎?main()C語(yǔ)言允許不對(duì)函數(shù)參數(shù)和返回值類(lèi)型進(jìn)行說(shuō)明甚至可以連函數(shù)名都不聲明此時(shí)默認(rèn)該函數(shù)的參數(shù)是不定個(gè)數(shù)的int型該函數(shù)返回值為int型永遠(yuǎn)不要利用此特性!printf()、scanf()變長(zhǎng)參數(shù)表,<stdarg.h>缺點(diǎn):對(duì)參數(shù)類(lèi)型和個(gè)數(shù)無(wú)法嚴(yán)格驗(yàn)證,易使用出錯(cuò)使用函數(shù)要注意每個(gè)函數(shù)只完成一個(gè)功能(包括main())對(duì)函數(shù)的功能可以用不含連詞的一句話(huà)描述函數(shù)不能過(guò)長(zhǎng)1986年IBM在OS/360的研究結(jié)果:大多數(shù)有錯(cuò)誤的函數(shù)都大于500行1991年對(duì)148,000行代碼的研究表明:小于143行的函數(shù)比更長(zhǎng)的函數(shù)更容易維護(hù)函數(shù)一定要對(duì)傳進(jìn)來(lái)的非法參數(shù)做點(diǎn)什么向調(diào)用者提供錯(cuò)誤信息assert()safediv.c全局變量(GlobalVariable)在所有函數(shù)之外定義的變量是全局變量,在定義它的位置以后都有效全局變量自動(dòng)初始化為0全局變量使函數(shù)之間的數(shù)據(jù)交換更容易,效率也高一些但是不推薦使用,甚至禁止使用程序的任何部分都可以改寫(xiě)全局變量,很難確定在程序的哪里改寫(xiě)了它,程序結(jié)構(gòu)混亂不得不用的時(shí)候(這種情況比較少見(jiàn)),要嚴(yán)格控制對(duì)它的改寫(xiě)靜態(tài)變量(static)函數(shù)的內(nèi)部變量在函數(shù)退出后失效(內(nèi)存釋放)。再次進(jìn)入函數(shù),變量重新定義每次函數(shù)執(zhí)行都建立一個(gè)全新的執(zhí)行環(huán)境,不受其它函數(shù)的干擾把此變量定義為static,則變量的值可以保存到下次進(jìn)入函數(shù)static
inti;靜態(tài)變量自動(dòng)初始化為0static.c遞歸(Recursion)函數(shù)直接或間接調(diào)用自己為遞歸unsigned
intfunc(unsigned
intn)
{
if(n==0)
return1;
else
returnn*func(n-1);
}recur.c模塊模塊包含兩部分源文件(xxx.c):一系列相關(guān)函數(shù)的定義頭文件(xxx.h):這些函數(shù)的聲明等必要信息函數(shù)聲明、外部變量聲明、宏定義、類(lèi)型定義……可以將模塊編譯為.obj文件,同.h文件一起供別人使用,從而保護(hù)了源代碼使用模塊的過(guò)程建立一個(gè)工程(project)把各模塊都加入到工程中#include模塊的頭文件開(kāi)始使用此模塊編寫(xiě)模塊的技術(shù)模塊的信息隱藏用static定義的函數(shù)和全局變量只在此模塊內(nèi)有效(建議采用)允許被其它模塊使用的全局變量在源文件中定義,不加static修飾在頭文件中進(jìn)行聲明,加extern修飾預(yù)編譯指令編譯器在開(kāi)始正式編譯之前處理的指令,叫預(yù)編譯指令它們不會(huì)存在于最后生成的目標(biāo)代碼中文件包含:#include用#include指定的文件內(nèi)容替換#include所在的行用<>或者""括上文件名<>表示在編譯器的include目錄內(nèi)查找文件""表示在當(dāng)前目錄查找文件文件名中可以帶有路徑#define#define
宏名字
替換文本在#define之后,所有獨(dú)立出現(xiàn)“宏名字”的地方(除了字符串內(nèi))都被“替換文本”替換“替換文本”中可以有空格宏可以有參數(shù)#definemax(A,B)((A)>(B)?(A):(B))能想出帶參數(shù)的宏和函數(shù)的區(qū)別嗎?定義宏的時(shí)候注意替換發(fā)生后產(chǎn)生的非預(yù)想結(jié)果一般用括號(hào)可以避免,如上例宏名中間不要有空格與#define配套者#undef,從現(xiàn)在開(kāi)始取消#define的定義#undefMAXLINE#if,#else,#elif,#endif#ifdef,#ifndef這些預(yù)編譯指令通常用來(lái)處理多文件工程和程序多版本的問(wèn)題。(程序多版本一般是不同平臺(tái)的版本,不同用戶(hù)等級(jí)的版本,不同開(kāi)發(fā)階段的版本等)使用預(yù)編譯指令的目的增強(qiáng)程序可讀性但是調(diào)錯(cuò)時(shí)宏可能帶來(lái)很多難題精簡(jiǎn)源代碼,提取變化這一點(diǎn)更多時(shí)候用函數(shù)的效果更好,但宏也有其不可替代的優(yōu)勢(shì)不編譯無(wú)用代碼,精煉目標(biāo)代碼C程序設(shè)計(jì)語(yǔ)言第5章指針與數(shù)組計(jì)算機(jī)內(nèi)的存儲(chǔ)部件,活動(dòng)中的所有指令和數(shù)據(jù)都保存在內(nèi)存內(nèi)速度快,但是掉電即失可以隨機(jī)訪(fǎng)問(wèn)只要指名要訪(fǎng)問(wèn)的內(nèi)存單元的地址,就可以立即訪(fǎng)問(wèn)到該單元地址是一個(gè)無(wú)符號(hào)整數(shù)(通常用16進(jìn)制數(shù)),其字長(zhǎng)與主機(jī)相同內(nèi)存中的每個(gè)字節(jié)都有唯一的一個(gè)地址內(nèi)存(RandomAccessMemory)
地址(Address)指針的故事“該程序執(zhí)行了非法操作,即將關(guān)閉”這種錯(cuò)誤幾乎全是由指針和數(shù)組導(dǎo)致的黑客攻擊服務(wù)器利用的bug絕大部分都是指針和數(shù)組造成的有些非計(jì)算機(jī)專(zhuān)業(yè)的人,盡量避免使用指針指針的故事鐵桿C/C++程序員最摯愛(ài)的武器:指針指針造就了C/C++的高效和強(qiáng)大很多不可能的任務(wù)由指針完成main(){char*a="main(){char*a=%c%s%c;printf(a,34,a,34);}";printf(a,34,a,34);}關(guān)于指針的原則學(xué)習(xí)原則一定要學(xué)會(huì)其實(shí)通常的應(yīng)用很簡(jiǎn)單就是一個(gè)變量復(fù)雜的應(yīng)用也不建議使用使用原則永遠(yuǎn)要清楚每個(gè)指針指向了哪里永遠(yuǎn)要清楚指針指向的位置是什么數(shù)組(Array)若干類(lèi)型相同的相關(guān)數(shù)據(jù)湊到一起,就是數(shù)組定義類(lèi)型數(shù)組名[整型常數(shù)1][整型常數(shù)2]……[整型常數(shù)n];inta[6][4];使用a[0][0]、a[1][2]、a[5][3]每個(gè)元素都是一個(gè)普通變量下標(biāo)可以是任意整型表達(dá)式數(shù)組的各個(gè)元素在內(nèi)存中分布在一起,分布規(guī)律是……array.c思考一下一維和三維數(shù)組怎么分布呢?從類(lèi)型的角度理解數(shù)組inta[10];定義了一個(gè)有10個(gè)int類(lèi)型元素的數(shù)組a的類(lèi)型可以看作int[10](只是看作,語(yǔ)法并不允許這么定義:int[10]a)inta[20][10];定義了一個(gè)有20個(gè)int[10]類(lèi)型元素?cái)?shù)組a[0]、a[1]……a[9]的類(lèi)型是int[10],所以a[0][0]、a[0][1]……a[19][9]的類(lèi)型是intinta[30][20][10];這個(gè)呢?這種特性決定了數(shù)組元素在內(nèi)存的分布規(guī)律,也解釋了數(shù)組的很多語(yǔ)法現(xiàn)象數(shù)組初始化數(shù)組定義后的初值仍然是隨機(jī)數(shù),一般需要我們來(lái)初始化inta[5]={12,34,56,78,9};inta[5]={0};inta[]={11,22,33,44,55};數(shù)組大小最好用宏來(lái)定義,以適應(yīng)未來(lái)可能的變化#defineSIZE10
inta[SIZE];數(shù)組的使用數(shù)組的下標(biāo)都是從0開(kāi)始對(duì)數(shù)組每個(gè)元素的使用與普通變量無(wú)異可以用任意表達(dá)式作為下標(biāo),動(dòng)態(tài)決定訪(fǎng)問(wèn)哪個(gè)元素for(i=0;i<SIZE;i++)
a[i]=2*i;下標(biāo)越界是大忌!使用大于最大下標(biāo)的下標(biāo),將訪(fǎng)問(wèn)數(shù)組以外的空間。那里的數(shù)據(jù)不是我們所想定的情況,可能帶來(lái)嚴(yán)重后果有時(shí),故意越界訪(fǎng)問(wèn)數(shù)組會(huì)起到特別效果,但一定要對(duì)自己在做什么了如指掌sizeof可以用來(lái)獲得數(shù)組所占字節(jié)數(shù)sizeof(a)sizeof(a[0])數(shù)組的用處與特點(diǎn)保存大量同類(lèi)型的相關(guān)數(shù)據(jù)快速地隨機(jī)訪(fǎng)問(wèn)一旦定義,不能再改變大小在編譯階段就確定了數(shù)組的大小數(shù)組名幾乎就是一個(gè)指針指針(Pointer)int*p;定義了一個(gè)指針變量p,簡(jiǎn)稱(chēng)指針pp是變量,int*是類(lèi)型變量都占用內(nèi)存空間,p的大小是sizeof(int*)p用來(lái)保存地址。此時(shí)這個(gè)地址是哪呢(p指向哪呢)?inti;
p=&i;*p就像普通的變量一樣使用,其值是p指向的內(nèi)存的內(nèi)容,類(lèi)型是int(在上例和i等價(jià))p可以動(dòng)態(tài)(任意)地指向不同內(nèi)存,從而使*p代表不同的變量p=0;p=&a[0];指針指針也是數(shù)據(jù)類(lèi)型。指向不同數(shù)據(jù)類(lèi)型的指針,分別為不同的數(shù)據(jù)類(lèi)型int*、float*、char*、int**、int***……指針指向非其定義時(shí)聲明的數(shù)據(jù)類(lèi)型,將引起warningvoid*類(lèi)型的指針可以指向任意類(lèi)型的變量指針在初始化時(shí)一般int*p=NULL;NULL表示空指針,即無(wú)效指針但它只是邏輯上無(wú)效,并不是真正地?zé)o效如果指針指向一個(gè)非你控制的內(nèi)存空間,并對(duì)該空間進(jìn)行訪(fǎng)問(wèn),將可能造成危險(xiǎn)&與*運(yùn)算符&運(yùn)算的結(jié)果指向該變量的指針inti,*p;
p=&i;int*p,a[10];
p=a;int*p,a[10];
p=&a[0];int*p,a[10];
p=&a[5];*和指針的組合是一個(gè)變量,該變量的地址和類(lèi)型分別是指針指向的地址和指針定義時(shí)指向的類(lèi)型inti,*p;
p=&i;
*p=0;int*p,a[10];
p=a;
*p=0;int*p,a[10];
p=&a[0];
*p=0;int*p,a[10];
p=&a[5];
*p=0;指針與數(shù)組數(shù)組名可以看作一個(gè)指針只是不能修改這個(gè)指針的指向常指針inta[10];a的類(lèi)型是int[10]a的類(lèi)型也是int*指針可當(dāng)作數(shù)組名使用,
反之亦然int*p,a[10];
p=a;
p[1]=0;
*a=0;指針運(yùn)算int*p=NULL;
p++;
/*p的值會(huì)是多少?*/指針的加減運(yùn)算是以其指向的類(lèi)型的字長(zhǎng)為單位的int*p,a[10];
p=a;*(p+3)等價(jià)于a[3]p++;
*p等價(jià)于a[1]指針運(yùn)算int*p,*q,a[10];
p=a;
q=&a[2];q-p==?q=p+3;運(yùn)算法則只能進(jìn)行加減和關(guān)系運(yùn)算只能同類(lèi)型指針之間或指針與整數(shù)之間運(yùn)算“類(lèi)型”本不存在存儲(chǔ)器在保存數(shù)據(jù)時(shí)并不關(guān)心數(shù)據(jù)的類(lèi)型完全以二進(jìn)制方式工作我們向計(jì)算機(jī)發(fā)出的指令說(shuō)明了某塊內(nèi)存里數(shù)據(jù)的類(lèi)型一塊內(nèi)存內(nèi)保存著(61626364)16以char類(lèi)型看待每個(gè)字節(jié):"abcd"以float類(lèi)型看待每個(gè)字節(jié):16777999408082104000000.000000以int類(lèi)型看待每個(gè)字節(jié):1684234849依天屠龍,強(qiáng)強(qiáng)聯(lián)手intmain(void)
{
inta[]={0,1,2,3,4,5,6,7,8};
inti;
unsigned
char*p;
p=(unsigned
char*)a;/*類(lèi)型強(qiáng)轉(zhuǎn)了*/
for(i=0;i<sizeof(a);i++)
{
PrintHexChar(p[i]);/*把指針當(dāng)數(shù)組用*/
putchar('');
}
}指針強(qiáng)轉(zhuǎn)后,可以把一塊內(nèi)存當(dāng)作另一種類(lèi)型來(lái)處理強(qiáng)強(qiáng)聯(lián)手,我們可以隨意控制任意內(nèi)存god.c指針與函數(shù)指針既然是數(shù)據(jù)類(lèi)型,自然可以做函數(shù)的參數(shù)和返回值的類(lèi)型指針做參數(shù)的經(jīng)典例子:main()
{
intx,y;
swap(x,y);
}voidswap(intx,inty)
{
inttemp;
temp=x;
x=y;
y=temp;
}NotWork指針做參數(shù)main()
{
intx,y;
swap(&x,&y);
}voidswap(int*px,int*py)
{
inttemp;
temp=*px;
*px=*py;
*py=temp;
}這里的函數(shù)調(diào)用過(guò)程還是“實(shí)參”的內(nèi)容復(fù)制到“形參”,千萬(wàn)不要理解成什么
“傳引用調(diào)用”指針做返回值printf("%s",GetInput());
......
char*GetInput(void)
{
charstr[100];
scanf("%s",str);
returnstr;
}charstring[30];
printf("%s",GetInput(string));
......
char*GetInput(char*str)
{
scanf("%s",str);
returnstr;
}√三個(gè)月使用scanf目睹之怪現(xiàn)狀inti;
scanf("%d",i);
/*這樣會(huì)如何?*/inti;
scanf("%f",&i);
/*這樣又會(huì)如何?*/charc;
scanf("%d",&c);
/*這樣呢?*/i的值被當(dāng)作地址。例如,i的值如果是100,那么輸入的整數(shù)就會(huì)從地址100開(kāi)始寫(xiě)入內(nèi)存輸入被當(dāng)作float,以float的二進(jìn)制形式寫(xiě)到i所在的內(nèi)存空間輸入以int的二進(jìn)制形式寫(xiě)到c所在的內(nèi)存空間。c所占內(nèi)存不足以放下一個(gè)int,其后的空間也被覆蓋數(shù)組做參數(shù)和指針一回事兒……voidProcessArray(int*a)
{
......
}voidProcessArray(inta[])
{
......
}這里給定元素個(gè)數(shù)有意義嗎?動(dòng)態(tài)分配內(nèi)存在<stdlib.h>和<alloc.h>中均定義了下面的函數(shù)void*malloc(size_tsize);size_t是在<stddef.h>中定義的數(shù)據(jù)類(lèi)型,就是一個(gè)unsigned
int向系統(tǒng)申請(qǐng)大小為size的內(nèi)存塊,把指向首地址的指針?lè)祷?。如果申?qǐng)不成功,返回NULLvoidfree(void*block);釋放由malloc()申請(qǐng)的內(nèi)存塊。block是指向此塊的指針malloc申請(qǐng)的內(nèi)存,在被free之前,程序的任何部分都可以使用當(dāng)然,要使用必須得到指向它的指針動(dòng)態(tài)分配內(nèi)存如果malloc()申請(qǐng)的內(nèi)存不被free()程序就退出,將產(chǎn)生內(nèi)存泄露(Memory
Leak)“內(nèi)存泄露”一詞類(lèi)似“原料泄露”。泄露出去的原料不能被利用,導(dǎo)致生產(chǎn)過(guò)程中原料不足malloc()時(shí),系統(tǒng)找到一塊未占用的內(nèi)存,將其標(biāo)記為已占用,然后把地址返回,表明此程序占用此塊內(nèi)存,其它程序不能再用它free()時(shí),系統(tǒng)標(biāo)記此塊內(nèi)存為未占用,本程序不能繼續(xù)使用,所有程序可以申請(qǐng)使用如果malloc()之后不free(),此塊內(nèi)存將永遠(yuǎn)不會(huì)被任何程序使用,就好像這塊內(nèi)存泄露出去一樣防止內(nèi)存泄露之道在需要的時(shí)候才malloc,并盡量減少malloc的次數(shù)能用自動(dòng)變量解決的問(wèn)題,就不要用malloc來(lái)解決malloc一般在大塊內(nèi)存分配和動(dòng)態(tài)內(nèi)存分配時(shí)使用malloc本身的執(zhí)行效率就不高,所以過(guò)多的malloc會(huì)使程序性能下降可以重復(fù)利用malloc申請(qǐng)到的內(nèi)存盡量讓malloc和與之配套的free在一個(gè)函數(shù)內(nèi)盡量把malloc集中在函數(shù)的入口處,free集中在函數(shù)的出口處以上做法只能盡量降低產(chǎn)生泄露的概率。完全杜絕內(nèi)存泄露,關(guān)鍵要靠程序員的細(xì)心與責(zé)任感字符串(String)
與字符數(shù)組、字符指針字符串一串以'\0'結(jié)尾的字符在C語(yǔ)言中被看作字符串用雙引號(hào)括起的一串字符是字符串常量,C語(yǔ)言自動(dòng)為其添加‘\0’終結(jié)符"Helloworld!"把字符串常量作為表達(dá)式直接使用,得到的值是該常量的地址C語(yǔ)言并沒(méi)有為字符串提供任何專(zhuān)門(mén)的表示法,完全使用字符數(shù)組和字符指針來(lái)處理字符數(shù)組每個(gè)元素都是字符類(lèi)型的數(shù)組charstring[100];字符指針指向字符類(lèi)型的指針char*p;數(shù)組和指針可以等同看待,上面三者本質(zhì)上是一回事字符串處理函數(shù)在<string.h>中定義了若干專(zhuān)門(mén)的字符串處理函數(shù)strcpy:string
copy
char*strcpy(char*dest,const
char*src);strlen:string
lengthsize_tstrlen(const
char*s);strcat:string
combinationchar*strcat(char
*dest,constchar
*src);strcmp:string
comparisonintstrcmp(const
char*s1,const
char*s2);stricmp:string
comparison
ignoring
caseintstricmp(const
char*s1,const
char*s2);指針、數(shù)組以及其它的類(lèi)型混合基本數(shù)據(jù)類(lèi)型int、long、char、short、float、double……指針是一種數(shù)據(jù)類(lèi)型是從其它類(lèi)型派生的類(lèi)型XX類(lèi)型的指針數(shù)組也是一種數(shù)據(jù)類(lèi)型是從其它類(lèi)型派生的類(lèi)型每個(gè)元
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 除塵環(huán)保課程設(shè)計(jì)范文
- 飲用水公司課程設(shè)計(jì)
- 積木構(gòu)建課程設(shè)計(jì)教案
- 鋼屋架設(shè)計(jì)課程設(shè)計(jì)
- 鋼屋架廠(chǎng)房課程設(shè)計(jì)
- 自動(dòng)伸縮窗簾課程設(shè)計(jì)
- 銅頂吹課程設(shè)計(jì)
- 鐵路選線(xiàn)課程設(shè)計(jì) 珠河
- 防塵罩課程設(shè)計(jì)
- 網(wǎng)頁(yè)制作課程設(shè)計(jì)報(bào)告
- 深圳2024-2025學(xué)年度四年級(jí)第一學(xué)期期末數(shù)學(xué)試題
- 中考語(yǔ)文復(fù)習(xí)說(shuō)話(huà)要得體
- 中風(fēng)后認(rèn)知障礙中醫(yī)臨床路徑
- 罌粟湯_朱氏集驗(yàn)方卷十_方劑加減變化匯總
- 《我相信---楊培安》歌詞-勵(lì)志歌曲
- 做一個(gè)幸福班主任
- 初中班主任案例分析4篇
- 公司7s管理組織實(shí)施方案
- Q∕GDW 12147-2021 電網(wǎng)智能業(yè)務(wù)終端接入規(guī)范
- 仁愛(ài)英語(yǔ)單詞默寫(xiě)本(全六冊(cè))英譯漢
- 公園廣場(chǎng)綠地文化設(shè)施維修改造工程施工部署及進(jìn)度計(jì)劃
評(píng)論
0/150
提交評(píng)論