郝斌C語言詳細筆記附源碼.doc_第1頁
郝斌C語言詳細筆記附源碼.doc_第2頁
郝斌C語言詳細筆記附源碼.doc_第3頁
郝斌C語言詳細筆記附源碼.doc_第4頁
郝斌C語言詳細筆記附源碼.doc_第5頁
已閱讀5頁,還剩123頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、郝斌老師的C語言:課堂講解全程動手敲代碼,講解細致,對于重要知識點的講解不厭其煩,是一個難得的C語言入門教程。在這里對老師的辛勤付出表示感謝。郝斌c語言視頻教程概述:課程計劃為什么學習c語 言:Fortran語言主要用于科學計算,在第三代語言中,以1980年為分水嶺,分為結(jié)構(gòu)化和面向?qū)ο笳Z言。Basic語言是vb的前生,pascal語言一般是用于教學。C語言是最重要的,其他的語言一般很少用了。結(jié)構(gòu)化的代表語言是c語言。結(jié)構(gòu)化語言的數(shù)據(jù)和操作是分離的,導(dǎo)致在寫大項目的時候,會出現(xiàn)各種各樣莫名其妙的問題。在面向?qū)ο蟮恼Z言中c+是最復(fù)雜的語言。由于c+語言太復(fù)雜,sun公司對c+進行了改裝,產(chǎn)生了j

2、ava語言。而c#是由微軟開發(fā)的,和java相似,幾乎一模一樣。在高級語言的執(zhí)行速度上,c是最快的,c+其次,而java和c#是最后的。Java和c#流行,主要的一個原因是可以跨平臺。C語言的發(fā)展和過程:C語言的特點:優(yōu)點:代碼量小,速度快,功能強大。缺點:危險性高,開發(fā)周期長,可移植性弱。危險性高:寫同一個程序,在java中會報錯,而在c中不會報錯,為什么呢,因為c認為程序你想怎么寫就怎么寫,c語言認為你寫的程序不是很離譜,他都認為你寫的這個程序有特殊的含義??梢灾苯油ㄟ^,而java則不可以。開發(fā)周期長:c語言是面向過程的語言,面向過程的語言的特點就是在開發(fā)大項目的時候,很容易崩潰,好比蓋大

3、樓,C語言還要造大量的磚塊、鋼筋等結(jié)構(gòu)原材料,而C+ C# JAVA則進行了一定的繼承封裝等操作,相當于原材料直接給你,你只需要用它蓋樓即可?,F(xiàn)在市場上的語言分三塊C/c+:單純的學習c是什么都做不了的。JavaC#可移植性不強:這是針對java來說的,因為java的可移植性太強了,所以就感覺說c的可移植性不強。金山公司最主要是靠wps辦公軟件來發(fā)展的。Wps是c語言開發(fā)的,其安裝包比Office少了10多倍。三大操作系統(tǒng):windows,unix,linuxWindows內(nèi)核是c語言寫的,而外殼是c+寫的。Java永遠不可能寫操作系統(tǒng)。因為java運行速度太慢了。而linux和unix都是純

4、c寫的。操作系統(tǒng)控制了硬件,如果說操作系統(tǒng)的運行速度慢,那么當我們在運行軟件的時候,運行速度會更慢。為什么使用c語言寫操作系統(tǒng)呢,首先是因為c的運行速度快,然后是因為c可以直接控制硬件,而其他語言不可以。沒有指針的語言是不能直接訪問硬件的。C語言的應(yīng)用領(lǐng)域:驅(qū)動一般是用c和匯編來寫的。數(shù)據(jù)庫一般是用c和c+來寫的C語言的重要性: 雖然應(yīng)用場合相對較窄,但貼近系統(tǒng)內(nèi)核,較底層。病毒最基本的是要感染系統(tǒng),數(shù)據(jù)結(jié)構(gòu),c,c+這三門語言是必須要學習的。牛人牛語:怎樣學習c語言要將編程當成一項事業(yè)來經(jīng)營,而不是糊口的工具。多思考,多上機。 不能光看,光聽,而要排錯,調(diào)試。在犯錯誤中成長。參考資料王爽寫的

5、c+也很不錯學習的目標:掌握簡單的算法-解決問題的方法和步驟。熟悉語法規(guī)則。能看懂程序并調(diào)試程序。C語言的關(guān)鍵字: C語言程序的格式:一定要養(yǎng)成良好的習慣:代碼規(guī)范 邊寫邊保存 ,括號成對出現(xiàn),應(yīng)用空格VC6.0軟件操作:新建 保存 關(guān)閉(關(guān)閉空間).cpp是原始文件,可單獨拷貝到其它電腦。第二講:(14)c語言編程必備知識1. Cpu,內(nèi)存條,硬盤,顯卡,主板,顯示器之間關(guān)系。Cpu不能直接處理硬盤上的數(shù)據(jù),必須要先調(diào)入內(nèi)存2. Hello word程序是如何運行起來的。3. 什么是數(shù)據(jù)類型數(shù)據(jù)類型-數(shù)據(jù)的分類,對編程而言,首要考慮問題是數(shù)據(jù)的輸入和存儲。可以分為A:基本數(shù)據(jù)類型:整型整型i

