C語言要點總匯_第1頁
C語言要點總匯_第2頁
C語言要點總匯_第3頁
C語言要點總匯_第4頁
已閱讀5頁,還剩61頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

一.C語言的產(chǎn)生和發(fā)展1972年美國的DennisRitchie,最初用在UNIX下的DECPDP-11計算機。由早期的BCPL(BasicCombindProgrammingLanguage)發(fā)展而來,并命名為C語言。ANSIC提交給ISO后產(chǎn)生ISOC(內(nèi)容基本一致):于1989年發(fā)布了第一個C的標準:C89最新一個是1999年的:C99GCC/CC是具體的C編譯器二C語言的特點(原則):C是中級語言(它能對計算機硬件直接操作。當然說它是高級語言也對)C是結(jié)構式語言以函數(shù)〈注意跟數(shù)學的函數(shù)區(qū)分,它是大函數(shù)概念,形式(具體邏輯功能的載體,通過輸入?yún)?shù),進行內(nèi)部黑箱操作,最后產(chǎn)生一個結(jié)果〈直接消化,或者返回給調(diào)用用戶〉)來組織代碼,通過循環(huán),條件等控制語句使程序完成結(jié)構化C一定會有的函數(shù):main()intmain(intargc,char*argv[])//Is-1-aMATH:Y=f(x,y,z) Y=x+y*z;C:intf(intx,inty,intz)(inttemp=x+y*z;returntemp;)intmain(){intY=f(3,4,5);}//unix/linuxmain是int返回類型,windows卜main。是void返回類型。main。是整個程序的起點和入口C功能齊全,代碼精簡,效率高效A+=32;==>A=A+32;〃右邊A發(fā)生了兩次運算#include<stdio.h>,具體程序中沒有用到的庫函數(shù),相關頭文件沒必要include.(包含)fabs()も#include<math.h> gcc-ImC適用范圍大##怎樣去設計程序?.從問題實際出發(fā),寫ー個概括性的抽象的文字描述。る業(yè)務需求.定義變量,選定函數(shù)〈確定要包含哪些頭文件〉,確定程序?qū)崿F(xiàn)的邏輯過程(算法)。〈思路〉(偽代碼)る解決方案.按照以上兩點,依據(jù)解決問題的順序把語句和函數(shù)寫出代碼.る技術實現(xiàn)注意:不要邊想邊寫代碼:先把主干代碼寫出來,再慢慢加枝節(jié)代碼(輸出的格式更漂亮,容錯措施,更細的ー些功能實現(xiàn))る甚至把主干代碼部分刪了重寫更具體的實現(xiàn)也是可以的.る代碼不是一次寫成的!る專業(yè)體現(xiàn)在細節(jié)!三.變量.變量是存儲數(shù)值的內(nèi)存空間,所存的值可被改變(儲物柜:只能存固體物件,同一時間只能存一定的物體,但是不同時間可以換存別的同樣的固體物體).由于數(shù)值的類型有多種,對應的變量就有:整型(整數(shù))變量;浮點型(實數(shù))變量,和字符型變量。本質(zhì)上理解:C的數(shù)據(jù)類型只有:int整型變量,其它的數(shù)據(jù)類型可通過typedef類型重定義符得以實現(xiàn)拓展。(后邊沒有確定數(shù)據(jù)類型的變量或指針,默認的數(shù)據(jù)類型就是整型).有具體的存儲方式:靜態(tài)變量,外部變量,寄存器變量和自動存儲變量(變量釋放時系統(tǒng)會登記本空間已經(jīng)空閑,但是空間所存值不會被清除)。.具體變量的標識名,一般不代表變量空間的首地址,而是代表變量空間所存的值。(字符串變量例外).變量的聲明定義格式:存儲方式數(shù)據(jù)類型變量名!,變量名2,...;注:函數(shù)體內(nèi)變量的聲明定義是合在ー起的變量的掌握要決:類型特性(類型拓展組合:〈形容性的關鍵字,unsigned,signed,long,short);字節(jié)長度;取值范圍;存儲原理;表現(xiàn)形態(tài)(包括初始化,常量形態(tài),賦值等).整型變量(int):短整型(shortint)(-3萬?3萬)(2字節(jié)),普通整型(int)(-21億?+21億)(4字節(jié)),〇可再細分有符號和沒符號的整型。.浮點類型變量(double)〈表示的數(shù)值是模糊數(shù),用來存實數(shù)具體類型:float(4字節(jié))單精復(7位有效數(shù),6位小數(shù))double(8字節(jié))雙精度(16有效數(shù),15小數(shù))longdouble(12字節(jié))長雙精度注意:并沒有說明指數(shù)多少位本類型都是有符號的,浮點數(shù)主要應用在大數(shù)或超小數(shù)的存儲上,它是類似人的ー種模糊記憶模式浮點數(shù)的存儲原理:+0.314159*10"8*8=64位空間:最高位(最左側(cè))存符號(0代表正,1代表負),次高位8~11個位的空間存指數(shù)“2人n”里邊的n,剩余的位空間用來存小數(shù)部分(314159)(整數(shù)只是0,忽略)//0000101011001000.字符型變量變量中所存放的字符是計算機字符集ASCII中的字符對應的序號。字符型變量可轉(zhuǎn)變?yōu)檎妥兞?轉(zhuǎn)換原理就是把對應字符的ASCII碼序號作為整型值輸出A?Z:65?90 a?z:97?122’〇'?’9’:48-57還能保存一些其它的控制符號:\n,\t,\b,\〇(0),...sizeof(char)=l個字節(jié)428~+127一般有符號signedcharszChar;〃也是可以unsignedcharuzChar;〃也是OK因為原型就是整型//0-25511111111=1*2人7+1*2A6+1*2人5+1*2人4+1*2人3+1*2人2+1*2Al+1*2人0<-1*2A8-1=255char默認情況下是有符號類型三.常量是不可改變的變量:ー個沒有傳統(tǒng)變量的標識名(它用自身的內(nèi)容值來代表自己),自動的,臨時的,只讀的,有類型的,存有值的內(nèi)存空間,例字符串常量。常數(shù).整型常量,有長整,短整,有符號,無符號。短整:一3萬?+3萬有二進制,ハ進制,十六進制011, 0x123011U0xl23U.浮點型常量,也有單精度F,雙精度(默認的浮點數(shù)都是雙精度),和長雙精度L類型〃實際使用時比較少用字符后綴,而用3.0浮點數(shù),3表示整數(shù)〃注意3.0和3在空間占用上是不同的有效位:單精度6位小數(shù),7位有效值雙精度15位小數(shù),16位有效值格式化輸出:%ffloat%Ifdouble%llflongdouble.字符型常量用‘‘單引號括上一個字符來表示一個字符常量,char字符變量空間占用永遠是1個字節(jié),字符常量事實上還是被解析成整型,所以空間占用是4字節(jié)。用へ加上具體數(shù)值或字符,,表示轉(zhuǎn)義字符,例へ0,(相當于””空字符串),'\"注意與“\n”相區(qū)分)前者常用來表示一個字符串結(jié)束了,后邊常表示換行回車,、只是表示轉(zhuǎn)義,不會占用空間另外也可以用整形數(shù)字(-128?+127)作為char變量的值。5?字符串常量:字符串常量就是ー串字符(不限個數(shù)),用雙引號括起來表示,它在空間上會多占用ー個字節(jié)的空間,里邊放上、。,表小字符串結(jié)束。字符串常量的空間占用是有效字符+1??捎胹trlen()去探測具體的字符串常量或變量有效字符長度。對于字符串常量可以用sizeof(字符串常量)去直接探測空間占用情況。注:strlen()是ー個函數(shù),探測也可知道它沒法加數(shù)據(jù)類型作參數(shù)。它的工作原理:由字符串空間首地址一直向后找'。標志,沒有碰到持續(xù)找下去,直到碰到,即使變量空間越界也不管。一串字符也可以是中文,使用的字符集可能會有:3個字節(jié):Utf-8國際共用,2個字節(jié):gb2312簡體中文,Big5繁體,GBK繁體較多,簡體也能用!個字節(jié):ASCII英文字母+法語,德語,俄羅斯語等西方的單字符內(nèi)容5.地址常量(指針常量)變量在內(nèi)存里的空間有對應的地址。我們可以用地址常量來引用這些地址:intiVal;&iVal&在這里表示取地址符,作用是取出變量(或者函數(shù)或者其它數(shù)據(jù)結(jié)構)的首地址。如何輸出地址值:pintf("%p”,&iVal);選做作業(yè):把ー個字符串常量"ilovechina!“把它全部變成大寫的方式輸出“ILOVECHINA!”。ps:?;A的可以寫偽代碼。ぐ解決方案二.運算符單目,雙目,三目單目:i++-i ~i!i雙目:即運算符位于兩個表達式之間a+ba+3三目:1?printf(“true”):printf("false”).賦值運算符二(它不是數(shù)學上的簡單的等式x=3+l/2*x,數(shù)學上x=6。但是C里intx=l;x=3+l/2*x;x=3)<注意區(qū)分賦值和例始化的異同,(初始化出現(xiàn)的情況:a.變量定義時給值,b.函數(shù)參數(shù)值傳遞)//inti=0;//ぐ這是初始化(伴隨定義過程中給值或者說變量剛分配好空間即給值)〃i=3;〃ぐ這就是賦值:將變量的舊有的值(不是垃圾值)清除,〈先了解〉動態(tài)空間的指針變量還可能把舊的空間回收(C++里的對象的賦值),再分配ー個新的空間,再在這個新空間里給上新值.賦值語句:把某個常量或變量或表達式(包含有返回值的函數(shù))的值賦值給另ー個變量。它表示“等于“,而不是“是否相等“。它的符號是”二”,而不是“=="不同于數(shù)學上的:xA2+yA2=zA3x+3=5(左邊表達式與右邊表達式相等)數(shù)學上的這些方程式可以這么表示:xA2+yA2==zA2x+3==5被賦值的變量我們稱為左值,一般它出現(xiàn)在賦值語句的左邊;產(chǎn)生值的常量,變量或表達式我們稱為右值,一般它出現(xiàn)在賦值語句的右邊。常量一般都只能作為右值。(函數(shù)返回值其實也是ー種常量,有返回值的函數(shù)也是ー個表達式,函數(shù)有函數(shù)運算符"()”).算術運算符+單目正ー單目負取反,有點類似!,ー用在數(shù)學運算上注意:單目+,一都是作用在表達式結(jié)果值上面+-*/(除數(shù)不能為0) %(取余,除數(shù)不能為0)7%3=111%3=215%3=016%3=1取余應用:表達了一個有限范圍值的概念。范圍在〇?(除數(shù)一1)之間。.邏輯運算符:真、假(因為真所以真,因為假所以假)&&邏輯與都成立為真I!邏輯或只要有真就是真!邏輯非將對象假的變真,真的變假(不會改變實際涉及變量的值,跟?類似,不像自增自減)C語言沒有BOOL類型,只有非。為真(別忘記負數(shù)),。為假邏輯短路現(xiàn)象.關系運算符:(關注:大小結(jié)果:真假〈整型1,0>)><>=<=!===在條件判斷語句里,盡可能將類似if(a==32);這樣的語句反過來寫,寫成if(32==a);以杜絕可能存在的隱患.自增自減運算符++a;-a;變量自身先加減1,后參與其它運算(一次運算)a-;a++;變量自身先參與其它運算,整個表達式運算結(jié)束后再變量自身加減1(兩次運算)在復雜表達式里,對它的理解(a+++b-c)注意不要進行++a++;運算冃旨,厶イ故"馬:++++++--+++H ++++++a;.復合賦值運算符+二加法賦值ー=*=/=%=?=?=&=1=A=普例:a+=2;==>a=a+2;完全等價?不是a+=2;+:只是進行ー次運算a=a+2;先進行a+2,結(jié)果存在臨時空間(只讀)里,后再把臨時空間里的值取出來賦值給a.由此推向其它復合賦值運算,都是同理.條件運算符v表達式1>?〈表達式2〉:〈表達式3>先進行表達式1的運算或調(diào)用,如果邏輯上成立或為真,則執(zhí)行表達式2的語句,否則執(zhí)行表達式3.逗號運算符<〈表達式1>,〈表達式2〉,〈表達式3〉,〈表達式4>,v表達式5>...>;Z=(a=O,—b,++c,d=3,printf(?Hi4t),while(a!=l)i++,e=5,f,++++-g);intab,c=9,d,e,f;〃不是所有用到逗號的語句都是逗號表達式多個表達式可以用逗號分開,其中用逗號分開的表達式的值分別結(jié)算,但整個大的表達式的值是最后一個表達式的值來代表。逗號表達式運算優(yōu)先級最低.位運算符(信號燈游戲)&位邏輯與兩個操作位都為1オ是1I位邏輯或只要有一個為1就為1(包含了兩個都為1也為1的情況)八位邏輯異或只要不同就為1(如果都相同,不管是不是1,都為0)〈位邏輯異〉?縣卜(位取反),運算結(jié)果是作用在表達式結(jié)果值身上,而不是操作數(shù)自身(不是所有的單目運算符都會作用在操作數(shù)身上)??左移右移跟乘除的關系左移n位等價于乘以2的n次方。右移n位等價于除以2的n次方。符號位是不會跟著移動,碰到最高位,會截斷.運算符的優(yōu)先級和結(jié)合性結(jié)合性:又稱為計算順序,它決定組成表達式的各個部分是否參與計算以及什么時候計算(大家優(yōu)先級ー樣時:自左向右運算,還是自右向左運算)優(yōu)先級 運算符 結(jié)合性最高()//Func(inta)數(shù)組口->.(連成一體) 自右向左I !~++--+-*(取內(nèi)容)&Qzeof (單目)自右向左I */% (雙目) 自左向右I +? 自左向右自左向右I ==!=>=<= 自左向右I&人1(雙目) 自左向右I &&優(yōu)先11 自左向右I?: 整體自右向左(內(nèi)部自左向右)\/ =+=-=*=/=%=&=A=|=?=?=(變態(tài)雙目,三目)自右向左最低,逗號 (多目) 自左向右助記:目數(shù)越多,優(yōu)先級越低結(jié)合性由目數(shù)升級,不斷由自右向左,再自左向右不斷切換特殊的:a+b*(c+d) 圓括號表示把所括內(nèi)容當成一個表達式處理課堂作業(yè):接收用戶輸入的任意值,并由用戶指定目標數(shù)在二進制形態(tài)下需設置為。的位(二進制位第幾位,),并將運算結(jié)果值輸出。01110110第5位數(shù)的起點位是第〇位11011111按位與 0010000000000001不能按位異(或)01010110三.表達式和語句表達式:它是由常量,變量,運算符組合(有返回值的函數(shù)也可以是組成表達式的元素)而成的語句,計算后會返回一個結(jié)果值。表達式可以嵌套使用,表達式內(nèi)可以又有表達式,例逗號表達式。不是所有的語句都是表達式,是不是表達式要看有沒有結(jié)果值.表達式返回的結(jié)果值是有類型的。表達式隱含的數(shù)據(jù)類型取決于組成表達式的變量和常量的類型,或函數(shù)返回值的類型。一般情況下,表達式內(nèi)有多種類型時,以最復雜的那個類型為準,進行強制類型轉(zhuǎn)換(兩個結(jié)論)。每ー個表達式的返回值都具有邏輯特性:非。為真,0為假。(C++オ有邏輯類型:bool)表達式結(jié)果值也是會有常量空間用來存儲值.變量、常量,表達式,函數(shù)inta=l,b=a,c=a+b;//O整體是語句,局部是表達式inta=b,b=l,c=b+a;//X雖然b已有內(nèi)存空間,但沒有類型,不能準確稱為變量,還不能拿出來使用.(后果:早產(chǎn)兒)V分配空間自右向左,初始化自左向右〉棧:后進先出想象一下ー個裝大米飯的碗語句:一般以分號作為結(jié)束標志的都是語句,表達式是語句中的ー種特殊情況..標準輸入語句(也是ー種表達式,因有返回值)助記:用戶的鍵盤輸入和scanf函數(shù)的正式調(diào)用處理,是兩個獨立的過程.鍵盤輸入時系統(tǒng)是把用戶輸入先存入到ー個輸入緩沖區(qū)空間,最后看用戶有沒有輸入ー個scanf格式化字符串參數(shù)中多出來的一個回車符(如果字符串中有\(zhòng)n,都不會馬上進入第二個過程的處理)Scanf和printfー樣,不會對參數(shù)做真實的類型轉(zhuǎn)換,只會看%后邊的類型說明符る%d情況下,用戶輸入字符,不會被轉(zhuǎn)成整型數(shù)//scanformatintscanf(く格式化字符串〉,く可寫變量地址表〉);int返回值表示返回函數(shù)實際接收到的正確參數(shù)的個數(shù)〃123a23.2a\n

