![C語言基本知識點(diǎn)_第1頁](http://file4.renrendoc.com/view/2c8ee27ba00f143ea39688433217b61f/2c8ee27ba00f143ea39688433217b61f1.gif)
![C語言基本知識點(diǎn)_第2頁](http://file4.renrendoc.com/view/2c8ee27ba00f143ea39688433217b61f/2c8ee27ba00f143ea39688433217b61f2.gif)
![C語言基本知識點(diǎn)_第3頁](http://file4.renrendoc.com/view/2c8ee27ba00f143ea39688433217b61f/2c8ee27ba00f143ea39688433217b61f3.gif)
![C語言基本知識點(diǎn)_第4頁](http://file4.renrendoc.com/view/2c8ee27ba00f143ea39688433217b61f/2c8ee27ba00f143ea39688433217b61f4.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
說在前面的話:《大學(xué)》節(jié)選
經(jīng)大學(xué)之道,在明明德,在親民,在止于至善。知止而后有定,定而后能靜,靜而后能安,安而后能慮,慮而后能得。物有本末,事有終始。知所先后,則近道矣。古之欲明明德于天下者,先治其國;欲治其國者,先齊其家;欲齊其家者,先修其身;欲修其身者,先正其心;欲正其心者,先誠其意;欲誠其意者,先致其知。致知在格物。物格而后知至,知至而后意誠,意誠而后心正,心正而后身修,身修而后家齊,家齊而后國治,國治而后天下平。80后在校大學(xué)生完成電子設(shè)計(jì)全過程(TINA7o聖4131opa228TL082)第一章C語言概述§1.1C語言岀現(xiàn)的歷史背景1.I計(jì)算機(jī)基本原理1.2計(jì)算機(jī)語言計(jì)算機(jī)語言種類極多,每天都有增加,可以適當(dāng)分類,如:通用(FORTRAN、COBOL、C、BASIC),翹(Ada、FOXPRO、LISP),敲(Basic、Pascal,Fortran,C),低級(匯編MASM,PL/M)〇依據(jù)不同問題的要求,選用不同的語言,甚至組合使用。編譯語言和解釋語言代碼效率:衡量語言效率,包括空間效率、時(shí)間效率§1.2C語言的特點(diǎn)1C語言的歷史C語言最早是由美國Bel!實(shí)驗(yàn)室設(shè)計(jì)的,主要用作UNIX系統(tǒng)的工作語言,后來發(fā)展成為ー種通用語言。C與UNIX有密切的關(guān)系,C最早是在PDP機(jī)器上用UNIX操作系統(tǒng)上開發(fā)的,后來又用C語言重寫了UNIX系統(tǒng)。C目前已經(jīng)在大型機(jī)、中型機(jī)乃至微機(jī)上得到實(shí)現(xiàn),并且有各種不同版本。其本身也處在不斷的發(fā)展之中。目前主要版本包括:MSC、TurboC、QuickC、BorlandC++、VisualC++,目前在網(wǎng)絡(luò)上廣泛使用的Java也同C語言十分類似?!?.2.2C語言的特點(diǎn)C語言簡潔,結(jié)構(gòu)清晰。i=i+l i++if(a>b)max=a; max=(a>b)?a:b;elsemax-b;fori=ltonfor(i=l;i〈=n;i++){..)next同時(shí),C語言以函數(shù)作為語言的基本結(jié)構(gòu),結(jié)構(gòu)清晰,達(dá)到模塊化、結(jié)構(gòu)化的要求C語言表達(dá)能力強(qiáng)。(運(yùn)算符豐富、數(shù)據(jù)結(jié)構(gòu)豐富、允許進(jìn)行低級操作)有些語言對公式表達(dá)能力強(qiáng),有些語言對數(shù)據(jù)庫表達(dá)能力強(qiáng),C語言通用性好,對硬件及各種資源都有良好的控制。c語言是ー種高效率編譯語言,目標(biāo)代碼質(zhì)量高,用作操作系統(tǒng)語言。UNIX中13000行系統(tǒng)編碼,除最底層有800行左右是用匯編語言寫的,其余都是用C寫的。事實(shí)上,有些匯編語言本身可以用C實(shí)現(xiàn)交叉匯編,如C-5LC-96o通用性好,可移植性強(qiáng)。由于C功能十分強(qiáng)大,不再需要針對特定機(jī)器用匯編語言進(jìn)行擴(kuò)充,加上C語言的標(biāo)準(zhǔn)化工作很好,所以在不同機(jī)器上,不同的操作系統(tǒng)上,幾乎不需要改變,在源代碼ー級是通用、兼容的。C語言的發(fā)展C、C++、VisualC、Java..Tips:http://www./TheInternationalObfuscatedCCodeContest,世界上最難懂的C編碼大賽Horton,c簡單的C程序介紹例Cl_l:main()|printf("Hello,world'n");)例Cl_2:#include<stdio.h>#include<stdlib.h>#include<conio.h>#defineTRUE1#defineFALSE0inti=0;voidput_msg(void);main(){intanswer;clrscr();printf(MDoyouwanttoseethemessage?\nH);printf(MEnter0forNo,1forYes==>n);scanf(u%d",&answer);if(answer==TRUE)put_msg();elseputs("Goodbyefornow.");)voidput_msg(void)(clrscr();for(i=0;i<=10;i++)printf("Teststring#%d.\n",i);從上例中可以看出,C程序主要結(jié)構(gòu)如下:預(yù)處理指令includedefine全程變量說明函數(shù)變量main。主函數(shù)體用戶自定義函數(shù)體C語言主要由函數(shù)組成,結(jié)構(gòu)化特性好,便于代碼共享。函數(shù)由函數(shù)說明、函數(shù)體構(gòu)成C語言總是從main。函數(shù)開始執(zhí)行,而不管main()位于程序的什么地方。C語言書寫格式自由,如main(){printf("Hello,world.\n");}但應(yīng)培養(yǎng)良好的編程習(xí)慣。C語句后面有;注解/*..*/C程序上機(jī)步驟4.1C語言版本不同操作系統(tǒng)版本(MAC、OS/2,UNIX,DOS,WINDOWS..同操作系統(tǒng)下不同公司版本TC、BC++,MSC,WatcomC.4.2TurboC特色集成環(huán)境。提供一個(gè)綜合開發(fā)環(huán)境,包括編輯、編譯、鏈接、調(diào)試。強(qiáng)大的聯(lián)機(jī)幫助功能強(qiáng)大的圖形功能目標(biāo)代碼質(zhì)量高2〇%?30%能直接嵌入?yún)R編語言能直接調(diào)用系統(tǒng)功能1.4.3TurboC使用第二章數(shù)據(jù)類型、運(yùn)算符與表達(dá)式§2.1C的數(shù)據(jù)類型§2.1.1數(shù)據(jù)類型?數(shù)據(jù)是程序的主要處理對象,語言的特征主要反映在數(shù)據(jù)類型上,如COBOL主要處理表型數(shù)據(jù),人工智能語言主要處理邏輯型數(shù)據(jù)。C語言的數(shù)據(jù)類型非常豐富,可以處理各種類型的數(shù)據(jù)。?區(qū)分?jǐn)?shù)據(jù)類型的意義:?節(jié)約內(nèi)存?小內(nèi)存數(shù)據(jù)運(yùn)行速度快§2.1.2C語言的主要數(shù)據(jù)類型?基本類型?整型?字符型?浮點(diǎn)型?枚舉型?構(gòu)造類型數(shù)組結(jié)構(gòu)體公用體?指針類型?空類型TypeLengthRangeunsignedchar8bits0to255char8bits-128to127enum16bits-32,768to32,767unsignedint16bits0to65,535shortint16bits-32,768to32,767int16bits-32,768to32,767unsignedlong32bits0to4,294,967,295long32bits-2,147,483,648to2,147,483,647float32bits3.4*(10**-38)to3.4*(10**+38)double64bits1.7*(10**-308)to1.7*(10**+308)longdouble80bits3.4*(10**-4932)to1.1*(10**+4932)§2.2常量與變量2.1常量和符號常量程序執(zhí)行過程中不改變的量稱為常量,如3.14159,16,,:,..常量的作用主要是便于理解,便于修改和移植,如definePI3.14159defineEOF0defineTRUE1常量也可以用標(biāo)識符進(jìn)行命名,如上例中的PI、TRUE等,但符號常量不能被賦值。如下例是錯(cuò)誤的:defineDOTプDOTゴ:';常量可以是各種類型,如:整型(180)、字符型(七,)、浮點(diǎn)型(3.1415926)..常量可以是各種數(shù)制十進(jìn)制122ハ進(jìn)制0122十六進(jìn)制0x12a、0X12A§2.2.2變量?變量屬性變量類型變量名(地址)變量值?變量名用標(biāo)識符來表示,用來表示變量名、文件名等名字的有效字符序列稱為標(biāo)識符。有效字符集:0、9、a、z、A~Z、_、($)第一個(gè)字符不能是數(shù)字一般情況下,前32個(gè)字符有效(可擴(kuò)展)大小寫代表不同標(biāo)識符,如MAX!=max,習(xí)慣上用大寫表示常量,小寫表示變量。不能用關(guān)鍵詞(保留詞)作標(biāo)識符,如:while、else、typedef、include..盡量使標(biāo)識符有意義,如depth、length、color、location等,少用如:a、x、al?每個(gè)變量在使用前都必須進(jìn)行強(qiáng)制定義,“先定義,后使用”。如:intnum;floatdepth;chargender;這點(diǎn)與BASIC中有默認(rèn)定義不同。變量定義的意義在于:合理分配內(nèi)存防止非法運(yùn)算,如floata,b,c;c=a%b;防止誤寫變量名例C2_l#include<stdio.h>voidmain()(intlower,upper,step;floatfahr,Celsius;lower=0;upper=300;step=20;fahr=lower;while(fahr<=upper)(celsius=(5.0/9.0)*(fahr-32.O);printf("%4.0f%6.1f\n",fahr,Celsius);fahr=fahr+step;)}該例子可簡化為例C2_2:#include<stdio.h>voidmain(){floatfahr,Celsius;for(fahr=0;fahr<=300;fahr+=20)celsius=(5.0/9.0)*(fahr-32.0);printf("%4.0f%6.1f\n",fahr,Celsius);))還可簡化為例C2_3:#include<stdio.h>voidmain()(floatfahr;for(fahr=0;fahr<=300;fahr+=20)printf("%4.0f%6.1f\n",fahr,(5.0/9.0)*(fahr-32.0));)§2.3整型數(shù)據(jù)§2.3.I整型常量十進(jìn)制整數(shù)dddハ進(jìn)制整數(shù)Oddd十六進(jìn)制整數(shù)Oxddd可以加長整數(shù)后綴L或1§2.3.2整型變量基本型int短整型shortint、short長整型!ongint、long無符號型unsigned例C2_4#include<stdio.h>main(){inti;i-37000;printf("i=%d\n”,i);}結(jié)果將顯示ー28536浮點(diǎn)型數(shù)據(jù).1浮點(diǎn)型常數(shù)十進(jìn)制3.〇、3.14159指數(shù)式2el5、2.0E15、3e-8指數(shù)不能小數(shù),尾數(shù)不能沒有。如3e2.4、E-5O.2浮點(diǎn)型變量float、double、!ongdouble長度分別為4、8、10字節(jié)float精度為7位有效數(shù)字,double精度為15?16位不能寫成doublefloat或!ongdoublefloat字符型數(shù)據(jù)§2.5.1字符常量可見ASCII字符,'d',飛‘,'$’不可見字符用轉(zhuǎn)義字符表不。如、n、'a、\b0見pl6表2.3注意顯示結(jié)果和打印結(jié)果可能不一致,如:printf("abcd\refgh\n");將顯示efghprintf("a\bb\n");將顯示b5.2字符變量?定義格式:char標(biāo)識符*char類型與int類型關(guān)系charcl;clゴa';cl=cl+2;printfC'nowclis%c.\n",cl);將顯示nowclisc各種輸入輸出中,經(jīng)常用到EOF符號,下面用程序檢測EOF定義:#include<stdio.h>voidmain(){charcl;cl=EOF;printf(uEOF=%d.\nM,cl);}將顯示EOF=-1ttinclude<stdio.h>main(){charcl二'a',c2='d',c3二'h';printf("'d' a'+'h'二’%c’.、n”,c2-cl+c3);}將顯示‘d'-'a'+'h'二'k'?注意,C中沒有字符串變量類型?!?.5.3字符串常量例:“Iamprogrammer,,ヽ“Iama\tprogrammerv*'和“x”不同字符串可以用字符型數(shù)組來存放。6變量賦初值例:inti;i二20;例:inta;intb;intc;->inta,b,c;例:inti=20;變量不初始化,則其值不確定。各種數(shù)據(jù)類型的混合運(yùn)算**int->unsigned->long->doubleI Ichar,short float例:ttinclude<stdio.h>main(){inta,b;floatratio;printf<Entertwonumber:");scanf("%d%d",&a,&b);ratio二a/b;printf(/zTheratiois%f.\n,z,ratio);當(dāng)輸入a=10,b=3時(shí),期望輸出為ratio=3.3333,實(shí)際輸出ratio=3.000。要改變這ー情況,要將語句改為:ratio=L0*a/b;注意,如改為:ratio=a/b*1.0:將仍然達(dá)不到效果。算術(shù)運(yùn)算符和算術(shù)表達(dá)式C運(yùn)算符簡介算術(shù)運(yùn)算符和算術(shù)表達(dá)式基本算術(shù)運(yùn)算符:+、ー、?、/、%例:5/3=1;-5/3=-1*/%->+-例:17/5%2+4=5;17/5.%2+4非法17/(int)5.%2+4=5自加減運(yùn)算符++、—不能用于常量或表達(dá)式:6++、(i+j)++例:if(c!=‘、0')n++;或++n;也能用于如cl=s[i++];c2=s[++i]不要出現(xiàn)諸如:a[i]=i++;之類的語句§2.9賦值運(yùn)算符和賦值表達(dá)式§2.9.1簡單賦值運(yùn)算?賦值操作與賦值運(yùn)算符C語言中將賦值操作作為一種運(yùn)算,和算術(shù)運(yùn)算一樣,賦值運(yùn)算也有值如:a=3.5;a=b+4;其中,a=3運(yùn)算的值為3,因此可以x=(a=3);結(jié)果x=3o這樣,賦值運(yùn)算不僅可以出現(xiàn)在賦值語句中,同樣可以出現(xiàn)在表達(dá)式中,例如:while((c=getchar())!=EOF)..?賦值運(yùn)算中的類型轉(zhuǎn)換截?cái)嗪蛿U(kuò)展§2.9.2復(fù)合賦值運(yùn)算符elop=e2==>el=elope2,例如:x+=5==>x=x+5x*=y+i==>x=x*(y+l)絕大部分二元操作符都可以和賦值運(yùn)算符構(gòu)成復(fù)合運(yùn)算符,如:+=,—=,*=,/—,%=,〉)=,くく=,&=,*=,|二可以提高編譯質(zhì)量,降低源程序復(fù)雜度,如:yyval[yypv[p3+p4]+yypv[pl+p2]]=yyvalLyypv[p3+p4]+yypv[pl+p2]]+2可以簡化成:yyval[yypv[p3+p4]+yypv[pl+p2]]+-2§2.10逗號運(yùn)算符和逗號表達(dá)式?格式:el,e2整個(gè)表達(dá)式的值是e2的值,例如:a=3*5,a*4構(gòu)成一個(gè)逗號表達(dá)式,其值為60如:Sinclude<stdio.h>main(){charoldch,ch='a';if((oldch=ch,ch='b')=='a)puts("aye");elseputs("bee");} /?結(jié)果將顯示bee*/?逗號運(yùn)算符級別是最低的。第三章最簡單的C程序設(shè)計(jì)§3.1C語句概述*C程序?源程序文件?預(yù)編譯命令?函數(shù)?說明部分?語句(執(zhí)行部分)*C語句種類?控制語句if〇?else?for()?while〇、d〇?while()continuebreakswitchgotoreturn函數(shù)調(diào)用語句,如printf("ThisisaCstatement.\n'');表達(dá)式語句,由運(yùn)算符構(gòu)成表達(dá)式,由表達(dá)式構(gòu)成語句。如x++是表達(dá)式,x++:就是語句,x+y;也是ー個(gè)語句。a=3是ー個(gè)表達(dá)式,表達(dá)式的值是3,a=3:是ー個(gè)語句??照Z句復(fù)合語句,一般用{..}括起來。2程序的三種基本結(jié)構(gòu)順序結(jié)構(gòu)選擇結(jié)構(gòu)循環(huán)結(jié)構(gòu)賦值語句*“=”是ー個(gè)賦值運(yùn)算符?賦值表達(dá)式與賦值語句。如:c=getchar();是ー個(gè)賦值語句,while((c=getchar())!=EOF)…其中c=getchar0是一個(gè)表達(dá)式,而?!=EOF也是ー個(gè)邏輯表達(dá)式,返回值為〇或1〇注意其中的c=getchar()不能寫成c=getchar();即表達(dá)式不能寫成語句。數(shù)據(jù)輸岀C語言中沒有專門的輸入輸出語句,輸入輸出操作是通過函數(shù)實(shí)現(xiàn)的。printf和scanf是標(biāo)準(zhǔn)函數(shù)庫中的兩個(gè)常用函數(shù),注意printf和scanf不是C語言的關(guān)鍵詞,不是C語言標(biāo)準(zhǔn)的組成部分。printf函數(shù)格式:printf(格式控制,輸出表列)?格式控制:格式說明,如:%d,%ld,%u1%6.3f字符,如:Thesumis,\n,\a,c=?輸出表列:表達(dá)式:2.98*3.14標(biāo)識符:sum,x格式說明%(m)(l)d%(m)(l)o%(m)(l)x%(m)(l)u%c%(-)(m)(.n)s%(~)(m)(.n)f%(-)(m)(.n)e?類型要匹配,注意非long型整數(shù)不能用long型輸出,否則將輸出錯(cuò)誤結(jié)果。如a=10;printf("%ld”,a);錯(cuò)誤。同樣,整型數(shù)不能用浮點(diǎn)型輸出。?要輸出%,可以用%%。例:#include<stdio.h>#defineformat1"%d,%o,%x,%u,%ld,%lo,%lx,%lu\n"#definevarlist(ele)ele,ele,ele,ele,ele,ele,ele,elemain()(intint_a=2;unsignedintun_b=65535;longlong_c=65535;printf("a="formatl,varlist(int_a));printf("b="format1,varlist(un_b));printf("c="formatl,varlist(long_c));輸出結(jié)果為:a=2,2,2,2,l31074,400002,388038e,65535b=-l,177777,ffff,65535,-1,37777777777,388038e,65535c=-l,O,ffff,0,65535,177777,ffff,65535putcharO函數(shù):輸出ー個(gè)字符,可以是一般字符,也可以是轉(zhuǎn)義字符。puts。函數(shù):輸出ー個(gè)字符串,例如:puts("Heilo,world");注意:puts后面不需要加へn,,因?yàn)閜uts函數(shù)自動(dòng)換行。采用puts。、putchar(),而不用printf()函數(shù),因?yàn)閜rintfO函數(shù)實(shí)現(xiàn)非常龐大,除非數(shù)值輸出或特殊格式輸出,一般盡量不用?!?.5數(shù)據(jù)輸入scanf()格式輸入函數(shù):scanf(格式控制,地址表列)scanf()中的地址表列必須是ー個(gè)地址,而不是ー個(gè)值,例如:inta;scanf(Rd”,a);/?錯(cuò)誤?/scanfぐ?%d",&a);/?正確?/格式控制可以用格式字符%(l)d、%(l)o、%⑴x、%c、%s、%(l)f、%(l)e等輸入相應(yīng)的十進(jìn)制、ハ進(jìn)制、十六進(jìn)制、字符、字符串、實(shí)數(shù)等數(shù)據(jù)〇如果在兩個(gè)格式字符之間有空格,則表示輸入的兩個(gè)數(shù)據(jù)之間可以加入任意個(gè)回車符、制表符或空格符。^include<stdio.h>main(){inta,b;scanf &a,&b);printf("%d,%d\n”,a,b);}格式控制 輸入%d%d 1213或12-13或1213%d%d 同上%d,%d 12,13%dabc%d 12abcl3如果輸入數(shù)據(jù)時(shí),遇到空格,則認(rèn)為該數(shù)據(jù)輸入完畢,例如:Sinclude<stdio.h>main(){charname[30];puts("Pleaseinputyourname");scanf("%s",name);printf("Hello,%s\n",name);)如果輸入WangZiqiang,輸出為Hello,Wanggetch()和getchar()都可以輸入ー個(gè)字符,但getch()不回顯,例如:#include<conio.h>#include<stdio.h>main(){charc;while((c=getchar())!=,q)printf("%c\n",c);)將此例中g(shù)etchar()改為getch(),并輸入abcdefgqabcdef,觀察兩種程序的輸出。第四章邏輯運(yùn)算和判斷選取控制關(guān)系運(yùn)算符和關(guān)系表達(dá)式關(guān)系運(yùn)算符及其優(yōu)先次序?關(guān)系運(yùn)算符:>、>=、く、く=、==、!=六種>、>=、く、く=、四種運(yùn)算符優(yōu)先級高于==、!=關(guān)系運(yùn)算符優(yōu)先級高于賦值運(yùn)算符關(guān)系運(yùn)算符優(yōu)先級低于算術(shù)運(yùn)算符例如:c>a+b==>c>(a+b)a>b!=c==>(a>b)!=ca==bくc==> a==(bくc) a=b>c!=cく=d==>a=((b>c)!=(c<=d))§4.1.2關(guān)系表達(dá)式?用關(guān)系運(yùn)算符連接起來的表達(dá)式就是關(guān)系表達(dá)式。如:a==6、c!=E0F、(a+b)>(c+d)?關(guān)系表達(dá)式的值:C中沒有布爾常量,關(guān)系運(yùn)算結(jié)果為真,則表達(dá)式值為1,運(yùn)算結(jié)果為假,則表達(dá)式值為〇〇代表真假的1和〇總是int型的,并且可以執(zhí)行通常的算術(shù)運(yùn)算。如:a=l;b=2;c=3,如果d=a>b==c>b,則d=0o§4.2 邏輯運(yùn)算符和邏輯表達(dá)式邏輯運(yùn)算符及其優(yōu)先級?邏輯運(yùn)算符:&&、||、!?優(yōu)先級:!-〉&&ー〉I|*&&、I優(yōu)先級高于賦值運(yùn)算符,低于關(guān)系運(yùn)算符,如:a=b>c||!d&&e=f==>a=(b〉c)||((!d)&&(e==f))§4.2.2邏輯表達(dá)式?用邏輯運(yùn)算符連接的表達(dá)式,如:5>3&a2||8<4-!0?邏輯運(yùn)算符判斷“真”的條件為“非零”*&&、丨]的操作數(shù)不一定要求同類型,但結(jié)果一定是int型的。?邏輯表達(dá)式僅在必要時(shí),オ進(jìn)行下ー步計(jì)算,因而可以縮短運(yùn)算周期。如expl丨|exp2,如已計(jì)算出exp!為"真”,則不再計(jì)算exp2;同樣,如:expl&&exp2,如果計(jì)算出expl=O,則同樣不再計(jì)算exp2?!?.3if語句§4.3.1if語句的三種形式if(表達(dá)式)語句if(表達(dá)式)語句else語句if(表達(dá)式1)語句1elseif(表達(dá)式2)語句2elseif(表達(dá)式3)語句3else語句n注意:if僅測試(表達(dá)式)是否為真,因此,if(表達(dá)式!=0)可用if(表達(dá)式)代替,例如,if(a+4)是合法的,與if(a+4!=0)同義。if語句中的語句可以是復(fù)合語句{..}。.3.2if語句的嵌套if語句可以嵌套,但由于if語句中的else是可省略部分,因此,多個(gè)if語句嵌套是,else的配套關(guān)系可能形成二義性,例如:if(n>0)for(i=0;i<=n;i++)
if(s[i]>0){}elseputs("nv=0,Error!”);事實(shí)上,else將與最近一個(gè)尚未與else配對的if聯(lián)系起來。4.3.3條件運(yùn)算符如下句子可以用條件運(yùn)算符代替:if(表の式)max二a;elsemax=b;可以用運(yùn)算符代替為:max=(表達(dá)式)?a:b;條件運(yùn)算符優(yōu)先于賦值運(yùn)算符,低于算術(shù)運(yùn)算符和關(guān)系運(yùn)算符只有賦值條件賦值語句可以用條件運(yùn)算符代替4switch語句switch后的表達(dá)式必須是整型表達(dá)式,或與整型相兼容的值,例如char型、enum型等。default可以省略,也可以出現(xiàn)在其他地方,case語句不必按照次序。例如:scanf("5d",&a);switch(a){case3:break;default:break;case5:break;case6:break;case2:break;)第五章循環(huán)控制1概述C語言中,用以實(shí)現(xiàn)循環(huán)的語句結(jié)構(gòu)包括:while(){}do{}whileOfor()gotoif2while語句*while語句格式為:while(表達(dá)式){語句}。其中,表達(dá)式為真時(shí),執(zhí)行{語句},為假時(shí),跳過語句。例如:#include<stdio.h>#defineYES1#defineNO0main(){intc,nl,nw,nc,inword;inword=NO;nl=nw=nc=0;while((c=getchar())!=EOF){++nc;if(c==,\n,)++nl;if(c==,,||c==,\n,llc==,\t,)inword=NO;elseif(inword==NO){inword=YES;++nw;})printf(,,line=%d\twords=%d\tchars=%d\n",nl,nw,nc);)?注意,while中必須包含使循環(huán)結(jié)束的語句,如上例中的c=getchar()==EOF就是結(jié)束條件。do-whiIe循環(huán)格式:do{語句}while(表達(dá)式)例如:余數(shù)問題。有一個(gè)數(shù),用3除余2,用5除余3,用7除余2。#include<stdio.h>main(){inti;i=0;do{i++;}while(i%3!=2||i%5!=3I|i%7!=2);printfi=%d\n〃,i);}結(jié)果是!=23注意,一般情況下,while和do-while是ー樣的,但do-while是非零循環(huán),而while是可零循環(huán)。見書p69例5.4循環(huán)體如果是單個(gè)語句,??梢圆灰?但加上。有助于理解。for循環(huán)語句格式:for(表達(dá)式1;表達(dá)式2;表達(dá)式3)語句,運(yùn)行過程是:表達(dá)式1;while(表達(dá)式2){語句;表達(dá)式3;例如:for(i=l;i<=100;i++)sum=sum+i;最常見的形式如:for(初值;循環(huán)結(jié)束條件;循環(huán)增量)for各部分表達(dá)式都可以省略,如for(;;;)是合法的,初值可以放到for前完成,增量可以在循環(huán)體內(nèi)完成,結(jié)束條件可以用if+break完成。例如:sum=0;for(i=l;i<=100;i++)sum=sum+i;可以變成:sum=0,i=l;for(;;){sum=sum+(i++);if(i>100)break;)甚至for語句中的循環(huán)體也可以省略,如:for(sum=0,i=l;iく=100;sum=sum+i,i++);printf("sum=%d\n”,sum);注意,其中for語句后的:代表空語句,如果沒有空語句,下ー語句將被作為循環(huán)體for語句和while語句一般可以互相替代,一般for語句較簡潔,功能也最強(qiáng),但是,如果不需要初始化,用while比較自然,如:while((c=getchar())==''||c=='\n'||c=='\t')/?skipwhitespacecharacters*/而需要初始化時(shí),用for更方便,如:for(i=0;i<N;i++)ー個(gè)綜合性的例子,此例將一個(gè)數(shù)字字符串如“-123”轉(zhuǎn)化為數(shù)字-123,并忽略數(shù)字前的空格、制表符等:ttinclude<stdio.h>main(){chars[]="-1223”;inti,n,sign;for(i=0;s[i]==>||s[i]=-\n||s[i]==\t*;i++)Tsign=l;if(s[i]=='+'I|s[i]=='-')sign=(s[i++]=='+')?1:T;for(n=0;s[i]〉='O'&&s[i]く='9';i++)n=n*10+s[i]-0*;printf("n=%d\n”,n*sign);}5break語句和continue語句*break語句作用:?使流程跳出switch結(jié)構(gòu)?使流程跳出當(dāng)前循環(huán)體*continue作用:結(jié)束本次循環(huán),繼續(xù)下一次判斷以決定是否繼續(xù)循環(huán)。例C_2〃打印!00以內(nèi)的全部素?cái)?shù)#include<stdio.h>Sinclude<math.h>#defineYES1#defineNO0main(){inti,j,sign;for(i=3;i<=100;i++){sign=YES;for(j=2:j<=sqrt(i);j++){if(i%j==O){sign=N〇:break;})if(sign=YES)printf(*%d\t*,i);例:下面程序段將跳過負(fù)數(shù)不予處理,而僅處理正數(shù)。for(i=0;i<N;i++){if(a[i]<0)
continue;§5.6goto語句格式:goto(語句標(biāo)號)使用場合:跳出某種嵌套較深的結(jié)構(gòu)盡量少用,破壞結(jié)構(gòu)化,甚至導(dǎo)致堆棧溢出。但有時(shí)使用可以簡化程序,減少變量,如:#include<stdio.h>#include<math.h>main(){inti,j;for(i=3;i<=100;i++){for(j=2;j<=sqrt(i);j++){if(i%j-0)gotonext;}printf("刎、t",i);next:;第六章數(shù)組—維數(shù)組的定義與使用1.1數(shù)組的定義格式:(type)數(shù)組名[常量表達(dá)式]:如:ints[10];數(shù)組名定義同標(biāo)識符常量表達(dá)式表示數(shù)組元素個(gè)數(shù),不能用變量進(jìn)行動(dòng)態(tài)定義。如s[n]數(shù)組元素從s[0]、s[l]~s[9],C語言不進(jìn)行越界檢查,越界使用數(shù)組將得到不可預(yù)料的結(jié)果。例:#include<stdio.h>main(){ints[5]={1,2,3,4,5};inti;for(i=2;i<8;i4-+)printf(,,s[%d]=%d\t',,i,s[i]);putcharCXn1);)得到結(jié)果為:s[2]=3 s[3]=4 s[4]=5 s[5]=23411 s[6]=25637s⑺=15709§6.1.2—維數(shù)組元素的引用例:構(gòu)造ー個(gè)Fibonacci數(shù)列,并計(jì)算巾ー1]/巾]#include<stdio.h>main(){intf[20]={l,l};inti;floatratio;for(i=2;i<20;i++)f[i]=f[i-l]+f[i-2];for(i=0;i<20;i++){if(i%2==0)putchar(,\n,);printf(nf[%2d]=%4dratio二%f'「i,f[i],(i>l)?(LO*f[i?l]/ffi]):〇);結(jié)果為:no]=1ratio=0.000000fl1]=1ratio=0.000000仃2]=2ratio=0.500000f[3]=3ratio=0.666667仃4]=5ratio=0.600000f[5]=8ratio=0.625000仃6]=13ratio=0.615385f[7]=21ratio=0.619048<18]=34ratio=0.617647fl9]=55ratio=0.618182H10]=89ratio=0.617978f[ll]=144ratio=0.618056f[12]=233ratio=0.618026f[13]=377ratio=0.618037f[14]=610ratio=0.618033fl15]=987ratio=0.618034f[16]=1597ratio=0.618034f[171=2584ratio=0.618034fll8]=4181ratio=0.618034f[19J=6765ratio=0.618034§6.1.3ー維數(shù)組的初始化用賦值語句初始化,如:ints[5]={0,1,2,3,4};靜態(tài)數(shù)組初始化,如:staticints[5]={0,1,2,3,4};部分元素初始化,如:ints[5]={0,1.2}:僅對前三個(gè)元素初始化,后面為〇自動(dòng)確定數(shù)組長度,如:ints[]={0,1,2,3,4},將自動(dòng)確定數(shù)組長度為5。以下初始化是錯(cuò)誤的:ints[5]={5*0};ints[5]={,,,3,4};§6.2二維數(shù)組的定義與引用2.1二維數(shù)組的定義格式:(type)數(shù)組名[常量表達(dá)式][常量表達(dá)式];如:floats[4][3];內(nèi)存中按行存放,即s[〇][〇]ー》s[0][1]->->s[3][2],即右方下標(biāo)變化最快。二維數(shù)組可以理解成若干個(gè)一維數(shù)組組成,如s[3][3]可以理解成:s[〇][3]、s[l][3]、s[2][3]§6.2.2ニ維數(shù)組的引用?注意下標(biāo)不要越界,如:ints[2][3];s[2][3]=4;錯(cuò)誤§6.2.3二維數(shù)組的初始化基本同一維數(shù)組注意:ints[3][4]={{1},{2,3},{4,5,6}};表示:"100〇-23004560問題:ints[][4]={1,2,3,4,5,6,7,8,9,10,11,12)?系統(tǒng)可以自動(dòng)確定為s[3][4],如果int$ロ[4]={1,2,3,4,5}系統(tǒng)將如何確定?(系統(tǒng)將確定為s[2][4])§6.3字符數(shù)組§6.3.1字符數(shù)組的定義charc[10]={ ','n','a','m','e'};注意,charc[10]與intc[10]是不同的,例如:#include<stdio.h>main(){chars[10]={,a,;b,;c,;d\,\0,};printf(n%sn,s);)將輸出:abcdo而:#include<stdio.h>main(){ints[l0]={"a'',''b'',''c'',''d'',''\O"};printf("%s",s);}將輸出:a0考慮一下,為什么?§6.3.2字符數(shù)組的初始化?注意,字符數(shù)組用來表示字符串時(shí),必須注意末尾的結(jié)束標(biāo)志‘、。’,沒有結(jié)束標(biāo)志,有時(shí)輸出時(shí)會(huì)得到意想不到的結(jié)果,如:Sinclude<stdio.h>main(){char= 〇'};printft);}結(jié)果輸出為:Hello%s0如果改為:#include<stdio.h>main(){chart[6]={,H,,'e','l','l','o','\0');printft);)則輸出正確結(jié)果:Hello.3.3字符數(shù)組的引用6.3.4字符串和字符串結(jié)束標(biāo)志?利用字符串為字符數(shù)組賦值,如:charsロメHello”;或charsロニ{(lán)“Hello”};注意此時(shí)s數(shù)組長度為6§6.3.5字符數(shù)組的輸入輸出?三種輸出方法:例staticcharsロ=”Hello”;用循環(huán)實(shí)現(xiàn),for(i=0;iく5;i++)printf(“%c”,s[i]);用字符串輸出格式,printf("%s”,s);用puts函數(shù),puts(s);?輸入方式用for循環(huán),如chars[10];inti;for(i二〇;iく10;i++)scanf("%c”,&s[i]);printfs);用scanf(fs”,s)方式,如:chars[30];scanfぐ4%s”,s);printfC4%s”s);注意,數(shù)組名代表數(shù)組首地址,數(shù)組元素代表值.3.6字符串處理函數(shù)putsgetsstrcpystrcmpstrlwrstrupr例如:puts(strupr("Hello,World\n”));第七章函數(shù).1概述C語言是函數(shù)型語言,因此,函數(shù)是C語言最重要的組成部分。ー組語句能處理不同的數(shù)據(jù),ー組語句能出現(xiàn)在程序的不同地方,這些都需要函數(shù)結(jié)構(gòu)。C語言中沒有另外的子程序結(jié)構(gòu)。main。本身就是ー個(gè)函數(shù)。C語言函數(shù)種類?標(biāo)準(zhǔn)函數(shù),即庫函數(shù),如scanf,printf,puts等?用戶自定義函數(shù)*C語言函數(shù)可以帶參數(shù),可以不帶參數(shù);可以返回值,可以不返回值;不允許嵌套定義,但允許遞歸使用。§7.2函數(shù)說明的一般形式?函數(shù)由兩個(gè)必須的部分組成,即函數(shù)說明和函數(shù)定義。?函數(shù)說明,或函數(shù)原型(prototype)用于告訴編譯器有關(guān)函數(shù)的信息。函數(shù)說明包括函數(shù)名、函數(shù)參數(shù)的數(shù)冃及類型,以及函數(shù)的返回類型。?函數(shù)定義包括函數(shù)傳遞及返回的具體信息,以及函數(shù)體本身。例:#include<stdio.h>intmax(intx,inty); /?函數(shù)說明?/voidmain(){inta,b,c;scanf(0%d%d",&a,&b);c=max(a,b); /?函數(shù)調(diào)用?/printf("maxof%dand%dis%d.\nH,a,b,c);intmax(intx,inty) /?函數(shù)定義?/(intz;z=(x>y)?x:y;return(z);}函數(shù)說明的一般格式:類型標(biāo)識符函數(shù)名(參數(shù)類型參數(shù)名,..),如:intmy_func(inta,intb,intc);doublecube(doublex);voidshowcolor(void);所有函數(shù)在確用之前必須先加以說明,即先說明再使用。只有一種情況可以不加說明,即函數(shù)先定義,再使用。如:#include<stdio.h>intmax(intx,inty)(intz;z=(x>y)?x:y;return(z);}voidmain()(inta,b,c;scanf("%d%d\&a,&b);c=max(a,b);printf("maxof%dand%dis%d.\nM,a,b,c);)此例是合法的,但不是好的風(fēng)格,因?yàn)榭勺x性低,對程序整體意圖不容易把握,第二個(gè)缺點(diǎn)是首先定義的函數(shù)必須是最詳細(xì)的,函數(shù)體中不能調(diào)用任何其他函數(shù),否則就會(huì)出錯(cuò)。使用函數(shù)說明往往比決定先定義哪個(gè)函數(shù)容易得多。參數(shù)名可以省略,因?yàn)楹瘮?shù)說明僅僅是告訴編譯器參數(shù)的個(gè)數(shù)及類型,并不關(guān)心參數(shù)的名稱,如下例是合法的:intmax(int,int);如用戶在函數(shù)說明中未說明返回類型,編譯器認(rèn)為返回類型為缺省型或整型。因此下例是合法的:max(intx,inty);max(int,int);作為良好的風(fēng)格,應(yīng)對函數(shù)類型作明確的說明,空類型的應(yīng)說明為void型,整數(shù)型的應(yīng)說明為int類型?!?.3函數(shù)參數(shù)和函數(shù)的值3.1形參與實(shí)參實(shí)參可以是常量、變量或表達(dá)式,但必須是有確定的值,如:c=max(a,a+b);實(shí)參類型必須與形參類型一致,否則會(huì)出錯(cuò)。實(shí)參與形參的對應(yīng)關(guān)系是單向的,即實(shí)參傳遞給形參,調(diào)用結(jié)束后,取得返回值,但實(shí)參的值并不發(fā)生改變。Sinclude<stdio.h>intchange(inta,intb);voidmain()(inta,b,c;scanff%d%d”,&a,&b);c=change(a,b);printf(z,maxof%dand%dis%d.、n”,a,b,c);)intchange(inta,intb)(intz;z=(a>b)?a:b;a++;b++;return(z);此例中,雖然函數(shù)定義中,形參值發(fā)生了改變,但并不影響實(shí)參的值。如果輸入值為1213,不要誤以為輸出將是maxof13and14is13〇§7.3.2函數(shù)的返回值函數(shù)的返回值是通過return語句實(shí)現(xiàn)的,一般格式為:return[表達(dá)式];如果沒有表達(dá)式,則表示僅從當(dāng)前函數(shù)中返回調(diào)用處。除了void型以外,一般函數(shù)都必須要有return語句,不管是否產(chǎn)生了有用的數(shù)據(jù)。如main。函數(shù)中如果沒有return將產(chǎn)生一個(gè)警告錯(cuò)誤。函數(shù)體中出現(xiàn)多條return語句是允許的,因?yàn)榈谝粋€(gè)遇到的return語句將使流程推出函數(shù),回到調(diào)用處。如果return的值與函數(shù)類型不符,以函數(shù)類型為準(zhǔn),如:doublesumit(inta,intb){return(a+b);}返回時(shí),將把類型提升到double型返回。盡量避免此類隱式轉(zhuǎn)換,以免出現(xiàn)難以調(diào)試、尋找的錯(cuò)誤?!?.4函數(shù)的調(diào)用§7.4.1函數(shù)調(diào)用的一般形式?函數(shù)名(實(shí)參表):?函數(shù)調(diào)用的幾種方法:函數(shù)語句,如:clrscr();函數(shù)表達(dá)式,如:c=a/max(a,b);函數(shù)參數(shù),如:m=max(c,max(a,b))下面是ー個(gè)較為全面的例子:#include<stdio.h>#include<conio.h>voidget_parms(float*pl,float*p2);floatget_ratio(floatdivident,floatdivisor);voidput_ratio(floatquotient);constfloatINFINITY=3.4E+38;main(){floata,b,ratio;charch;do{get_parms(&a,&b);ratio=get_ratio(a,b);put_ratio(ratio);puts("Pressqtoquit,otherkeytocontinue.");}while((ch=getch())!='q');}voidget_parms(float*pl,float*p2){puts("Entertwonumbers:");scanf("%f%f\pl,p2);)floatget_ratio(floatdivident,floatdivisor){if(divisor==0.0)return(INFINITY);elsereturn(divident/divisor);)voidput_ratio(floatratio){if(ratio==INFINITY)puts("Theratioisundefined*1);elseprintf(**Theratiois%f\n",ratio);}函數(shù)的嵌套調(diào)用函數(shù)不允許嵌套定義,例如,如ド結(jié)構(gòu)是不允許的:f()(:g(){:]}但是,函數(shù)中允許嵌套調(diào)用,即:f()(:g();}g()}例:#include<stdio.h>#include<conio.h>voidmain(){voidfact(intn);intn;puts("Pleaseentern°);scanf(H%d",&n);fact(n);}voidfact(intn){voidput_result(intn,doubleresult);inti;doublefac=l.;for(i=n;i>=l;i-){fac=fac*i;}put_result(n,fac);}voidput_result(intn,doubleresult){printf(,,%d!=%20.10e\n,,,n,result);)函數(shù)的遞歸調(diào)用作為函數(shù)嵌套調(diào)用的ー個(gè)特例,就是函數(shù)自己調(diào)用自己,稱為函數(shù)的遞歸調(diào)用。函數(shù)的遞歸調(diào)用是C語言的特征之一,利用遞歸調(diào)用,可以解決許多用ー般方法難以解決的問題。例C7_4:計(jì)算n!#include<stdio.h>doublefact(intn);voidmain(){intn;scanf("%d",&n);printf("%d!=%g\n",n,fact(n));)doublefact(intn){doublefac=1;if(n>l)fac=n*fact(n-l);elsefac=1;return(fac);}ー個(gè)典型的遞歸例子即著名的Hanoi塔問題,程序如下:#include<stdio.h>#include<conio.h>voidhanoi(intn,chara,charb,charc);voidmove(chara,charb);inti=l;voidmain(){intn;puts("Pleaseentern");scanf(n%d",&n);printf(nTheproceedofmoving%ddiskesis:\n",n);hanoi(n,'A',B,'C');}voidhanoi(intm,chara,charb,charc){if(m==l)move(a,c);else{hanoi(m-l,a,c,b);move(a,c);hanoi(m-l,b,a,c);})voidmove(chara,charb){printf("step%d:%c->%c\nn,i-H-,a,b);}?雖然使用遞歸可以解決許多特殊的問題,但是,遞歸程序需要耗費(fèi)堆棧,因此并不節(jié)省內(nèi)存空間,同時(shí),由于程序反復(fù)嵌套調(diào)用,時(shí)間也不節(jié)省,因此,如果能用非遞歸結(jié)構(gòu)解決的問題,盡量不用遞歸結(jié)構(gòu)?!?.8變量的存儲(chǔ)類§7.8.1變量存儲(chǔ)類概述*C語言中,變量有兩個(gè)主要的屬性:?變量的類型,決定了變量的數(shù)值類型和存儲(chǔ)空間大小?變量的存儲(chǔ)類(storageclass),它決定了何時(shí)何地可以使用變?ー個(gè)變量的存儲(chǔ)類屬性包含三方面的屬性,即:變量作用域變量生存期變量的連接§7.8.2變量的作用域?文件作用域(filescope):具有文件作用域的變量可以在源文件的任何地方使用,所以,文件作用域又稱為全程作用域(global)。源文件中的任何函數(shù)都可以使用文件作用域變量。?用戶在所有函數(shù)以外說明的變量具有文件作用域。如:inti,j;main(){..}或者:main(){?.)inti,j;?如果文件作用域變量的說明不是在源程序的頂端,如上面的例2,依據(jù)變量應(yīng)該先說明再使用的規(guī)則,其作用域應(yīng)說明點(diǎn)開始,但在說明點(diǎn)以前,可以通過extern加以說明并使用它。如:main(){externinti,j;i++;j++;}inti,j;函數(shù)作用域(functionscope):具有函數(shù)作用域的變量只能在說明變量的函數(shù)中使用。因此,ー個(gè)程序中只有一個(gè)函數(shù)可以使用具有函數(shù)作用域的變量。通常在函數(shù)定義的頂端說明具有函數(shù)作用域的變量。如:inti,j;intmy_funcl(int,int);main(){intx,y,z;z=my_ftinc(x,y);)intmy_func(ints,intt){intk;k=(s>t)?s:t;returnk;)此例中,k具有函數(shù)作用域,其作用域僅限于函數(shù)myjbnc中。同樣,x,y,z也具有函數(shù)作用域,其作用域限于main。函數(shù)內(nèi)。塊作用域(blockscope):也稱局部作用域(localscope)〇具有塊作用域的變量只能在說明變量的塊中使用,這個(gè)塊可以是ー個(gè)復(fù)合語句單位。例如:main(){inti=10;intent;for(cnt=0;cnt<=20;cnt++){intj=l;printf("Inloop,j=%d.\n,,,j);)printf(“〇utofloop,i=%d.\n'',i);}其中,i具有函數(shù)作用域,而j具有塊作用域,僅能在for復(fù)合語句中使用,在循環(huán)體以外使用將出現(xiàn)編譯錯(cuò)誤。函數(shù)原型作用域(functionprototypescpoe):在函數(shù)原型的參數(shù)表中說明的標(biāo)識符具有函數(shù)原型作用域,其作用域延伸到函數(shù)原型結(jié)束。例如:intmy_func(intx,inty);其中x、y具有函數(shù)原型作用域,其作用域僅五該函數(shù)原型的參數(shù)說明中有效,所以,作用域是最小的。ー個(gè)變量如果在一定范圍內(nèi)是有效的,該范圍稱為該變量的作用域;如果同時(shí),在此作用域內(nèi),該變量可以被引用,則稱在該作用域內(nèi),該變量是可見的(visibility)。通常,作用域和可見性是相同的概念,但有時(shí),作用域內(nèi)的變量并不可見,如:main(){inti=10;intent;for(cnt=0;cnt<=20;cnt++){inti=l;printf("Inloop,i=%d.\n",i);printf(“〇utofloop,i=%d.\n,,,i);}其中,第一個(gè)i具有函數(shù)作用域,第二個(gè)i具有塊作用域。執(zhí)行for循環(huán)時(shí),第一個(gè)i在作用域內(nèi),但是不可見,第二個(gè)i在塊作用域內(nèi)并且是可見的。所以有時(shí)在作用域內(nèi),但變量不一定可見?!?.8.3變量的生存期(duration)?變量生存期表示變量可供使用的時(shí)間。ー個(gè)變量的生存期決定著何時(shí)為變量分配內(nèi)存單元。因此,生存期定義了被說明的標(biāo)識符在內(nèi)存中具有真正的物理對象的期限。在大程序中,同時(shí)為所有變量分配內(nèi)存將是極其浪費(fèi)的,C只為正在使用著的變量分配內(nèi)存,這樣有效地解決了存儲(chǔ)空間的問題。例如,調(diào)用函數(shù)時(shí),為函數(shù)中使用的變量分配內(nèi)存;函數(shù)結(jié)束后,分配的內(nèi)存空間將被釋放。?生存期有三種,即:自動(dòng)(auto)生存期,又稱局部生存期靜態(tài)(static)生存期寄存器類?靜態(tài)生存期:具有靜態(tài)生存期的變量一旦程序運(yùn)行就馬上分配內(nèi)存,并且這個(gè)內(nèi)存一直保留到程序運(yùn)行終止。常見的靜態(tài)生存期對象包括:L具有文件作用域的所有變量都是靜態(tài)生存期的。2.所有函數(shù)都是靜態(tài)生存期對象。3.其他用static或extern存儲(chǔ)類指明符指定的變量。靜態(tài)生存期變量在沒有顯式初始值時(shí),其值自動(dòng)初始化為〇。例如,以下兩個(gè)例子中的i具有靜態(tài)生存期。例1:inti;main(){?.)其中,i具有文件作用域和靜態(tài)生存期,因此,在程序的任何地方都可以調(diào)用i。例2:main(){..)voidfunc(intx){staticinti;其中的i具有函數(shù)作用域和靜態(tài)生存期。因此,在整個(gè)程序運(yùn)行期間,為i所開辟的內(nèi)存單元都存在,但只有在函數(shù)func()內(nèi)才能調(diào)用i,其他區(qū)域內(nèi)不可調(diào)用i。例3:intj;main(){for(;j<=10;j++){staticinti;i++;}}此例中,j具有文件作用域和靜態(tài)生存期,i具有塊作用域和靜態(tài)生存期。具有文件作用域的對象一定具有靜態(tài)生存期,但是,具有靜態(tài)生存期的變量不一定具有文件作用域,也可以具有函數(shù)作用域或塊作用域。/*2c*/intadd();intadd();main()main()((intresult;intresult;result=add()result=add();printf(%d,result);printf(%d,result);result=add();result=add();printf(%d,result);printf(%d,result);result=add();result=add();printf(%d,result);printf(%d,result);}}intadd()intadd()({intnum=50;staticintnum=50;num++;num++;returnnum;returnnum;}}上面兩個(gè)源文件,只有函數(shù)add()里的變量聲明有所不同,一個(gè)是自動(dòng)存儲(chǔ)類型,ー個(gè)是靜態(tài)存儲(chǔ)類型。對于1.C文件,輸出結(jié)果為515151;這很好理解,每次初始值都是50,然后加1上來;對于2.C文件,輸出結(jié)果為515253;這是由于變量是靜態(tài)的,只在第一次初始化了50,以后都是使用上次的結(jié)果值。當(dāng)?shù)谝淮握{(diào)用add。時(shí),初始化為50,然后加1,輸出為51;當(dāng)?shù)诙握{(diào)用時(shí),就不初始化了,這時(shí)num的值為上次的51,然后加1,輸出52;當(dāng)?shù)谌握{(diào)用時(shí),num為52,加1就是53了。比較就會(huì)發(fā)現(xiàn)它們的不同之處了。靜態(tài)變量在下ー節(jié)要說的遞歸函數(shù)中經(jīng)常使用到。當(dāng)?shù)谝淮尾恢该黛o態(tài)變量的初始值時(shí),默認(rèn)為〇。?自動(dòng)生存期:是最有效地利用內(nèi)存的存儲(chǔ)方式。當(dāng)進(jìn)入到封閉塊或函數(shù)時(shí),將在堆棧(或寄存器)中創(chuàng)建它們。當(dāng)程序推出該塊或函數(shù)時(shí),它們將被刪除。具有自動(dòng)生存期的對象必須顯式初始化,否則它們的內(nèi)容將是不可預(yù)料的。在說明局部生存期的變量時(shí),可以使用存儲(chǔ)類指明符auto,但通常省略auto,因?yàn)樵趬K或函數(shù)中說明變量時(shí),auto是默認(rèn)的。具有局部生存期的對象一定具有局部作用域(函數(shù)作用域或塊作用域),因?yàn)樵诜忾]塊的外面它不存在,反之則不然,具有局部作用域的對象可能具有靜態(tài)作用域。例如,以下例子中的i具有自動(dòng)生存期;例1;voidfiinc(intx);main(){inti;.Jvoidfunc(intx){inti;i=3;■■)其中,main。中的i和func()的i都是自動(dòng)生存期的變量,它們互相沒有任何關(guān)系。例2:voidfunc(int);staticinti;main(){i++;func(3);)voidfunc(intx){inti=x;}其中,第一個(gè)i具有文件作用域和靜態(tài)生存期,但在ftmc()函數(shù)中的i具有函數(shù)作用域和動(dòng)態(tài)生存期,它們是兩個(gè)不同的i,同時(shí),在func()中,第一個(gè)i處在作用域中但不可見?!?.8.4變量的連接(linkage)ー個(gè)完整的程序可以由若干個(gè)源程序組成,ー個(gè)源程序可以由若干個(gè)函數(shù)組成,因此,存在這樣的問題,如果ー個(gè)程序的多個(gè)源程序中,使用了同名標(biāo)識符,或者ー個(gè)源程序中的多個(gè)函數(shù)中,使用了同名的標(biāo)識符,那么程序如何處理呢?因此,變量的連接表明在不同的程序單位中出現(xiàn)的同名標(biāo)識符彼此之間的連接關(guān)系。變量的連接關(guān)系有三種,即:1.內(nèi)部連接(internallinkage”.外部連接(externallinkage)3.不連接(nolinkage)〇?內(nèi)部連接:?具有內(nèi)部連接屬性的標(biāo)識符僅在ー個(gè)文件中表示同一對象或函數(shù),因此,這樣的變量具有文件作用域。?用存儲(chǔ)類說明符static說明的任何具有文件作用域的標(biāo)識符具有內(nèi)部連接屬性,也即用static說明的文件作用域標(biāo)識符不能被其他源程序引用。例如:staticinti;main(){?.}此例中的i具有文件作用域,由于加上了static說明,因此,i具有內(nèi)部連接屬性,其他源程序不能引用i。注意,對文件作用域i加static說明,并不意味著此時(shí)iオ是靜態(tài)變量,事實(shí)上,所有的文件作用域變量都是靜態(tài)生存期變量,不管是否有static說明都不可能具有局部生存期(自動(dòng)生存期)。?外部連接:?具有外部連接屬性的標(biāo)識符在組成程序的各個(gè)源程序中表示同樣的對象。ー個(gè)外部變量具有文件作用域,同時(shí),為能在其他源文件中引用該標(biāo)識符,必須在其他使用該標(biāo)識符的源程序中重新說明并在說明前使用extern關(guān)鍵詞。如果對象或函數(shù)的說明中包含存儲(chǔ)類說明符extern,則此標(biāo)識符與具有文件作用域的標(biāo)識符的任何可見說明具有一致的連接屬性;若不存在可見說明,則它具有外部連接屬性。例如:main()(externinti;Jstaticinti;此例中,由于存在static說明了文件作用域標(biāo)識符i具有內(nèi)部連接屬性,因此,main。中的i也具有內(nèi)部連接屬性,其他源程序不能引用這ーi。如果在函數(shù)說明中不包含存儲(chǔ)類說明符,則其連接屬性為缺省存儲(chǔ)類說明符extern0如果ー個(gè)具有文件作用域的變量標(biāo)識符說明不含存儲(chǔ)類指明符,則該標(biāo)識符具有外部連接屬性。例如:下面的這個(gè)例子由兩個(gè)源程序組成,它們分別是main.cpp和func.cpp,其中在main.cpp中,定義了文件作用域變量inti,注意雖然沒有加static,但i是靜態(tài)變量,由于引用在前,定義在后,故在第四行用externinti說明。在func.cpp
中,i具有外部連接屬性,因此,用externinti表示此時(shí)i與main.cpp中的i為同一對象。該程序運(yùn)行結(jié)束時(shí),i=5o注意:當(dāng)定義externinti的時(shí)候,不能再定義初始化的形式,如:externinti=3main.cppfunc.cppexternvoidfunc(intx);main(){func(3);externinti;i++;)inti;voidfunc(intx){externinti;i=x;i++;)?不連接:具有不連接屬性的變量只能在說明變量的塊中可見,它不能被多于ー個(gè)的函數(shù)引用。例如函數(shù)形參、函數(shù)或塊作用域的變量等。§7.8.5小結(jié)?作用域:文件作用域、函數(shù)作用域、塊作用域、函數(shù)原型作用域?生存期:局部(自動(dòng))生存期、靜態(tài)生存期、動(dòng)態(tài)生存期?連接:外部連接、內(nèi)部連接、不連接作用域生存期連接屬性局部生存期靜態(tài)生存期外部連接內(nèi)部連接不連接文件作用域Xq*ベX函數(shù)作用域**XXq塊作用域**XXqx表示否;q表示是;?表示可以存儲(chǔ)類中,除了auto、staticタト,還有一種寄存器類型register,如registerinti;register型一定是auto型的,不同的是要求編譯器盡可能分配寄存器單元給它,但如果沒有,則作為auto分配。由于現(xiàn)在編譯器都進(jìn)行自動(dòng)優(yōu)化,以決定是否為ー個(gè)變量分配寄存器,所以register已很少使用。例如,TurboC++的IDE中,在Option->Compi1er->0ptimizations中,在RegisterVariables中有Automatic,RegisterKeyword,None三個(gè)選項(xiàng),一般為Automatico對象的連接屬性也同樣適用于函數(shù),函數(shù)從本質(zhì)上來說都是具有文件作用域、靜態(tài)生存期的,如果函數(shù)說明前加上存儲(chǔ)類說明符static,則該函數(shù)具有內(nèi)部連接屬性,只能在本文件中調(diào)用,其它文件中不能調(diào)用。如果函數(shù)說明時(shí)加上存儲(chǔ)類說明符extern,或者沒有存儲(chǔ)類說明符,則表明該函數(shù)具有外部連接屬性,可以為其它源文件所調(diào)用。程序設(shè)計(jì)中,盡量避免使用大作用域、長生存期及外部連接屬性的標(biāo)識符,因?yàn)樗鼈兊氖褂?會(huì)降低程序的結(jié)構(gòu)化、模塊化特性,只有在需要多參數(shù)傳遞的時(shí)候オ使用。第八章編譯預(yù)處理TurboC提供了編譯預(yù)處理功能,編譯預(yù)處理主要包括以下三種功能;宏定義?對象型宏?函數(shù)型宏?文件包含?條件編譯C編譯器首先對源程序進(jìn)行編譯預(yù)處理,然后將編譯預(yù)處理后的結(jié)果連同源程序ー起,進(jìn)行編譯處理,得到目標(biāo)代碼?!?.1宏定義和文字處理中的宏一樣,C程序中使用宏可以降低書寫工作量,提高程序的可讀性和準(zhǔn)確度。依據(jù)宏定義是否帶有參數(shù),可將宏定義分為對象型宏和函數(shù)型宏?!?.1.1對象型宏對象型宏格式:^define標(biāo)識符字符串#define告訴預(yù)編譯器宏定義的開始。標(biāo)識符即程序中使用的宏名,預(yù)編譯器在程序中遇到宏名時(shí),即用字符串來替換它。例如:#definePRICE0.32fee=sale*PRICE;宏不僅可以代替數(shù)據(jù),也可以代替字符、字符串及其它數(shù)據(jù)類型,例如:#include<stdio.h>#include<conio.h>#defineFIRST_CHARH'#defineSECOND_CHAR'i"#defineCOMMA#defineSTRING"Thisisamacroexample."#defineCPRTputchar#defineSPRTputsmain()(CPRT(FIRST_CHAR);CPRT(SECOND_CHAR);CPRT(COMMA);SPRT(STRING);)結(jié)果將打印Hi,Thisisamacroexample.幾點(diǎn)注意:宏名必須遵循標(biāo)識符的規(guī)則,當(dāng)中不能使用空格,雖然沒有規(guī)定,但一般習(xí)慣上宏名用大寫字符,以區(qū)別與變量。語法上宏定義可以出現(xiàn)在程序的任何地方,只要在用到宏名的前面,但一般將預(yù)編譯命令集中在程序前段,以便于閱讀和修改。#define不能寫成#DEFINE,宏名后面不能用=,宏定義后不能以分號結(jié)束,否則,分號(;)將成為字符串的一部分。分隔符、使宏定義可以寫成多行。必須注意預(yù)編譯展開時(shí),宏名將被用宏定義時(shí)宏名后面的所有字符展開,因此,必須注意引號的使用。例如:#defineSTRING"Thisisateststringmacro.^^printf(“%s”,"STRING");輸出結(jié)果并不是期望的Thisisateststringmacro.,而是STRING,正確的寫法應(yīng)該是:printf(''%s”,STRING);如果有兩個(gè)宏定義需要合并的情況,也應(yīng)注意,例如:#defineSTR1"Thisisa”#defineSTR2"teststringmacro.”如下應(yīng)用是合法的:puts(STRlSTR2);printf("%s",STRlSTR2);?宏定義可以嵌套,這意味著如下定義是合法的:例1:#defineSTR1"Thisisa"#defineSTR2"teststringmacro."#defineSTRINGSTR1STR2puts(STRING);例2:#defineNUM_l10#defineNUM_215#defineSUMNUM_1+NUM_2printf("TheSUMis%d\n",SUM);?宏定義可以用#undef取消,取消后宏名不再有定義,可以另作他用。如:#undefSUM#undefSTR1§8.1.2函數(shù)型宏宏定義還可以帶有參數(shù),成為函數(shù)型宏,同函數(shù)相似,函數(shù)型宏也有形參,在代換時(shí),也進(jìn)行宏形參和宏實(shí)參的對應(yīng)。但是,函數(shù)型宏和函數(shù)有本質(zhì)的不同,不能混淆。函數(shù)型宏格式為:#define標(biāo)識符(標(biāo)識符表)置換表例如:#include<stdio.h>#definePI3.1415927#defineLENGTH(R)2*PI*R#defineAREA(R)PI*R*Rmain(){intr=10;printf("Thelengthofcircleis%f.\n",LENGTH(r));printf("Theareaofcircleis%f.\n",AREA(r));}經(jīng)過預(yù)編譯處理后,執(zhí)行語句中的LENGTH(r)替換成2*3.1415927*r;AREA(r)被替換成3.1415927*r*r。幾點(diǎn)注意:注意括號。例如,如果對上述宏引用改成LENGTH(5+5).AREA(5+5),替換結(jié)果卻是錯(cuò)誤的,其中,LENGTH(5+5)將被替換成:2*3.1415927*5+5,結(jié)果當(dāng)然錯(cuò)誤。解決的辦法是:將函數(shù)型宏定義改為:#defineLENGTH(R)2*PI*(R)#defineAREA(R)PI*R*(R)注意引號,在函數(shù)型宏定義時(shí),置換表內(nèi)如果有引號,則引號內(nèi)的內(nèi)容是不會(huì)被置換的。如果我們定義如下函數(shù)型宏:#include<stdio.h>#defineOUTPUT(s)printf("s=%d\n';s)main(){intresult=10;OUTPUT(result);)輸出結(jié)果并不是我們希望的result=10,而是s=10o解決辦法是采用#轉(zhuǎn)換率:#include<stdio.h>#defineOUTPUT(s)printf(#sH=%d\n",s)main(){intresult=10;OUTPUT(result);}采用#轉(zhuǎn)換串的另ー個(gè)例子是:#include<stdio.h>#defineOUTPUT(s)#smain(){puts("Hesaid:"OUTPUT("Hello"));}結(jié)果將輸出:Hesaid:"Hello"。否則,如果采用OUTPUT—Hello"")或者#defineOUTPUT(s)"s”得至リ的輸出是錯(cuò)誤和:Hesaid:s。##字符串粘貼:如果采用如下函數(shù)型宏定義:#include<stdio.h>#defineMERGE(i,j)ijmain(){puts(MERGE("a","b"));}不能得到期望的“ab”,而將出現(xiàn)編譯錯(cuò)誤,正確的方法是:#include<stdio.h>#defineMERGE(i,j)i##jmain(){puts(MERGE("a","b"));}考慮以下程序的輸出將是什么:#include<stdio.h>#defineSTR_1"Thisis"#defineSTR_2"atestn#defineCAT(a,b)a##bmain(){puts(CAT(STR_l,STR_2));}編譯將出現(xiàn)錯(cuò)誤,但如果將a##b改為ab,輸出將正確:Thisisatest?再次強(qiáng)調(diào),函數(shù)型宏和函數(shù)調(diào)用是本質(zhì)不同的,使用不當(dāng)會(huì)產(chǎn)生難以發(fā)現(xiàn)的錯(cuò)誤??紤]如下例子:#include<std
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 現(xiàn)代商業(yè)辦公空間設(shè)計(jì)藝術(shù)
- 《神奇的工具》(說課稿)安徽大學(xué)版三年級下冊綜合實(shí)踐活動(dòng)
- 生態(tài)城市中的綠色建筑材料應(yīng)用
- 16《朱德的扁擔(dān)》說課稿-2024-2025學(xué)年二年級上冊語文統(tǒng)編版
- 環(huán)保型辦公空間的設(shè)計(jì)與實(shí)現(xiàn)
- 七年級地理下冊 11《中國在世界中》說課稿2 魯教版五四制
- 現(xiàn)代醫(yī)療辦公中的電子病歷標(biāo)準(zhǔn)化操作教程
- 現(xiàn)代綠色物流與環(huán)境保護(hù)的協(xié)同發(fā)展
- 現(xiàn)代醫(yī)療技術(shù)下的辦公樓規(guī)劃設(shè)計(jì)
- 現(xiàn)代建筑設(shè)計(jì)的創(chuàng)新點(diǎn)與實(shí)踐案例分享
- 醫(yī)院消防安全培訓(xùn)課件
- 質(zhì)保管理制度
- 《00541語言學(xué)概論》自考復(fù)習(xí)題庫(含答案)
- 2025年機(jī)關(guān)工會(huì)個(gè)人工作計(jì)劃
- 2024年全國卷新課標(biāo)1高考英語試題及答案
- 華為經(jīng)營管理-華為激勵(lì)機(jī)制(6版)
- 城市旅行珠海景色介紹珠海旅游攻略PPT圖文課件
- 小學(xué) 三年級 科學(xué)《觀測風(fēng)》教學(xué)設(shè)計(jì)
- JJF1664-2017溫度顯示儀校準(zhǔn)規(guī)范-(高清現(xiàn)行)
- 第二講共振理論、有機(jī)酸堿理論
- 高考英語聽力必備場景詞匯精選(必看)
評論
0/150
提交評論