6、nt -4字節(jié) 一字節(jié)byte = 8 位bit短整型short int-2長整型long int-8浮點型單精度浮點數(shù)float:存儲范圍小 -4雙精度浮點數(shù)double:存儲范圍大-8Float 和 Double 都不能保證將小數(shù)完全準確保存。字符char:c語言中是沒有字符串string-1 (區(qū)別于JAVA、C#中有string且C#中 char為2字節(jié))B:復(fù)合類型:就是把基本類型拼湊在一起結(jié)構(gòu)體枚舉 - 實用共用體基本淘汰4什么是變量變量的本質(zhì)是內(nèi)存中一段存儲空間。Int I; i=5; I 是變量,程序向系統(tǒng)申請了一個內(nèi)存單元,在程序運行中,i的值可以改變,但程序結(jié)束后,其所占的

7、空間不是釋放,而是被系統(tǒng)收回權(quán)限。5 Cpu,內(nèi)存條,vc+6.0,操作系統(tǒng)之間的關(guān)系。6 變量為什么必須初始(即賦值)軟件運行與內(nèi)存關(guān)系(垃圾數(shù)據(jù)-9868598658)1. 軟件在運行前需要向操作系統(tǒng)申請存儲空間,在內(nèi)存空間足夠空閑時,操作系統(tǒng)將分配一段內(nèi)存空間并將該外存中軟件拷貝一份存入該內(nèi)存空間中,并啟動該軟件運行。2. 在軟件運行期間,該軟件所占內(nèi)存空間不再分配給其他軟件。3. 當該軟件運行完畢后,操作系統(tǒng)將回收該內(nèi)存空間(注意:操作系統(tǒng)并不清空該內(nèi)存空間遺留下來的數(shù)據(jù)),以便再次分配給其他軟件使用。操作系統(tǒng)一門課中系統(tǒng)分配表中會講到,用1標記表示內(nèi)在是被占用的,用0標記表示是空閑的

8、。綜上所述,一個軟件所分配到的空間中極可能存在著以前其他軟件使用過后的殘留數(shù)據(jù),這些數(shù)據(jù)被稱之為垃圾數(shù)據(jù),所以通常情況下我們?yōu)橐粋€變量,為一個數(shù)組,分配好存儲空間之前都要對該內(nèi)存空間初始化。7 如何定義變量數(shù)據(jù)類型 變量名稱 = 賦予的值;等價于數(shù)據(jù)類型 變量名;變量名 = 要賦予的值;舉例子:int i = 3; 等價于 int i; i = 3;Int i,j;等價于 int i;int j;Int i,j=3 等價于 int i; int j;j=3;Int I =3, j = 5;等價于 int i; int j; I = 3;j = 5;8 什么是進制 逢幾進一我們規(guī)定八進制前面加0

9、(零),十六進制前面加0x。常用計數(shù)制對照表:Printf的基本用法:9 常量在c中是如何表示的當個字符使用單引號括起來,多個字符串使用雙引號括起來(指針、數(shù)組)。在c中,默認是double類型的。在后面加F表示當做float來處理,否則會有警告提示 -丟失部分字節(jié)。10 常量以什么樣的二進制代碼存儲在計算機中?編碼:整數(shù)是以補碼的形式轉(zhuǎn)換為二進制代碼存儲在計算機浮點數(shù)是以ieee754標準轉(zhuǎn)換為二進制代碼存儲字符本質(zhì)實際是與整數(shù)的存儲方式相同,ASII碼標準。第三次課:代碼規(guī)范化可以參考林銳高質(zhì)量c/c+編程代碼的規(guī)范化非常的重要,是學習一門編程語言的基礎(chǔ),代碼可以允許錯誤,但不能 不規(guī)范。

10、例如:成對敲括號 ()加空格于 運算符和數(shù)字之間 I = 1 + 2;加縮進 分清上下級地位。換行-進行功能區(qū)域分隔 or 括號單獨成一行。代碼規(guī)范化的好處1:整齊,別人和自己都容易看懂。2:代碼規(guī)范了,代碼不容易出錯。3:一般的程序可以分為三塊:a: 定義變量b:對變量進行操作c: 輸出值什么是字節(jié)存儲數(shù)據(jù)的單位,并且是硬件所能訪問的最小單位。內(nèi)存中存儲的最小單位是位bit(0或1),但是硬件控制的時候不能精確到位,只能精確到字節(jié)(8位),是通過地址總線來控制的,而精確到位是通過軟件來控制的,叫做位運算符來精確到位的。1字節(jié) = 8 位 1K = 1024 字節(jié) 1M = 1024 K 1G

11、 =1024 M 1T = 1024 G 2G的內(nèi)存條的總空間:2 *1024 * 1024 *1024 * 8 =4*1032不同類型數(shù)據(jù)之間相互賦值的問題不同數(shù)據(jù)類型之間最好不要相互轉(zhuǎn)換。如果需要明白這個知識點,那么需要明白補碼。什么是ASCII碼以char定義變量的時候,只能使用單引號括起一個字符才是正確的。在上圖中注釋的最后一樣是重復(fù)定義了ch的值,是錯誤的,而下面的ch = c是指把c賦值給ch,是正確的。上圖中輸出的值是98(將字符以整數(shù)%d的形式輸出)Ascll碼規(guī)定了ch是以哪個值去保存,ascii碼不是一個值,而是一種規(guī)定,規(guī)定了不同的字符是以哪個整數(shù)值去表示。其它規(guī)定還有G