scanf具有輸入緩沖區(qū),未處理完的用戶錄入的數(shù)據(jù),可供后面第二個scanf()使用空白字符〈空格,回車〉,多個會被轉(zhuǎn)成一個,起到分隔作用。注意:空格,回車在某些情況下又是在充當字符。非空白字符,像下面的格式化字串里的逗號,也可以起到分隔符的作用(要求用戶輸入的是字符串%s時,那逗號會被字符串參數(shù)吸收,容易引發(fā)大錯誤。怎樣避免?不要加字符分隔符,scanf碰到空格,字符串輸入會自動結(jié)束)inti;charc;floatf;scanf("%d,%c,%ド,〃等價鍵盤錄入:123,¢32.3scanf("%d%c%ド,&i,&c,&り;〃沒空白,也會等價于下面的語句scanf("%d%c%ド,13.88888\n空白字符,非空白字符及無字符在scanf格式字符串里都是來用起所輸入?yún)?shù)分隔作用,格式要求的作用格式轉(zhuǎn)義符號作用格式轉(zhuǎn)義符號作用%d%hd%ld十進制有付號整數(shù)int,short,long%u%hu十進制無符號整數(shù),無符號短整型%f%lf%llf單精度浮點數(shù)ノ雙精度/長雙精度%s字符串(錄入的字符串仃空格,scanf就會停止繼續(xù)給值字符串參數(shù),可用fgets()...)%c單個字符%p指針的值,地址值(更多用在print。%x十六進制數(shù)%oハ進制數(shù)加上-表示左對齊,默認是右對齊printf()>scanf()下的格式用法:TOC\o"1-5"\h\z%5df12 —12%-5d—12 12—%05d—12 00012%8.3f912.0 12.000注:-,前綴〇 在scanf里基本沒作用。當在格式說明符之間加入?時,表示忽略scanf("%?3n]%*c");〃忽略用戶輸入的一切直到碰到換行符(回車),再忽略換行符用戶錄入緩沖區(qū):“adsfkaqweruvswr'n"%*c,“'上面語句的作用是清空用戶錄入緩沖區(qū)的數(shù)據(jù),當緩沖區(qū)有不單有至少ー個普通字符,在后面還有\(zhòng)n,可用scanf(,,%*[A\n]%*c”);scanf后邊推薦加上:while(getchar()!='\n,);可準確的清空緩沖區(qū)(一定要有一個、n)scanf()要求有一個回車符作為scanf調(diào)用返回標志(不是用戶每次錄入回車scanf都會返回,有可能被字符型參數(shù)吸收),但是回車符并不會給scanf清除吸收(回車符在特定條件下也會被吸收,如剛好對應%じ或%s,如果沒有被吸收,就是起分隔或觸發(fā)調(diào)用返回的作用).如果scanf在ー個循環(huán)體里,a)ー開始它就得不到正確的參數(shù),則會死循環(huán):while(1)scanf(,,%d,,,&iV);//b)用戶如果直接回車scanf不一定會返回,0參數(shù)對于非字符參數(shù)沒有意義.還是會等待用戶輸入至少ー個非回車/非空格字符.fflush(stdin);〃無條件的強制清除一切輸入緩沖區(qū),局限性:相當于拿掉緩沖區(qū),只能在VC下這么用。fflush(stdout);〃強制輸出緩沖區(qū)的內(nèi)容。在UC,VC下都有作用。.標準輸出語句intprintf(〈格式化字符串》,〈參數(shù)表〈表達式>>);int返回值表示所輸出的字符串字節(jié)長度(GB2312,BIG5,GBK中文占2個字節(jié),UTF8:中文占個字節(jié),英文及符號占用1個)一切函數(shù)的形參的調(diào)用順序是自右向左(還是棧的概念,后進先此右進先出)符號作用〃12:30:35\r 置同行最左,后面緊隨文字采覆蓋方式\xhh表示acsii碼用16進值表示3,條件語句if(表達式){語句1;語句2;}if(表達式)語句1;elseif(表達式2)語句2;else語句3;if(表達式1)〃條件是有權重層次的,進階關系(if(表達式2)…elseif(...)…else…;〃只有條件!成立オ可能進行條件2之類的判斷elseif(…)…;〃可以是平行if(.if(…)…;}〃推薦這么用###以下方式不推薦同學們使用,會讓程序?qū)哟慰勺x性變得特別差if(表達式!)if(表達式2)語句1;else語句2;〃近水樓臺先得月這個語句與表達式2的if語句相配套else語句3;switch(整型變量或整型常量或整型表達式)〃a(case1:語句1;...;語句n;break;〃默認多個語句可以不加花括號case2:inta=0;語句;break;case3:{inta=l;語句break;}〃什么情況要用花括號〈作用域〉,不要干擾到其它條件的處理代碼Z/b語?J1;...;造句n;break;default:語句!;...;語句n;)//case1:case2:這些本質(zhì)上還是ー個標號花括號:1.可組合多個語句。把各個小語句組合成大的ー個語句,也稱為復合語句,但不是表達式。.限制花括號內(nèi)的語句的作用域(影響區(qū)域)。.花括號內(nèi)外如果有同名的變量定義時,內(nèi)部的會屏蔽外部的同名變量.循環(huán)語句和循環(huán)控制JumpHere:for(〈起始值設定表達表或語句》;〈條件表達式或語句〉;〈增量表達式或語句〉)//;這里不加;〈起始值設定〉不是〈初始化〉:C這里不能加int之類的定義表達式JumpHere2:for(〈初始化〉;;〈增量,)(for(;;)/*無條件循環(huán)?/{if(l)break;gotoJumpHere;}if(l)continue;〃本循環(huán)緊跟的代碼不會被執(zhí)行,而是直接進入下ー輪的循環(huán)if(0)break;)if(l)break;)JumpHere3:跳出范圍:continuev跳出本次循環(huán)〉v=breakv跳出ー個循環(huán)〉v=gotov可跳出多個循環(huán)〉.while(條件表達式)語句;if(l)break;do〃不管條件表達式成不成立,都先執(zhí)行一次,再判斷要不要再次循環(huán)(語句;}while(條件表達式);〃這里要加;作業(yè)1:求兩個整數(shù)的最大公約數(shù)。(最高效的算法)〃8,4最大公約數(shù)是4作業(yè)2:判斷一個整數(shù)是不是素數(shù)?!ㄖ荒鼙?和本身整除的數(shù)是素數(shù)做項目的兩大原則:專業(yè)體現(xiàn)在細節(jié)。要注意出錯細節(jié)的處理!用戶是個頑皮的小屁孩!代碼要健壯,要能容錯!四.數(shù)組是ー組同類型的變量的集合體,在內(nèi)存里連續(xù)存儲分配。1.數(shù)組聲明(聲明不一定是定義,主要用來預告變量等相關的類型定義信息,在代碼上后出現(xiàn)的對象的定義如何提前被前面的代碼去調(diào)用就是依靠聲明,聲明沒有初始化過程,在ー個程序里,聲明可以重復出現(xiàn)多次,有時聲明和定義格式上是ー樣)和初始化2,如何訪問數(shù)組元素a.用下標運算符口去訪問內(nèi)容(有些情況還能訪問數(shù)組的地址)b.也可以用類似指針(有數(shù)據(jù)類型的內(nèi)存地址)(結(jié)合*取內(nèi)容符號的訪問方式)的方式去訪問數(shù)組元素3,字符數(shù)組:ー個字符數(shù)組不一定是一個字符串字符串:ー序列連續(xù)排列的字符組合,并以、0為結(jié)束標識。字符組合不一定是字符串。輸出字符數(shù)組時要特別小心,如果不能明確里邊的內(nèi)容是不是字符串,最好不要用printf的%s去直接輸出數(shù)組。可用(FOR(i=0;i<sizeof(ary);i++)printf("%c”,ary[i]);)去打印字符數(shù)組。一般只能存一個字符串,雖然多個也可以存,但是輸出時只能以字符為單位輸入,即上述for..printf方式。作業(yè):得到用戶輸入的任意英文字符串,把它小寫的全部變成大小,并且倒序輸出上ー不要出現(xiàn)緩沖區(qū)有多余內(nèi)容,并且含有空格也要能處理,要標準getchar():一次獲取用戶輸入的ー個字符(包括空格或回車等等)vwhile.getchar組合與scanf配套使用時才能精準表示清除緩沖區(qū)的用義,其它地方有可能變成是循環(huán)等待用戶輸入,因為緩沖區(qū)有可能為空〉strlen();獲取字符串的有效長度(不含、。),如果要用它表示字符串實際在內(nèi)存中的占用情況,需:charstr[]=^^abc^^;intiStrLen=strlen(str)+l;對ー個字符串的訪問,其實是在訪問它的首地址.多維數(shù)組多維數(shù)組不是用來存多種不同用意的數(shù)據(jù),而是用來有條理的管理多個同類型的數(shù)據(jù)重點把握:a.層次關系的把握,b.地址運算的規(guī)律.字符串數(shù)組(特殊二維字符數(shù)組,要求每ー個行存ー個字符串,末尾要加、。)〈盡管字符數(shù)組也可以在里邊保存多個的字符串,但是畢竟是ー種特殊的情況,我們所說的字符串數(shù)組,是指非常方便的用于存儲多個的字符串的這么ー種用意,用來處理多個字符串的二維數(shù)組。每一行空間里至少會有一個、。..putchar(putc)/puts/(fgets)/strcpy(strncpy)/strcmp/strlen(只能用于字符,字符串操作)char*strstr(constchar*bigstr,constchar*substr)〃在ー個bigstr字符串里查找ー個substr小字符串,比較時不包含'。,如果找到就返回所找到的字符組合的首地址,否則返回NULLmemset內(nèi)存賦值或清空memcpy內(nèi)存拷貝(不限數(shù)據(jù)類型)作業(yè)(小項目):實現(xiàn)ー個查找指定子字符串find_str的函數(shù),如果找到子字符串則將目標字符串中的子字符串替換成指定的另外一個字符串desc_str,例如:abcdefg中找def,找到后替換成DEF,最后整個字符串就變成了:abcDEFg.如果沒有找到指定的子字符串,則返回一1值,否則返回一個在字符串obj.str中的所找到的首字符對應的下標值intstrReplace(charobj_str[],charfind_str[],chardesc_str[])//charstr[50]=^^abcdefg^^;//intpos二strReplace(str,"deF',"DEFFFFFA”);〃基本要求:實現(xiàn)等長替換〃進階要求:實現(xiàn)不等長的替換(內(nèi)存操作函數(shù))〃不需理會obj_str的空間是否夠用的情況。五.函數(shù)具體邏輯功能(與數(shù)據(jù)〈局部靜態(tài)變量,)的載體,通過輸入?yún)?shù),進行內(nèi)部黑箱操作,最后產(chǎn)生一個結(jié)果〈直接消化,或者返回值(可能一個數(shù)據(jù),也可能是一批數(shù)據(jù)??赡芡ㄟ^return(可以返回普通變量,指針或結(jié)構變量〈ー批不同類型的數(shù)據(jù)》),也可能通過形參的間接方式〈如形參是指向內(nèi)存的ー個首地址,一般是數(shù)組〉)給調(diào)用用戶,.函數(shù)聲明和調(diào)用聲明:是對編譯器宣告有這么ー個函數(shù),它的返回值及形參變量的類型是怎樣的,函數(shù)名是什么,即使函數(shù)體編譯器還沒有見到,它也可以先對調(diào)用這樣的函數(shù)的語句編譯放行。隱式聲明:如果ー個函數(shù)被調(diào)用前連聲明都沒有,C編譯器也能放行,不過返回值類型就只能是int類型。(C++不再支持隱式聲明)函數(shù)調(diào)用:運行使用指定函數(shù)名的函數(shù),一般伴隨參數(shù)的傳遞和返回值的接收過程(不是必需)。(主調(diào)函數(shù)就是用來調(diào)用其他函數(shù)的。被調(diào)函數(shù)是被運行調(diào)用的函數(shù))(調(diào)用函數(shù)后它的返回值的接收不是必需的,即使沒有接收也沒有關系,這個返回值會存在臨時空間里,所以也可以把有返回值的函數(shù)看作是ー個對應返回值類型的常量,返回的所指向的空間如果不是只讀(間接),結(jié)合一些運算符,如?,構成一個表達式還能充當左值:*func()=123;)C語言中函數(shù)名在程序中一般必須是唯一的。也必須遵守標識符命名規(guī)則。(C靜態(tài)函數(shù),被不同的文件包含時,有時也可以允當不同的函數(shù),因為作用域不同。C++函數(shù)重載:允許多個的函數(shù)名相同,但要求形參類型或排列順序不同)v函數(shù)名,變量名,數(shù)組名,指針名都沒有自己的標識符存放空間,包括后邊C++的引用名也ー樣,它們都只是給人看的,編譯器不需要這些,正如計算機只看二進制,不看十進制ー樣,UNIX一切函數(shù)都能調(diào)用自己,函數(shù)名代表了函數(shù)的首地址。(遞歸調(diào)用)函數(shù)的格式:聲明:返回值類型函數(shù)名(形參列表v形參類型1,形參類型2…〉)?〃川.以沒有形參變量名。聲明作用只是告訴系統(tǒng)可以怎樣去調(diào)用這個函數(shù)聲明是給計算機看,它只需了解待調(diào)用函數(shù)的具體類型,而不需要標識符。只有參數(shù)類型,沒有形參變量名的稱為啞元,它只提供類型信息,眼前不需要使用,常用于聲明或提供區(qū)別及兼容作用。函數(shù)的定義實現(xiàn)一般必須要有形參變量名,沒有的話就無法得到主調(diào)函數(shù)傳來過來的實參副本數(shù)據(jù)。void:沒有返回值,可以放在返回值的地方,也可以放在函數(shù)形參列表處;void*未確定實際數(shù)據(jù)類型的指針變量,它不經(jīng)類型轉(zhuǎn)換要做地址運算,就是放大(縮?。?個字節(jié)(內(nèi)存空間基本單位就是1個字節(jié))。定義實現(xiàn):返回值類型函數(shù)名(形參列表V形參類型變量1,形參類型變量2..〉){ー個或多個語句;}.函數(shù)參數(shù)的傳遞和值返回函數(shù)的形參列表內(nèi)的變量調(diào)用順序自右向左,形參變量列表的空間分配是自左向右(跟函數(shù)體內(nèi)的多個變量的空間分配及初始化順序是相反的)。函數(shù)實參向形參的傳遞和返回值本質(zhì)上是值的拷貝(即使實參變量名與形參變量名ー樣,也不是同一個變量),各個實參類型(如果能類型轉(zhuǎn)換也可以,不是所有類型都能相互轉(zhuǎn)換unsigned和float)和排列順序必須與函數(shù)定義的形參列表一致??截惸繕耸菍崊?拷貝的目的地是形參變量。形參變量得到的值其實是ー個實參變量值的副本,是ー個克隆體(存值的空間不同)。變量在函數(shù)體中是自下向上,自右向左分配空間。變量在函數(shù)體中的定義及初始向是自左向右。與形參的兩種順序剛好相反。當函數(shù)定義沒有返回值類型,甚至連void也沒有,這時C語言會默認處理為返回int翹(C++沒有返回值的一般是特殊函數(shù),如構造函數(shù)和析構函數(shù)),例:func();fintfunc();C不像C++,可以完全沒有返回值類型(void其實也是ー種類型)3?可變參數(shù)的函數(shù)實現(xiàn)類似printf(),scanf()這樣的函數(shù),里邊的參數(shù)個數(shù)是不定(限制條件:至少要有一個確定的參數(shù)〈指定數(shù)據(jù)類型的參數(shù),在形參列表里靠左放置,)。%d%s%c%f〃告訴可變參數(shù)類型是什么:1每一個可變參數(shù)類型2.整體到底有多少個可變參數(shù)一般參數(shù)列表是確定的,定義時有多少個形參,調(diào)用時就必須提供多少個實參,順序要一樣,指定實參與形參對應的數(shù)據(jù)類型也要一致(可強制轉(zhuǎn)換類型也可以)。實現(xiàn)可變參數(shù)函數(shù),需要用到ー個類庫,頭文件是stdarg.hva」ist結(jié)構類型〃可用來定義ー個存儲指向可變實參列表的結(jié)構變量va_start,va_arg,va_end二個なva_start:告訴VA類庫到底可變參數(shù)是由哪一個固定參數(shù)之后オ開始(后邊都是可變參數(shù),va_start是用來定位可變參數(shù)的開始位置)。va_arg:獲取當前的可變參數(shù)結(jié)構變量里的ー個實參值,并且結(jié)構變量內(nèi)部的位置指針向后自動推進一位(下一次再調(diào)用va_arg,得到的就是下ー個參數(shù)值)。va_end:結(jié)束操作,釋放資源???:是ー個可變參數(shù)運算符,表示可接收不定參數(shù)(0?無限個)六.變量的作用域和存儲類型LC的標識符作用域就三種:局部(不單指函數(shù),還包括內(nèi)部的像循環(huán)體等{}內(nèi)的作用域)全局(一般指放在函數(shù)外邊的ー些變量):在多個互不include的文件中都有作用,不過這個作用要靠extern聲明去揭示文件〈沒有被include的文件オ是不同的文件,:作用域只限文件自身內(nèi)部。作用域:它決定了程序中的哪些語句可以使用該變量,或函數(shù),結(jié)構體等等對象2.各種同名變量作用域的優(yōu)先順序:下層花括號語句體〉,上層函數(shù)體〉〉全局/文件(優(yōu)先級高的屏蔽低的同名變量)2.2生命期:全局〉=文件〉二函數(shù)〉:下層花括號語句體3.變量的存儲類型(生命期,作用域)自動(auto)〈生命結(jié)束時,有系統(tǒng)善后,自動由系統(tǒng)回收內(nèi)存空間資源,原理:只是登記這片內(nèi)存空間已是空閑狀態(tài),并沒有去清除空間所存的內(nèi)容值。編譯器默認變量就是auto類型〉。靜態(tài)(static)〈生命期如本進程一樣長,靜態(tài)不是只讀的意思,表達了一個生命如進程的概念,如果它放在函數(shù)外邊,變量加了static就是在限定變量的作用域為本文件的代碼中會有作用。另外如果static加在函數(shù)的局部變量里,則它的作用域就只限在該函數(shù)內(nèi)部〉,外部(extern)〈生命如進程,作用域是全局的,不限具體哪ー個文件,但是引用這個變量的文件需要聲明有這個全局變量,就是用extern聲明當前這個全局變量是由外部文件的全局區(qū)域定義的這么個全局變量〉,寄存器(register)〈除了程序無法得到其內(nèi)存地址外,其余和自動變量ー樣,有遞交申請為VIP身份這樣的含義〈不一定能申請成功,不成功則作為普通變量,選做作業(yè):使用可變參數(shù)技術,實現(xiàn)各個可變參數(shù)成員的值的累加效果,最后把等式顯示出來,并打印累加的結(jié)果值const表示只讀,加了這個關鍵字,變量的空間就只能讀不能寫,那唯一的一次寫的機會是在變量的初始化時volatile易變的(實時更新的),不需要進行優(yōu)化處理,有變化,不要保留,馬上反應七.遞歸函數(shù)遞歸的意思是函數(shù)自己調(diào)用自身(直接方式),或者在自己函數(shù)調(diào)用的下級函數(shù)中又調(diào)用自己(間接方式)。//F(){F();}//F(){F();F();}//F(){E();} E(){F();}〃可讀性差,變態(tài)的,遞歸:可拆分為遞(向下層傳遞參數(shù))和歸(函數(shù)不再向下傳遞時會ー層ー層的返回)兩個過程〈類似ー個人在大廈里爬樓梯,爬到頂層了沒事可干,再ー層ー層爬回地面(注意層次不要搞混),遞歸與循環(huán)的異同,請參考示圖。寫遞歸函數(shù)需考慮的要素:a,怎樣取ー個變量或多個往下遞歸(不是絕對,但是推薦這么做,變量在傳遞中要有變化)b.怎樣終止遞歸,要設置ー個合理的終止條件(原來的規(guī)律不能成立,函數(shù)遞歸層的代碼不再重復)c.遞歸過程中的臨時或中間結(jié)果怎樣保存(例:遞歸函數(shù)的靜態(tài)局部變量,或用ー個變量參數(shù)將它再傳下去,變量可以變得更高效和精簡),不是每一個遞歸都需考慮這個情況。注:遞歸函數(shù)沒有限制函數(shù)體里可以調(diào)用多少次自身,但是物理硬件決定了他還是會有一個極限,盡量不要超過26萬次(UNIX)在ー個遞歸函數(shù)體內(nèi)部可有多種的遞歸調(diào)用副本,每ー個副本傳遞的參數(shù)不同。例:func(n){if(n<l)return;func(n-l);func(n-2);func(n-3);return;}遞歸思維(怎樣用遞歸解決有規(guī)律可循的一些問題)A.找到ー個有規(guī)律可尋的問題的解決方案的ー個典型的環(huán)節(jié)(層面),只考慮這ー個層面的代碼應該如何實現(xiàn)(由點到面,這個點是有普遍代表性的)B.在這一個層面里只考慮a.參數(shù)變量如何設置,如何變化傳遞。b.終止條件語句如何寫,也就是不再遵守典型規(guī)律的那些情況如何變成代碼上的終止條件。c.仔細調(diào)整一下需輸出文字信息放在遞的過程和歸的過程的情況,不要出現(xiàn)重復打印的情況結(jié)論:遞歸思維本質(zhì)特點是暫時忽略各個層次實現(xiàn)的不同細節(jié),而只關注固定的某ー環(huán)節(jié)的較大過程實現(xiàn)即可(有規(guī)律性的.例外情況不會太多的問題,適合用遞歸來實現(xiàn))作業(yè):實現(xiàn)漢諾塔的功能,將由小環(huán)到大環(huán)堆放的多個環(huán)(大環(huán)上邊可放小環(huán),小環(huán)下邊不能放比它小的環(huán))從ー個位置搬到另ー個位置的算法,另外只提供ー個緩沖位置(整體就三個位置空間)。把搬運具體環(huán)(第幾環(huán))的過程打印出來(文字清單輸出舉例:將第幾個環(huán)由哪ー個位置搬到哪ー個位置。將第幾個環(huán)由哪ー個位置搬到哪ー個位置。。。),第N環(huán)比第N-1環(huán)要大intmain(intargc,char*argv[])ハ.預處理預處理過程掃描源代碼,對其進行初步的轉(zhuǎn)換,產(chǎn)生新的源代碼提供給編譯器??梢婎A處理過程先于編譯器對源代碼進行處理。(預處理不是真正的程序:預處理處理的是文本,產(chǎn)生的結(jié)果仍然是文本)預處理指令是以#號開頭的代碼行,結(jié)束不需要加;號。指令用途#空指令無任何效果,類似空行#include包含一個源代碼文件#define定義宏#undef取消已定義的宏〈后邊方便可以再次使用同名的宏標識符再去替代其它的內(nèi)容〉#if如果條件為真,就編譯下面代碼(一般跟常量或宏)#else跟#if等條件判斷預處理指令配套使用,相當于程序里的else類似作用。上面條件都不成立,則編譯下面的代碼#ifdef如果宏已定義,則編譯下面代碼v不關心宏有沒有值,或值是真還是假,只要有定義這么ー個宏,ifdef就認為是真,#ifndef 如果宏未定義,則編譯下面代碼#elif 如果前面的#if條件為假,當前條件為真,則編譯下面代碼