12、B 2312 UTF-8等。字符本質(zhì)上與整數(shù)的存儲方式相同【字符的存儲】基本的輸入和輸出函數(shù)的用法:第三次課Printf()將變量的內(nèi)容輸出到顯示器上。四種用法輸什么是輸出控制符,什么是非輸出控制符輸出控制符包含如下:Printf為什么需要輸出控制符:01組成的代碼可以表示數(shù)據(jù)也可以表示指令。必須要有輸出控制符告訴他怎么去解讀。如果01組成的代碼表示的是數(shù)據(jù)的話,那么同樣的01代碼組合以不同的格式輸出就會有不同的輸出結(jié)果,所以必須要有輸出控制符。在上圖中,int x =47,如果前面加0(零)048表示的是八進制,如果前面加0x(零x)0X47則表示的是十六進制,而在輸出的時候,則是o(字母o

13、)表示八進制,ox(字母o,x)表示十六進制。非輸出控制符:非輸出控制符在輸出的時候會原樣輸出。Scanf()通過鍵盤將數(shù)據(jù)輸入到變量中有兩種用法:示例:非輸入控制符:在輸入的時候也會原樣輸入。但是強烈建議:在使用scanf的時候,不使用非輸入控制符。給多個變量賦值:需要記住,非控制符需要原樣輸入。如何使用scanf編寫出高質(zhì)量代碼運算符:算術(shù)運算符:加(+),減()乘(*)除(/)取余(%)關(guān)系運算符:, =, , 關(guān)系邏輯賦值。取余的結(jié)果的正負只和被除數(shù)有關(guān)。第四節(jié)流程控制(第一個重點):1 什么是流程控制程序代碼執(zhí)行的順序。2 流程控制的分類順序執(zhí)行選擇執(zhí)行定義:某些代碼可能執(zhí)行,可能不

14、執(zhí)行,有選擇的執(zhí)行某些代碼。分類:ifIf最簡單的用法:如果想控制多個語句的執(zhí)行或者不執(zhí)行,那么需要使用括起來。3.ifelse的用法:ifelse ifelse的用法:C錯誤的ifelse ifelse語句:在上圖中,當執(zhí)行到哈哈那句時,下面的else將會被算作另外一個語句來執(zhí)行,而在我們的c語言中,沒有以else開頭的語句。所以會出錯。If 實例:If常見的問題:變量的替換:求三個數(shù)字的大?。篊語言常見誤區(qū):紙老虎素數(shù):只能被1和自己整除的數(shù),如1,5,9等?;匚臄?shù):正著寫和倒著寫一樣的數(shù)。如1221,121,等編程實現(xiàn)求一個十進制數(shù)字的二進制形式:求一個數(shù)字的每位是奇數(shù)的數(shù)字取出來組合形

15、成的新數(shù)字。求一個數(shù)字到過來的數(shù)字。1:如果不懂,那么就看答案??炊鸢冈谇?。沒錯誤了,在嘗試改。如何看懂一個程序:1. 流程:2. 每個語句的功能:3. 試數(shù):對一些小算法的程序:1. 嘗試自己編程結(jié)局。2. 解決不了,看答案。3. 關(guān)鍵是把答案看懂。4. 看懂之后嘗試自己修改程序,且知道修改之后程序的不同輸出結(jié)果的含義。5. 照著答案去敲6. 調(diào)試錯誤7. 不看答案,自己獨立把程序編出8. 如果程序?qū)嵲谑菑氐谉o法了解,就把他背會。 空語句的問題: 在上圖中,最終的結(jié)果會是AAAA,BBBB,程序也不會報錯,為什么呢,因為在程序執(zhí)行的時候,會在;哪里認為是一個空語句。也就是說,如果if成立,

16、那么執(zhí)行空語句。If常見錯誤解析(重點)上面這個程序是錯誤的,為什么呢,在該程序中,總的有4個語句,而在以else開頭的那個語句中是有錯誤的,因為在c語言中是沒有以else開頭的這種語法。在上面這個程序中,最終的值是AAAA,雖說后面的31也滿足條件,但是當32滿足條件后,該if語句就會終止,后面的語句是不會在執(zhí)行的。 既然7行要寫表達式,就要寫if。循環(huán)的定義、分類。定義:某些代碼會被重復(fù)執(zhí)行。分類:for while dowhile 在上圖中,先執(zhí)行1,在執(zhí)行2,2如果成立,標志著循環(huán)成立,那么在執(zhí)行4,最后在執(zhí)行3,3執(zhí)行完后代表一次循環(huán)完成,然后在執(zhí)行2.以此類推。1永遠只執(zhí)行一次。+

17、I 等價于 i+1求1-10的所有奇數(shù)的和:求1-12之間的所有能被3整除的數(shù)字之和: For所控制的語句:在上圖中,for默認只能控制一個語句,但是如果要控制多個語句時候,那么需要使用把語句括起來。求1+1/2+1/3.1/100的和在上圖中,重點是強制數(shù)據(jù)類型轉(zhuǎn)換也就是(float)(i)那句:如果把print那句換為下面這句會怎么樣呢:也是錯的,為什么呢,因為i是整型,1也是整型,所以不管你怎么轉(zhuǎn)換也是整型啊,如果想要這樣寫的話,那么我們需要把1改成1.0也可以的。也就是:試數(shù)詳細步驟舉例:浮點數(shù)存?。呵?-100之間所有奇數(shù)的和:求1-100之間的奇數(shù)的個數(shù): 求1-100之間奇數(shù)的平

18、均值: 求1-100之間的奇數(shù)之和,在求1-100之間的偶數(shù)之和:多個for循環(huán)的嵌套使用:整體是兩個語句。上圖中,先執(zhí)行1,在執(zhí)行2,如果2成立,執(zhí)行4,在執(zhí)行5,如果5成立執(zhí)行A,在執(zhí)行6,在執(zhí)行5,如果5不成立,意味著里面的循環(huán)結(jié)束,然后執(zhí)行3,在執(zhí)行2,如果2成立又執(zhí)行4,在執(zhí)行5,如果5成立在執(zhí)行6,在執(zhí)行5,如果5不成立,在執(zhí)行3,在執(zhí)行2,如果2不成立,意味著本次循環(huán)結(jié)束,在執(zhí)行B,在上圖中,需要注意的是,如果2成立的話,那么每次4都需要執(zhí)行。進制之間的轉(zhuǎn)換:如234為5進制,那么轉(zhuǎn)換成10進制是多少:2x5x5+3x5+4的值就是轉(zhuǎn)換成的10進制。234e是16進制,轉(zhuǎn)換成2進

19、制是多少:2x16x16x16+3x16x16+4x16+12的值就是轉(zhuǎn)換成10進制的值。注意上面的規(guī)律。那么把十進制轉(zhuǎn)換成r進制呢,其實很簡單,就是把10進制數(shù)除以r,直到商是0的時候。然后取余數(shù),余數(shù)倒序排列: 瑣碎的運算符:自增:自減:和自增一樣。三目運算符:最終的輸出結(jié)果是1.逗號表達式:最終結(jié)果是6.上圖中,逗號是個順序點,即所有的副作用必須在下個語句前生效,其最后結(jié)果為1,j+2只是產(chǎn)生臨時值,并沒有把j+2的值賦個j。如果寫成j+=2,那最后的值則變?yōu)?.For的嵌套使用舉例:上例中輸出的結(jié)果是9個哈哈,1個嘻嘻。在上圖中,整個程序分成3個語句,輸出的結(jié)果是3個嘿嘿,3個哈哈,1

20、個嘻嘻。其結(jié)果是:While(先付錢后吃飯)1:執(zhí)行的順序:2:與for的相互比較:用for來求1-100之和:用while實現(xiàn)1-100之和。只需要把for語句替換為:For和while是可以相互轉(zhuǎn)換的,可以用下面的表達式來表示:While和for在邏輯上完全等價,但是for在邏輯上更強。更容易理解,更不容易出錯。推薦多使用for。3:while舉例:試數(shù):通過上面的試數(shù),應(yīng)該能很快的理解回文數(shù)的算法。4:什么時候使用while,什么時候使用for:沒法說,用多了就自然而然知道了Dowhile(先吃飯后付錢)一元二次方程:Switch的用法:電梯程序:Case是程序的入口,當進入程序后,程序

21、會從上往下執(zhí)行,如果有break,那么會中斷程序,如果沒有,那么會一直執(zhí)行。Break的用法:在多層循環(huán)中,Break只能終止他最近的循環(huán)。在多層switch中,break也是只能終止距離他最近的switch。Break只能用于循環(huán)和switch,不能用于if。如果用于if,必須要當循環(huán)中嵌套if的時候。Continue的用法:上圖中,如果執(zhí)行continue,那么C,D將不會被執(zhí)行,會執(zhí)行3.在上圖中,如果執(zhí)行了continue,那么后面的C,D將不再執(zhí)行,而會去執(zhí)行表達式。數(shù)組:-非重點 數(shù)組的使用:為什么需要數(shù)組1:為了解決大量同類型數(shù)據(jù)的存儲和使用問題。2:用數(shù)組可以模擬現(xiàn)實世界。In

22、t a25:一維數(shù)組,可以當做一個線性結(jié)構(gòu)。Int a86:可以當做一個平面,意思是8行6列。有48個元素。Int a345:可以當做一個三維 立體。Int a3456:可以當做一個四維空間。數(shù)組的分類一維數(shù)組怎樣定義一維數(shù)組:為n個變量分配存儲空間:數(shù)組內(nèi)存空間是連續(xù)的。所有的變量類型必須相同:數(shù)組不可能第一個元素是整形,第二個元素是浮點型。所有變量所占用的字節(jié)必須相等。 例子:int 5數(shù)組不是學習重點的原因?數(shù)組一旦定義,其長度是死的。有關(guān)一維數(shù)組的操作 -都需要自己另外編程序?qū)崿F(xiàn)而我們通常用第三方軟件(工具)如數(shù)據(jù)庫等方便直接地實現(xiàn)。對數(shù)組的操作:初始化 賦值 排序 求最大/小值 倒置

23、 查找 插入 刪除初始化:上圖中a5前面如果沒有加上數(shù)據(jù)類型,那么這里的a5不是指一個數(shù)組,其中的5只的是下標。上圖中,數(shù)組的5個元素不是用a來代表的,是用a0,a1a4來代表的,所以說數(shù)組名a代表的不是數(shù)組的5個元素,數(shù)組名代表的是數(shù)組的第一個元素的地址。賦值 把一個數(shù)組元素給全部倒過來:排序 求最大/小值 倒置 查找 插入 刪除 二維數(shù)組:二維數(shù)組的初始化: 輸出二維數(shù)組內(nèi)容:多維數(shù)組:是否存在多維數(shù)組:不存在因為內(nèi)存是線性一維的,在內(nèi)存中是不分行不分列的。N維數(shù)組可以當做每個元素是n-1維數(shù)組的 一維數(shù)組。函數(shù)(第二個重點):為什么需要函數(shù):避免了重復(fù)性操作。有利于程序的模塊化。(自上而

24、下,逐步細化,大問題分解成小問題)用它作為參照,可以對比 JAVA 和C#面向?qū)ο蟮乃枷?。C語言基本單位是函數(shù),C#、C+和JAVA基本單位是類。什么叫做函數(shù)邏輯上:能夠完成特定功能的獨立的代碼塊。 物理上:能夠接收數(shù)據(jù)【也可以不接收數(shù)據(jù)】,能夠?qū)邮盏臄?shù)據(jù)進行處理【也可以不對數(shù)據(jù)進行處理】,能夠?qū)?shù)據(jù)處理的結(jié)果返【也可以沒有返回值】??偨Y(jié):函數(shù)是個工具,他是為了解決大量類似問題而設(shè)計的,函數(shù)可以當做黑匣子(內(nèi)部原理不用管)。如何定義函數(shù)函數(shù)的返回值,函數(shù)的名字(函數(shù)的形參列表)函數(shù)的執(zhí)行體函數(shù)定義的本質(zhì):詳細描述函數(shù)之所以能夠?qū)崿F(xiàn)某個特定功能的具體方法。函數(shù)中的變量叫做形參;數(shù)組中的變量叫元