(一般跟常量或宏)velseif>#endif結(jié)束ー個#iL..#else條件編譯塊或#ifndef#ifdef#endif存在這ー個預處理命令是因為預處理不支持{}預處理符號#error 停止編譯并顯示錯誤信息#line 可以將#line下文代碼重編行號#運算符 稱為字符串轉(zhuǎn)換運算符(要用在預處理語句里):##運算符 (用在預處理行語句)程序調(diào)試需要用到的宏指令(系統(tǒng)預定義好的宏)_LINE_#line指令可以改變它的值,簡單說,編譯時,它包含程序的當行行數(shù)FILE指代代碼所在的文件名FILE_FUNCTION_指代當前正在運行的函數(shù)_DATE_ 宏指令表示源文件被翻譯到正式代碼時的日期(字符串)_TIME_ 程序編譯的時間(字符串)_STDC_ 如果_STDC一已經(jīng)定義,如果編譯器是用GCC編譯代碼,這個宏會為1,如果是用G++或其它編譯,它不為1。_CPLUSPLUS_與標準C++一致的,編譯器把它定義為ー個包含致少6位的數(shù)值。與標準C++不一致,編譯器將使用具有5位或更少的數(shù)值。九.指針(掌握的重點:首地址,因子,層次,不能代表所指向空間的整體占用,ロ/*/&)指針概念1.指針基本概念及其指針變量的定義(指針變量簡稱為指針)指針是這樣ー個特殊的數(shù)據(jù)類型,這個指針變量用來存放其它變量的地址,同時還點明了所指向變量的數(shù)據(jù)類型(讓因子vl字節(jié)單位的倍數(shù)〉有著落〈void?類型因子是1個字節(jié)<1倍〉,內(nèi)存空間最小單位〉)。(a.首地址:獲悉怎樣去操作指定的變量空間b.數(shù)據(jù)類型〈因子》:獲悉地址運算能怎樣進行)〃〇X124fflevー這是ー個!6進制的整型常量還是ー個地址常量???表面看不出//inta,&avー這就是地址常量v一地址常量可看成是一個指針常量〃這里有點明數(shù)據(jù)類型ー個指針變量在內(nèi)存中占用4個字節(jié)。(指針變量的自身內(nèi)容空間不是指指針是int類型,而是剛好它也占用4個字節(jié),指針的類型(為何指針要仃數(shù)據(jù)類型:要確定因子)取決于定義時給定的數(shù)據(jù)類型)char*a;sizeof(a)==?4//a指針變量的自身的內(nèi)存空間有多少char*a=^^abc^^sizeof(*a)=?1〃指針所指向的空間大小(因子),不是取決于空間的內(nèi)容,而是指定定義時的數(shù)據(jù)類型(char)不管指針所指向的是什么數(shù)據(jù)類型,他自身的空間占用就是4個字節(jié)類型標識符?指針變量1,普通變量L?指針變量2,普通變量2; 〃?在這里表示定義指針,修飾只起一次作用?在其它語句表示取空間的內(nèi)容值,獲取變量所在空間。如果這個空間不是只讀的,還可以直接作為左值左值概念本質(zhì):可被改寫的空間才能充當左值void*p;〃未確定數(shù)據(jù)類型的指針,一般沒有辦法直接用,使用前最好做強制類型轉(zhuǎn)換,一般出現(xiàn)在函數(shù)形參或返回值V泛型編程的思路。代碼的復用性增強,。要用時需將它轉(zhuǎn)換為有具體數(shù)據(jù)類型其它指針。Char*p=(char*)malloc(1)'JImalloc返回了一?個已分配好的ー個字節(jié)的空間,這個空間類型未定,所以返回的指針類型是void?我們這里是強制給他轉(zhuǎn)換成char類型。C中規(guī)定,當指針值為〇(NULL)時,指針不指向任何有效數(shù)據(jù),這時可稱為空指針。有時也常用NULL來指示函數(shù)調(diào)用中某些錯誤情況的發(fā)生。指針變量定義,一直到被調(diào)用過程中都沒有給它賦過值。這樣的指針可稱為野指針,他的值是垃圾值。但有時垃圾值對應內(nèi)存地址還是有內(nèi)容。這樣直接去使用非常容易出嚴重問題,所以要避免野指針的情況出來。不指向具體變量地址時,給他賦上NULL不要將一個整數(shù)賦值給指針變量,同樣也是因為指針的因子無法確定,如果值所代表的空間類型并不是指針定義時的類型,這時的使用非常容易出錯2?地址運算(不是簡單的算術運算,還可以是多層面的地址運算〈多維,多級)a.比較:兩個指針指向同一個對象(數(shù)組)時才有意義。b,指針和整數(shù)加、減運算:(放大因子〈具體放大多少字節(jié)取決于指針的類型,會起作用)c.兩個指針變量間減法運算:運算結(jié)果表示元素個數(shù)相差。 (縮小因子會起作用)〈需要指向同一個數(shù)組,并且要層次一致(不要把行的因子和列的進行減法運算》トー.數(shù)組和指針任何能由數(shù)組下標完成的操作也都可以用指針來實現(xiàn)。任何指針能完成的操作如果要轉(zhuǎn)換成數(shù)組下標來實現(xiàn),要依據(jù)具體情況而定,不一定可行。(老夫的錢都是老妻的,老妻的錢不一定是老夫的)(我的就是你的,你的還是你的)a)指向數(shù)組元素的指針〈不要把數(shù)組名的第二屬性(整體空間占用)跟因子混淆起來,因子是單位空間大小〉公式:a[i]==*(a+i)==*(p+i)==p[i]//a是數(shù)組,p是指針其實數(shù)組的下標值就是地址運算要用到的整數(shù)這里的前提:因子必須一致,層次必須一致b)指向二維數(shù)組的指針二維數(shù)組元素的地址int<5][3];a[i][j]==*(a[i]+j)==*(*(a+i)+j)〃注意==(*(a+i))[j]//a是整個的數(shù)組名注意:不要把(*(a+i))[j]寫成?(a+i)[j](ロド標運算符是運算符,優(yōu)先級比*高)下標運算符不一定表示內(nèi)容值,而可能是地址值,所以可以這么認識?,&丄]只是用來表示一個具體的層次問題(多維數(shù)組的層次,例二維數(shù)組兩層:行,歹リ,隱性的ー層是數(shù)組名那ー層,列是內(nèi)容層),?」]是向下ー層運算(最后一層一定是內(nèi)容層,如果不是最后ー層,那得到的將是地址值),&向上一層運算(有時沒有辦法順利推進)。(它取到的永遠是地址值)數(shù)組指針(變量):指針變量指向ー個由n個元素所組成的數(shù)組(把數(shù)組看成是ー個運算單元(因子是ー個數(shù)組類型),跟字符指針,整型指針沒什么兩樣)一般會用數(shù)組指針來指向一個二維數(shù)組,運算時比較方便,它的因子和二維數(shù)組的數(shù)組名的因子ー樣大,所以可以管理二維數(shù)組,能表示的層面有一致性。一個二維數(shù)組指針可以用來管理一個三組數(shù)組intmain(intargc,char*argv[])intmain(intargc,char**argv)有限制的つintmain(intargc,charargv[10][10])只要確保空間是連續(xù)的,因子是一致的,就可指針,數(shù)組互換格式:數(shù)據(jù)類型(?標識符)[n];〃類型?n就是指針的因子在原有因子(數(shù)據(jù)類型)基礎上再進ー步進行放大。比如:將指針放大成具有二維數(shù)組名單位行的跨度(因子),像inta[5][3].那就必須在因子(整型)基礎上再放大3倍,這樣對應的數(shù)組指針定義就是int(*p)[3];如何把一個數(shù)組指針指向一個ー維數(shù)組?看例子十二.字符指針charstrロゴ我是ー個字符串”;char*p="我是ー個字符串”;ー個字符串常量代表了自身的首地址,也代表了他自己整體一個空間占用。(跟數(shù)組名類似)ー維數(shù)組和字符字針在層次上是ー樣的(因子都是1),不同點在于數(shù)組還具備數(shù)據(jù)空間,指針只有地址空間,數(shù)組有第二屬性,指針沒有。十三.指針數(shù)組它是ー個數(shù)組格式:數(shù)據(jù)類型?數(shù)組名E];〃不管是什么類型,因子都是4,因為元素是指針變量〃它比數(shù)組指針變量少了一層主要使用在多個字符串的處理上面。使用字符串數(shù)組(二維數(shù)組)對處理長度不等的字符串效率低,而且有局限性〈長度有限〉。而指針數(shù)組由于每個元素都是指針變量,故通過地址運算來操作各個字符串(行),是十分方便,每ー個指針元素可指向不定長的字符串(字符串與字符串之間的空間存放是不連續(xù)的,也即是說指針數(shù)組語法上雖然可以轉(zhuǎn)換成二維數(shù)組,但邏輯不對,不過可以把它轉(zhuǎn)換成二級指針〈數(shù)組本來就是由指針演變出來的〉)。intmain(intargc,char*argv[])//argumentcount//argumentvariable作業(yè):實現(xiàn)ー個微型的mis(信息管理系統(tǒng)),保存QQ個人資料(姓名,QQ號,性別)??梢越邮苡脩糨斎隥友個人資料,顯示所有的Q友資料項(不定個數(shù)的Q友資料)。用上自動動態(tài)結(jié)構數(shù)組或動態(tài)分配堆容間:unsignedtotal=0;structstudent*pStu=NULL;while(...){…〃接收用戶輸入Q友資料Structstudenttmp={...};〃把用戶的輸入分別列入初始化項目Structstudent*tmpStu=pStu;pStu=(structstudent*)malloc(++total*sizeof(structstudent));memcpy(pStu,tmpStu,sizeof((total-1)*sizeof(structstudent));memcpy(pStu+total,&tmp,sizeof(tmp));if(NULL!=tmpStu){free(tmpStu);tmpStu=NULL;}〃再問用戶是否仍需輸入)〃現(xiàn)實意義:可以實現(xiàn)在未知元素個數(shù)情況下的數(shù)據(jù)存儲。十四.指針函數(shù)和函數(shù)指針L指針函數(shù)(注意不要返回一個局部變量的地址值,不然程序不可能有高品質(zhì),高性能,會有不定時的炸彈隱患。不是說不能定義ー個局部指針變量來返回它所存的指針值,而是說這個指針變量所存的地址值所指向的空間不應該是局部的)當ー個函數(shù)聲明其返回值為ー個指針時,實際上是返回一個指針值給調(diào)用函數(shù)。這樣的函數(shù)可稱為指針函數(shù)。數(shù)據(jù)類型?函數(shù)名(形參列表)2.函數(shù)指針指向函數(shù)的指針包含了函數(shù)的地址,可以通過它來調(diào)用函數(shù)。格式:函數(shù)的數(shù)據(jù)類型ド函數(shù)指針標識符)(形參列表〈可以是啞元〉)把函數(shù)的地址賦值給函數(shù)指針:void(*pfunc)();pfunc二&func;〃后邊不加圓括號表示函數(shù)地址pfunc二func;〃也可不加通過指針調(diào)用函數(shù):(*pfunc)();pfunc();〃如果有實參,也要加上十五.指針的指針(二級指針)指針變量里的值是另ー個指定數(shù)據(jù)類型指針變量的地址,這樣稱為指針的指針二級指針即可以用來表示存儲另ー個ー級指針變量的作用,還可以用來管理一個二維數(shù)組。前者層次只有兩層,后者有三層(層次的劃分看實際應用事實而定)數(shù)據(jù)類型??標識符;TIPS:指針+所指向的空間ッ數(shù)組指針,數(shù)組等對象的層次由類型定義去確定,沒有空間存這個層次關系利用指針的指針可以允許被調(diào)用函數(shù)修改局部指針變量內(nèi)容值〈地址值局部指針實參的所指向的變量或空間的內(nèi)存地址值,和處理指針數(shù)組(注意是變量本身而不是變量給出的數(shù)值)規(guī)律:要修改變量實參的內(nèi)容值,被調(diào)函數(shù)定義形參時注意要在實參類型上再退ー層(由內(nèi)容表現(xiàn)層退到行地址層,內(nèi)容表現(xiàn)層又是指針類型時,即是說形參應該定義成二級指針)十六.指向指針數(shù)組的指針經(jīng)??梢杂弥羔様?shù)組來代替多維數(shù)組(二維數(shù)組)。指針需要關注內(nèi)容:變化因子;地址運算;十七.結(jié)構體(結(jié)構體的使用可看作是ー個大型的普通變層G但是數(shù)組不能這么被用,區(qū)別:數(shù)組元素個數(shù)未定,而結(jié)構成員類型和數(shù)量都已固定)結(jié)構是由基本數(shù)據(jù)類型構成的,并用ー個標識符來命名的各種變量的組合。結(jié)構體中可以使用不同數(shù)據(jù)類型。數(shù)據(jù)庫或電子表格里的ー個數(shù)據(jù)表,應用結(jié)構是比較常見。.結(jié)構說明和結(jié)構變量的定義及初始化struct結(jié)構名〈可省略,只在ー個函數(shù)中使用的結(jié)構,只是用一次,就是臨時結(jié)構,typedef>〃這里是設計出結(jié)構類型(數(shù)據(jù)類型成員標識名;數(shù)據(jù)類型成同標識名2;}結(jié)構變量名;〃分號不能省略結(jié)構的使用:先設計出結(jié)構類型,再定義結(jié)構變量。結(jié)構本身是ー種數(shù)據(jù)類型,跟int,char差不多,只不過它內(nèi)部復合了其它的一些子類型,用結(jié)構類型定義出來的變量跟用int定義出來的變量除了類型不一樣,其它的用法都一樣,在函數(shù)中可以被直接傳遞,也可以被直接返回,不像數(shù)組變量要透過傳遞首地址,交待個數(shù)オ能間接傳遞。struct結(jié)構名:用來定義ー種結(jié)構數(shù)據(jù)類型標識符??蓪?struct結(jié)構名替換成typedefstruct{…}結(jié)構數(shù)據(jù)類型名 ぐ后邊再定義它的變量時,就可以直接:結(jié)構類型名變量名;原先:struct結(jié)構名,結(jié)構變量名typedef關鍵字表示數(shù)據(jù)類型重定義,換名??珊喕蓄愋兔臅鴮?。作用跟原有類型是ー樣的。結(jié)構變量的初始化可像數(shù)組那樣用{}進行初始化。.結(jié)構變量的使用:(結(jié)構變量沒有辦法被直接使用,更多是指調(diào)用結(jié)構變量的成員)主要也是在用結(jié)構變量里的成員進行相關操作。結(jié)構變量.成員變量名.結(jié)構數(shù)組.結(jié)構指針調(diào)用格式:結(jié)構指針つ成員變量名要注意:成員變量不是指針所有的,而是指針所指向的結(jié)構變量實體的成員。調(diào)用格式:(?結(jié)構指針).成員變量名(類似下標運算符的轉(zhuǎn)換,只是這里轉(zhuǎn)換).結(jié)構的嵌套形式結(jié)構里又有結(jié)構成員,有數(shù)組成員等等,C結(jié)構里不能有函數(shù)成員,C++可以。.結(jié)構的參數(shù)和返回值的傳遞:像普通變量那樣進行值的傳遞,而不需要像數(shù)組那樣,傳遞首地址,還需要指針的協(xié)助。還可以直接用ー個結(jié)構變量給另ー個結(jié)構變量賦值。.結(jié)構體的內(nèi)存對齊在默認情況下,為了方便對結(jié)構體內(nèi)元素的訪問和管理,加快處理速度。當結(jié)構體內(nèi)的成員(數(shù)組成員會進行拆分成基本類型)的長度都小于處理器的位數(shù)(32位,4字節(jié))的時候,便以結(jié)構體里面:A.最長的數(shù)據(jù)類型的成員為對齊單位,超過CPU的,以CPU字長為準(32位,4個字節(jié)長)B.保證結(jié)構體內(nèi)相同的連續(xù)數(shù)據(jù)類型空間內(nèi)部不進行對齊(數(shù)組,或多個同類型成員依次定義,中間不夾其他類型成員)C.從節(jié)約空間的原則入手,能湊成一個對齊單位而又不影響B(tài)點的,就以此進行空間拼湊處理D.結(jié)構體的長度一定是最長的數(shù)據(jù)元素的整數(shù)倍。注意:成員地址最好落在偶數(shù)地址上//progmapack(n)結(jié)構體內(nèi)類型相同的連續(xù)元素將在連續(xù)的空間內(nèi),和數(shù)組ー樣。.位段位段是比字節(jié)還要小的單位,它只有。和1的表示方式,單位是位。具體有多少位也就形成了位段。結(jié)構體允許我們給每ー個成員進行空間位段的限定,以達到節(jié)省空間,或局部修改數(shù)據(jù)存儲空間的目的。具體位段使用中的限制,請參考:struct bitdomain.c例子。作業(yè):把上一次的作業(yè)(QQ相關)用結(jié)構來動態(tài)實現(xiàn),在加上一個QQ會員簡介成員(不定長度,但有最大上限)。要求盡可能的動態(tài)壓縮結(jié)構(網(wǎng)絡數(shù)據(jù)包的傳輸)的空間占用。#include<stdio.h>〃工作中的結(jié)構:typedefstruct〃加上其它成員longsize;〃統(tǒng)計個人簡介動態(tài)堆空間長度char*introduce;〃個人簡介max:500K}working_data;〃進程內(nèi)的結(jié)構定義voidtemp=malloc(size);〃動態(tài)分配不能超過結(jié)構的intruduce成員的上限data*data=(data)temp;memcpy(data->introduce.str,size);客戶端/服務器端本地結(jié)構(要把結(jié)構體寫到硬盤):typedefstruct(〃加上其它成員longsize;〃統(tǒng)計個人簡介動態(tài)堆空間長度charintroduce[500*1024];〃個人簡介max:500K要寫進硬盤時不能用指針成員,需要等長的成員空間。為什么不能用指針成員?}local_data;〃進程內(nèi)的結(jié)構定義十八.聯(lián)合表示幾個變量共用ー個內(nèi)存空間,在不同的時間保存不同的數(shù)據(jù)類型和不同長度的變量。而且同一時間只保存ー個。union聯(lián)合名數(shù)據(jù)類型成員名;數(shù)據(jù)類型成員名;)聯(lián)合變量名;union空間使用更接近于realloc(重新分配空間)其長度一般為union中最大的成員變量長度。Union變量:聯(lián)合變量名.成員名Union指針: 聯(lián)合指針つ成員名(?聯(lián)合指針).成員名同一時間只有一個成員變量在起作用。其它成員變量如要使用(不是賦值操作),其實是在進行形態(tài)轉(zhuǎn)換(不是類型轉(zhuǎn)換,值相差不多才是類型轉(zhuǎn)換)。〃把不能類型轉(zhuǎn)換的也能輸出十九?枚舉是ー個被命名的整型常數(shù)的集合。enum枚舉名標識符匚整型常數(shù)],〃整型常數(shù)亦可省略標識符匚整型常數(shù)],〃使用中可把標識符單獨看作是ー個獨立的整型常量(constint,宏)???標識符匚整型常數(shù)],}枚舉變量;enum的使用:直接用枚舉內(nèi)部文本標識符即可,不需要加枚舉變量名。如果枚舉沒有初始化,即省略二整型常數(shù)時,則從第一個標識符開始,順次賦給標識符0,1,2...但當枚舉中的某個成員賦值后,其后的成員按依次加1的規(guī)則確定其值。enumeration二十.堆(HEAP)堆是ー種動態(tài)存儲結(jié)構(樹,可擴展性特別強),實際上就是數(shù)據(jù)段中的自由存儲區(qū),常用于動態(tài)數(shù)據(jù)的存儲分配。它可以不斷進行分配直到?jīng)]有堆空間為止,也可以隨時進行釋放、再分配,不存在次序問題。堆的作用域一般都是全局/靜態(tài)的。動態(tài):是指在程序運行期間確定其空間大小并且可以中途調(diào)整大小。內(nèi)存空間管理:分為代碼段(只讀的)、數(shù)據(jù)段(可讀寫)(靜態(tài)存儲區(qū))、BSS段(靜態(tài)〈有條件的全局〉/全局存儲區(qū))、堆(動態(tài)全局〈必須人工釋放〉存儲區(qū))、自由空間(還未被分配)、棧、遠堆、自由空間cat/proc/具體的pid/maps二H一.其它關鍵字.const被const修飾的變量是只讀的,就是在程序的運行期間,其數(shù)值不能被改變。a.修飾變量初始化這樣的語句constintiVal=30;〃以后iVal就變成了一個常量(只讀變b.修飾函數(shù)形參voidfunc(constintiVal)〃保護形參值在操作過程中不會被改變。忠于使用者,更重要的是可避免很多的誤操作,就像if(i==0)要改寫成(0==i)是同樣的道理。c.const在不同的位置有不同的含義constint*p=iVal;P++;//(*p)++;//const加在數(shù)據(jù)類型左邊限制指針所指向的變量只讀int*constp2=iVal;//p2++; //const加在數(shù)據(jù)類型?右邊限制指針變量自身為只讀2.volatile使用volatile修飾ー個變量就是告訴編譯器,這個變量可能會被未知的因素改變,編譯器對這個變量的訪問代碼不應該進行優(yōu)化。volatile告訴編譯器應該在這個變量被改變的時候,立刻把它寫到內(nèi)存中,讀取這個變量的時候,不使用寄存器里面的備份數(shù)據(jù),而是直接從內(nèi)存的相應地址將這個數(shù)據(jù)讀取出來。(優(yōu)化的副產(chǎn)品:寄存器和內(nèi)存的數(shù)據(jù)不ー定是同步的)num3—)使用:vl>多線程,多進程應用中的共享變量<2>硬件寄存器<3>在ー個中斷服務程序中會訪問的非自動變量二十二.文件操作基本常識文件:指存儲在媒體介質(zhì)上的數(shù)據(jù)集合。(傳統(tǒng)的文件概念)UNIX/LINUX一切偕文件.兩種文件輸入輸出系統(tǒng):a.由ANS!標準定義的緩沖文件(也稱為標準文件流輸入輸出vI/O>系統(tǒng));socket控制臺的標準輸入輸出函數(shù):scanf()getchar()gets()vvfgets?!ǔ藄canf其他的會把回車符吸收。printf()putchar()puts()有關文件的參數(shù)(文件結(jié)構指針或稱流指針),只要用標準設備的流指針代替,這些標準文件的輸入輸出函數(shù)即成為控制臺I/O函數(shù)。設備文件流指針名FilelD

溫馨提示

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

最新文檔

評論

0/150

提交評論