25、素。一旦函數(shù)執(zhí)行完畢,其內(nèi)部的形參所占空間就被收回。return表達式的含義:Return是終止被調(diào)函數(shù),向主調(diào)函數(shù)返回表達式的值,如果表達式為空,則只終止函數(shù),不向被主函數(shù)返回任何值。Break是用來終止(就近的)循環(huán)和switch語句。而return是用來終止被調(diào)函數(shù)的。函數(shù)返回值的類型,也稱為函數(shù)的類型,因為如果函數(shù)名前的返回值類型和函數(shù)執(zhí)行體中的return表達式中表達式的類型不同的話,則最終函數(shù)返回值的類型以函數(shù)名前的返回值類型為準。例:在上圖中,函數(shù)的返回值以函數(shù)前的數(shù)值類型為準。函數(shù)的分類有參函數(shù)和無參函數(shù)。有返回值和無返回值。庫函數(shù)和用戶自定義函數(shù)。普通函數(shù)和主函數(shù)(main函

26、數(shù))1:一個程序有且只有一個主函數(shù)。2:主函數(shù)可以調(diào)用普通函數(shù),普通不能調(diào)用主函數(shù)。3:普通函數(shù)可以相互調(diào)用。4:主函數(shù)是程序的入口,也是函數(shù)的出口。5:值傳遞函數(shù)和地址傳遞函數(shù)。 判斷一個數(shù)是否是素數(shù):使用函數(shù)判斷一個數(shù)是否是素數(shù):函數(shù)和程序的調(diào)用應(yīng)該注意的地方:函數(shù)的聲明:當函數(shù)沒有返回值時,那么規(guī)范的寫法是要在函數(shù)中寫明void的。在上圖中,第一個void表示沒有返回值,而第二個void表示不接收形參,也就是函數(shù)不接收數(shù)據(jù)。如果想把函數(shù)寫在程序的后面,那么需要寫函數(shù)聲明:函數(shù)聲明的含義是告訴編譯器f()是個函數(shù)名。如果不加函數(shù)聲明,那么編譯器在編譯到f的時候,不知道f是個什么,如果加了函

27、數(shù)聲明,那么編譯器編譯到f的時候,就知道f是個函數(shù)。需要注意的是,調(diào)用語句需要放在定義語句的后面,也就是說,定義函數(shù)的語句要放在調(diào)用語句的前面。如果函數(shù)調(diào)用寫在了函數(shù)定義的前面,則必須加函數(shù)前置聲明,函數(shù)前置聲明的作用是:1:告訴編譯器即將可能出現(xiàn)的若干個字母代表的是一個函數(shù)?!按蛘泻簟?:告訴編譯器即將可能出現(xiàn)的若干個字母所代表的函數(shù)的形參和返回值的具體情況。3:函數(shù)聲明必須是一個語句,也就是在函數(shù)聲明后需加分號。4:對庫函數(shù)的聲明也就是系統(tǒng)函數(shù)。是通過#include來實現(xiàn)的。如stdio.h形參和實參要求:1:形參和實參個數(shù)是一一對應(yīng)的。2:形參和實參的位置也是一一對應(yīng)的。3:形參和實參

28、的數(shù)據(jù)類型需要相互兼容。 如何在軟件開發(fā)中合理的設(shè)計函數(shù)來解決實際問題。 求1到某個數(shù)字之間的數(shù)是否是素數(shù),并將他輸出:合理設(shè)計函數(shù)1合理設(shè)計函數(shù)2:合理設(shè)計函數(shù)3:合理的設(shè)計函數(shù)4:合理設(shè)計函數(shù)5:常用的系統(tǒng)函數(shù)和如何通過書籍來學習函數(shù): Turboc2.0實用大全機械工業(yè)出版社遞歸:(略)棧:相當于一個杯子(容器) 變量的作用域和存儲方式: 全局變量和局部變量:局部變量:局部變量的使用范圍只能在本函數(shù)內(nèi)部使用。全部變量:全局變量和局部變量命名沖突的問題:在同一個范圍之內(nèi)不能定義兩個一樣的局部變量:在一個函數(shù)內(nèi)部,如果定義的局部函數(shù)的名字和全局變量名一樣時,局部變量會屏蔽掉全局變量:上例中最

29、終的輸出結(jié)果是8,因為局部變量把全局變量給屏蔽掉了。指針:(C語言的靈魂)內(nèi)存的存儲是以一個字節(jié)為一個編號,也就是8位合在一起給一個編號,不是0,1就給編號。內(nèi)存分為很多個單元,每個單元就會分配一個編號。地址:內(nèi)存單元的一個編號。而指針和地址一個概念的。也就是說指針就是地址。普通變量:只能存放一個值。指針變量:同樣是一個變量,但是指針變量存放其他變量的地址。*p代表的是p所指向的那個變量。在上圖中*p和i是同一個東西,但是*p和p不是同一個東西。在上圖中,int * p是一個聲明,開頭的int * 是他的數(shù)據(jù)類型。P是變量的名字。不能理解我定義了一個整形變量,這個整形變量的名字叫做*p。所謂i

30、nt *類型,實際就是存放int 變量地址的類型。*p代表的是以p的內(nèi)容為地址的變量。解析:p的內(nèi)容是一個地址,在上圖中,p的內(nèi)容就是i的地址,*p其指向的變量當然就是i變量了。指針和指針變量:指針就是地址,地址就是指針。地址就是內(nèi)存單元的編號。指針變量:存放地址的變量。而指針只是一個值,這個值是內(nèi)存單元的一個編號。指針變量才是一個變量,他里面才可以存放數(shù)據(jù)。指針和指針變量是兩個不同的概念,但是需要注意的是,通常我們在敘述時會把指針變量簡稱為指針,實際他們含義并不一樣。指針的重要性:指針的分類:指針的定義:地址:內(nèi)存單元的編號,是一個從0開始的非負整數(shù)。范圍:cpu對內(nèi)存是通過控制、數(shù)據(jù)、地址

31、三條總線來進行控制的??刂疲篶up會先把內(nèi)存中的數(shù)據(jù)讀入,進行處理后,在返回給內(nèi)存,然后內(nèi)存在把數(shù)據(jù)寫入硬盤。數(shù)據(jù):用于數(shù)據(jù)的傳輸,不管是把內(nèi)存中的數(shù)據(jù)發(fā)送給cpu,還是把cpu的數(shù)據(jù)寫如內(nèi)存條,都是由數(shù)據(jù)線來完成的,但是數(shù)據(jù)傳輸?shù)姆较騽t是由控制線來控制的。地址:地址線則是確定數(shù)據(jù)要寫入內(nèi)存中的那個單元。所謂的一個單元就是一個字節(jié)。一條地址總線能控制2的1次方,一般的機器有32個地址線,最終能夠控制2的32個單元,而每個單元是八位,而最終我們的內(nèi)存能夠存儲2的32次方*8位。則換算為G的話,最終大小為4G.那么地址總線的范圍則是4G大。指針:指針就是地址,地址就是指針。 指針變量就是存放內(nèi)存單

32、元編號的變量。 指針變量和指針是兩個不同的概念。 指針的本質(zhì)就是一個操作受限的非負整數(shù)。指針不能進行算術(shù)運算-相加 乘 除。但是能相減。如果兩個指針變量指向的是同一塊連續(xù)空間的不同存儲單元,則這兩個指針變量才可以相減。類似于同一個小區(qū)同一樓層六牌號相減表示兩房間隔。這時才有現(xiàn)實意義。基本類型的指針:Int *p:p只能存放int類型的地址。P = & i:把i的地址賦給p。然后p就指向了i,*p就等于i。其實就是1:該語句保存了i的地址。2:p保存了i的地址,所以p指向i。3:p既然指向i,*p就是i。*p:表示以p的內(nèi)容為地址的變量。*p:p是有指向的,p里面是個垃圾值,*p則是說以p的內(nèi)容

33、為地址的變量。因為不知道p的值是多少,所以不知道*p到底代表的是那個變量。而*p = i,i=5,最終的結(jié)果就是把5賦給了一個所不知道的單元。 上圖中,第一個error是數(shù)據(jù)類型不符合,不能相互轉(zhuǎn)換。*q代表的是整形,因為*q代表的是以q的地址為內(nèi)容的變量。而p是地址(int *)類型。第二個error同樣有錯,因為q沒有賦值。經(jīng)典指針程序-互換兩個數(shù)字: 1:先用函數(shù)來互換:最終的輸出結(jié)果沒有互換,因為函數(shù)的a,b已經(jīng)執(zhí)行完成,分配給內(nèi)存的空間已經(jīng)釋放了,所以最終a,b的值還是主函數(shù)a,b的值?;Q的是形參的a,b。和主函數(shù)沒有關(guān)系。在上圖中,輸出的值也是沒有互換的,輸出的同樣是3,5,需要

34、注意的是,互換的只是p、q的內(nèi)容,局部函數(shù)變化了,但是主函數(shù)是沒有變化的。最終正確的程序:*號的三種含義:1:乘法2:定義指針變量。Int * p,定義了一個名字叫p的變量,int *表示p只能存放int變量的地址。3:指針運算符。該運算符是放在已經(jīng)定義好的指針變量的前面。如果p是一個已經(jīng)定義好的指針變量,則*P表示以p的內(nèi)容為地址的變量。 注意理解形參,實參,和局部變量的關(guān)系。指針可以是函數(shù)返回一個以上的值:不使用指針的話,只能使用用return來返回一個值。如何通過被調(diào)函數(shù)修改主調(diào)函數(shù)普通變量的值指針和數(shù)組:指針和一維數(shù)組:(數(shù)組名 下標與指針關(guān)系 指針變量的運算)一維數(shù)組名:一維數(shù)組名是

35、個指針常量,他存放的是一維數(shù)組第一個元素的地址。常量是不能被改變的,也就是說,一維數(shù)組名是不能被改變的。數(shù)組名a存放的是一維數(shù)組第一個元素的地址,也就是a = &a。printf(“%#Xn”,&a0); = printf(“%#Xn”,a);指針和二維數(shù)組:下標和指針的關(guān)系:如果p是個指針變量,則pi永遠等價于*(p+i)確定一個一維數(shù)組需要幾個參數(shù),【如果一個函數(shù)要處理一個一維數(shù)組,則形參需要接收該數(shù)組的哪些信息?!看_定一個一維數(shù)組需要兩個參數(shù),1:數(shù)組名,從數(shù)組的名稱就可以知道數(shù)組的第一個值,因為一維數(shù)組的名稱就是數(shù)組的第一個元素的地址。2:是數(shù)組的個數(shù)。來計算該數(shù)組有多少個值。區(qū)別于

36、字符串(只需要一個參數(shù)首地址)因為字符串默認其后面都有一個“/0”作為結(jié)束標志。而數(shù)組并沒有相關(guān)約定。在上圖中,a是個指針變量,所以上面局部函數(shù)f的pArr則要定義成指針函數(shù)才可以,而len則是int類型。代表接收的是整型的數(shù)字。 在上圖中因為數(shù)組a的名稱代表的是a的第一個元素的地址,所以在函數(shù)f中所定義的指針變量pArr和a是相同的,因為a也是指針類型。也就是說pArr=a=a0,pArr1=a1=*(pArr+1)=*(a+1),pArr2=a2=*(pArr+2) =*(a+2).所以在f函數(shù)中pArr3=a3,所以第二個printf輸出的結(jié)果是88.總結(jié):pArri = ai = *(

37、pArr+i) = *(a+i)在沒有學習指針時,可將a3認為是數(shù)組中第4個元素,但現(xiàn)在應(yīng)該對其內(nèi)部原理有更深刻認識。這里下標也當成指針了,從首元素開始向后移動3個,即指向第4個元素。在上圖中因為數(shù)組a的名稱代表的是a的第一個元素的地址,所以在函數(shù)f中所定義的指針變量pArr和a是相同的,因為a也是指針變量類型。也就是說pArr=a=a0,pArr1=a1=*(pArr+1)=*(a+1),pArr2=a2=*(pArr+2) =*(a+2).通過上圖,我們知道,我們在f函數(shù)中修改數(shù)組的值,相當于修改主函數(shù)中相對應(yīng)的值。何謂變量地址 / 一個指針占幾個字節(jié)Sizeof(變量名/數(shù)據(jù)類型) 其返

38、回值就是該變量或數(shù)據(jù)類型所占字節(jié)數(shù)。一個指針變量無論其指向變量占幾個字節(jié),其本身所占大小都是4字節(jié)。*p具體指向幾個字節(jié),要靠前面類型確定,如果為int則為4字節(jié),如果double則占8字節(jié)。CPU 與 內(nèi)存 交互時 有32根線,每根線只能是1或0兩個狀態(tài),所有總共有232個狀態(tài)。1 個狀態(tài) 對應(yīng) 一個單元。如全為0 全為1 等。內(nèi)存中第一個單元,即32根線狀態(tài)全為0。0000 0000 0000 0000 0000 0000 0000 0000 其大小為4字節(jié)所有每個地址(硬件所能訪問)的用4個字節(jié)保存(而不是一 位bit)一個變量的地址用該變量首字節(jié)的地址表示。這也就是為什么指針變量始終只

39、占4字節(jié)的原因。接下來是:138課 動態(tài)分配內(nèi)存(很重要)專題:138講動態(tài)內(nèi)存分配 (所有高級語言,沒有C里深刻,對JAVA、C#理解有益)傳統(tǒng)數(shù)組的缺點:1.數(shù)組長度必須事先指定,而且只能是常整數(shù),不能是變量例子int a5; /必須事先指定,而且只能是常整數(shù) int len = 5; int alen;/error2.傳統(tǒng)形式定義的數(shù)組,該數(shù)組的內(nèi)存程序員無法手動釋放數(shù)組一旦定義,系統(tǒng)為數(shù)組分配的內(nèi)存空間就會一直存在,除非數(shù)組所在的函數(shù)運行終止。在一個函數(shù)運行期間,系統(tǒng)為該函數(shù)中的數(shù)組分配的空間會一直存在。直到該函數(shù)運行完畢時,數(shù)組的空間才會被系統(tǒng)自動釋放(不是清零)。例子:void f

40、(void) int a5=1,2,3,4,5;./數(shù)組a 占20個字節(jié)的內(nèi)存空間,程序員無法手動編程釋放它,數(shù)組a只能在f()函數(shù)結(jié)束被系統(tǒng)釋放3. 數(shù)組的長度一旦定義,數(shù)組長度就不能再更改。數(shù)組的長度不能在函數(shù)運行的過程中動態(tài)的擴充或縮小4. 傳統(tǒng)方式定義的數(shù)組不能跨函數(shù)使用A函數(shù)定義的數(shù)組,只有在A函數(shù)運行期間才可以被其他函數(shù)使用,但A函數(shù)運行完畢后,A函數(shù)中的數(shù)組將無法在被其他函數(shù)使用。#includevoid g(int * pArr, int len) pArr2 = 88; /parr2=a2 等價于 void f(void) int a5 = 1,2,3,4,5; /數(shù)組a 只

41、在f()執(zhí)行時有效 g(a,5);printf(%dn, a2);int main(void) f(); / 結(jié)果: 88/printf(a0 = %dn, a0); / error return 0;為什么需要動態(tài)分配內(nèi)存很好的解決的了傳統(tǒng)數(shù)組的4個缺陷動態(tài)內(nèi)存分配舉例_動態(tài)數(shù)組的構(gòu)造 難點/*2011-05-01malloc是memory(內(nèi)存) allocate(分配)的縮寫動態(tài)內(nèi)存空間是怎么造出來的?*/#include #include int main(void)int i = 5; /分配了4個字節(jié),靜態(tài)分配int * p = (int *)malloc(100);/*1. 要使

42、用malloc函數(shù),必須要添加malloc.h頭文件2. malloc函數(shù)只有一個形參,并且形參是整型3. 100表示請求系統(tǒng)為本程序分配100個字節(jié)4. malloc函數(shù)只能返回第一個字節(jié)的地址,但此時并不能確定該變量的類型,只有將這個地址被強制類型轉(zhuǎn)化成存放整型變量的地址,這時才傳達出指向整型變量的信息。5. 系統(tǒng)總共分配了104個字節(jié)的內(nèi)存空間,p變量本身占4個字節(jié)(靜態(tài)分配),p所指向的內(nèi)存占100個字節(jié)(動態(tài)分配) 若為int 則可存25個,若為char則可存100個變量。6. p本身所占的內(nèi)存是靜態(tài)分配的,p所指向的內(nèi)存是動態(tài)分配的*/free(p);/free(p)表示把p說指向

43、的內(nèi)存空間給釋放掉,/p本身的內(nèi)存不能釋放,只有main函數(shù)終止時,由系統(tǒng)自動釋放*p = 5; /*p代表的就是一個這int變量,*p這個整型變量的內(nèi)存分配方式和int i =5;不同。/*p是內(nèi)存是動態(tài)分配的, int i是靜態(tài)的。printf(同志們好!n);return 0;-/*2011-05-01目的: malloc使用_2*/#include #include void f(int * q) /q是p的拷貝或副本 q等價于p *q等價于*p *q=200則*p=200/*p = 200; /error f()沒有p變量,p是在main()函數(shù)定義的/ q = 200; /erro

44、r q是指針變量(地址),200是整數(shù)int *q = 200; /OK!類型一致/ * *q 語法錯誤 !*q整型變量, 只有指針變量前可以加*/free(q);/把q指向的內(nèi)存釋放掉int main(void)int * p = (int *)malloc(sizeof(int);/sizeof(int)=4;*p = 10;printf(%dn, *p); /10f(p);printf(%dn, *p); /200/ f()函數(shù)中 free(q)作用后,則輸出 -572662307(垃圾值)return 0;/*2011-05-02目的:動態(tài)一維數(shù)組示例realloc(pArr, 100

45、)/擴充動態(tài)內(nèi)存空間 (原來50變100;原來150變100)/保留原來動態(tài)內(nèi)存中未被截取的內(nèi)容*/#include #include int main(void) /int a5; /系統(tǒng)靜態(tài)地分配20個字節(jié)的空間給數(shù)組aint len;int *pArr;printf(請輸入你要存放的元素個數(shù): );scanf (%d, &len);/5pArr = (int *)malloc(4*len);/pArr指向這20個字節(jié)動態(tài)空間的前4個字節(jié)/*動態(tài)的構(gòu)造了一個一維數(shù)組,該數(shù)組的長度len, 數(shù)組名是pArr, 數(shù)組元素類型是int類似與int pArrlen; len可以根據(jù)需要變化*/對一

46、維數(shù)組進行操作,如:對動態(tài)一維數(shù)組進行賦值for (int i=0; ilen; +i)scanf(%d, &pArri); printf(動態(tài)數(shù)組元素為: n);/對一維數(shù)組進行輸出for(i=0; ilen; +i)printf(%dn, pArri);free(pArr);/動態(tài)空間被釋放printf(%dn, *(pArr+1); /動態(tài)空間被釋放,原來動態(tài)數(shù)組數(shù)元素內(nèi)容為垃圾值-572662307return 0;/*-在VC+6.0輸出結(jié)果:請輸入你要存放的元素個數(shù):44 6 8 10動態(tài)數(shù)組元素為:46810*/使用動態(tài)數(shù)組的優(yōu)點:1.動態(tài)數(shù)組長度不需要事先給定;2.內(nèi)存空間可以

47、手動釋放;3.在程序運行中,動態(tài)內(nèi)存空間大小可以通過realloc函數(shù)手動擴充或縮小靜態(tài)內(nèi)存和動態(tài)內(nèi)存的比較靜態(tài)內(nèi)存是由系統(tǒng)自動分配,有系統(tǒng)自動釋放靜態(tài)內(nèi)存是在棧分配的動態(tài)內(nèi)存是由程序員手動分配、手動釋放動態(tài)內(nèi)存是在堆分配的 /*2011-05-02目的: 多級指針 - 自己畫幾個示意圖 就會豁然開朗。/#include int main(void) int i = 10;/ iint * p = &i; / 最終 *p就是 i;int* *q = &p; / q 只能存放 int *類型的地址 即p 的地址&pint* *r = &q; / r 只能存放 int *類型的地址 即q 的地址&

48、q/r = &p; /error! 因為r是int*類型,只能存放int *類型變量的地址printf(i = %dn, *r); *r = q; *r = *q =p *r = *q = *p = i;printf(i = %dn, *q); *q = p ; *q = *p = i printf(i = %dn, *p); *p = i;printf(i = %dn, i);return 0;/*-在VC+6.0輸出結(jié)果:i = 10i = 10i = 10i = 10*/#include /多級指針在函數(shù)中的應(yīng)用void f(int * q)*q = 100;/*q就是pvoid g()

49、int i = 10;int * p = &i;printf(i = %d *p = %dn, i, *p);f(&p); /p是int *類型&p就是int * 類型printf(i = %d *p = %dn, i, *p); int main(void) g();return 0;/*-在VC+6.0輸出結(jié)果:i = 10 *p = 10i = 100 *p = 100*/ #include #include void f(int * q) /q是p的拷貝副本*q = 1;void g(int *r)*r = 2;void h(int *s)*s = 3;void i(int *t)*t = 4;/要想修改函數(shù)變量的值,只能發(fā)送該變量的地址,修改一個以上的值,必須用指針int main(void) int *p = (int *)malloc(4);printf(*p = %dn, *p);/垃圾值f(p); /調(diào)用的是指針printf(*p = %dn, *p);/1 g(&p);/調(diào)用的是指針變量的地址printf(*p = %dn, *p);/2/h(&(&p);/ error C2102: & requires l-valueint *pp = &p; /pp是存放p地址的指針, int * 整型指針的指針類型h(&pp); /調(diào)

溫馨提示

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

評論

0/150

提交評論