C語言基礎(chǔ)知識(shí)匯總學(xué)習(xí)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?可以根據(jù)黑體字來檢索需要學(xué)習(xí)的模塊哦^_^

C語言關(guān)鍵字:
????unsigned?signed?bool?void?char?short?int?long?double?float?struct?enum?union?typedef?sizeof
????if?else?for?switch?case?default?while?do?break?continue?goto
????extern?register?volatile?auto?const?static?return
常用的Linux系統(tǒng)命令:
????touch/cat/more/head/tall/rm/cp/mv
????mkdir/rmdir/cd/ls/tar
????ifconfig/ping/telnet/ssh/ftp
vim文本編輯器:
????在終端下依靠鍵盤操作使用的文本編輯器。
????三大主要模式:正常模式、插入模式、命令模式
????常用快捷鍵:Ctrl+x?Ctrl+z?Ctrl+c
????教程:vimtutor
C語言介紹:
????發(fā)明C語言的目的是什么
????長盛不衰
????優(yōu)缺點(diǎn)、特點(diǎn)
????C語言三劍客:《C語言陷阱和缺陷》、《C和指針》、《C專家編程》、《C程序設(shè)計(jì)語言》、
《C?Primer?Plus》、《必然》、《白說》
編譯器介紹:
????編譯器就一個(gè)特殊的程序,把負(fù)責(zé)把C代碼(文本文件)編譯成可執(zhí)行的二進(jìn)制文件。
????它由:預(yù)處理器、編譯器、鏈接器組成
????常用的參數(shù):-E?-c?-S?-o?-std?-l?-D?-Werror?-Wall
????E???激活預(yù)處理;頭文件、宏等展開(.i文件)
????S???激活預(yù)處理、編譯;生成匯編代碼(.s文件)
????c???激活預(yù)處理、編譯、匯編;生成目標(biāo)文件(.o文件)
????o???生成目標(biāo)
????Wall????打開編譯告警(所有)
????g???嵌入調(diào)試信息,方便gdb調(diào)試
????《程序員的自我修養(yǎng)》
數(shù)據(jù)類型:
????整型:unsigned、signed
????char,short,int,long,long?long
????實(shí)型:float,double,long?double
????字符:char
????布爾:bool
????取值范圍:char,short,int
????各類型的字節(jié)數(shù):
????各類型的占位符:long?double(%LF)
進(jìn)制轉(zhuǎn)換:
????為什么需要二進(jìn)制:因?yàn)楝F(xiàn)在的計(jì)算機(jī)由大規(guī)模集成電路構(gòu)成,計(jì)算單元只能識(shí)別高低電流這種數(shù)據(jù),
因此只能使用二進(jìn)制數(shù)據(jù)。
????為什么需要八進(jìn)制:為了方便記錄二進(jìn)制,由于歷史原因八進(jìn)制數(shù)據(jù)還在使用。
????為什么需要十六進(jìn)制:相當(dāng)于升級(jí)版的八進(jìn)制,由于計(jì)算機(jī)的高速發(fā)展,八進(jìn)制已經(jīng)無法滿足需要。
????十進(jìn)制轉(zhuǎn)換成二進(jìn)制:
????????求余:把十進(jìn)制數(shù)據(jù)不停的用2求余,逆序記錄求余的結(jié)果。
????????????189?%?2?=?1
????????????94?%?2?=?0
????????????47?%?2?=?1
????????????23?%?2?=?1
????????????11?%?2?=?1
????????????5?%?2?=?1
????????????2?%?2?=?0
????????????1?%?2?=?1
????????????10111101
????????求權(quán):128?64?32?16?8?4?2?1
????二進(jìn)制轉(zhuǎn)換成十進(jìn)制:
????????2的不同次方相加。
????二進(jìn)制轉(zhuǎn)換成八進(jìn)制:三位二進(jìn)制轉(zhuǎn)換成一位八進(jìn)制
????????10?111?101?=?0275
????????128?56?5?=?189
????二進(jìn)制轉(zhuǎn)化成十六進(jìn)制:四位二進(jìn)制轉(zhuǎn)換成一位十六進(jìn)制
????????10?<=>?a
????????1011?1101?=?0xbd
????0b10111101?二進(jìn)制
????0275?八進(jìn)制
????0xbd?十六進(jìn)制
????數(shù)據(jù)在內(nèi)存是如何存儲(chǔ)的:
????????數(shù)據(jù)分為原碼、反碼、補(bǔ)碼,內(nèi)存中存儲(chǔ)的是數(shù)據(jù)的補(bǔ)碼。
????原碼:數(shù)據(jù)直接轉(zhuǎn)換成的二進(jìn)制(無論正負(fù))
????反碼:將原碼按位求反得到反碼
????補(bǔ)碼:
????????正:原碼
????????負(fù):反碼+1
????補(bǔ)碼:10111101?char
????????10111100
????????01000011?-67
常量與變量
????常量:程序運(yùn)行過程中不可改變的數(shù)據(jù)
????????字面值
????????100?int類型
????????100L?long
????????100U?unsigned?int
????????100LU?unsigned?long
????????100LL?long?long
????????100LLU?unsigned?long?long
????????3.14?double
????????3.14F?float
????????3.14LF?long?double
????????枚舉值
????????宏常量
????????具有const屬性的被初始化過的全局變量
????變量:類型?變量名;注意:取名規(guī)則,見名知意
????????容器、數(shù)據(jù)
流程控制
????if?else,switch,for,while,do?while,break,continue,goto
????注意:大括號(hào)不要省略,分號(hào)不要多加
????《C語言編碼規(guī)范-華為》
????《C++語言編程規(guī)范-谷歌》
????如何判斷XX類型是否是“零值”?
????float,bool,int,char,int*?p;
????if(0.000001?>?f?&&?f?>-0.000001)
????if(flag)
????if(0?==?num)
????if('\0'?==?ch)
????if(NULL?=?p)
????閱讀、安全角度思考。
數(shù)組
????C語言中只有一維數(shù)組,多維數(shù)組都是使用一維數(shù)組模擬的。
????數(shù)組的越界:一切正常、段錯(cuò)誤、臟數(shù)據(jù)。
????char?str[11]?=?"hello,world";
????變長數(shù)組:數(shù)據(jù)的長度填寫變量,編譯時(shí)不能確定,程序運(yùn)行期間可以變化,而執(zhí)行數(shù)組定義語句時(shí)長度才固定下來。
????????優(yōu)點(diǎn):可根據(jù)實(shí)際情況定義數(shù)組的長度,從而節(jié)約內(nèi)存
????????缺點(diǎn):不能初始化。
????int?arr[10];
????arr?<=>?int?*
????int?arr[3][4]
????arr?<=>?int?(*)[4];
函數(shù)
????函數(shù)是C語言中管理代碼的最小單位,命名空間獨(dú)立,棧空間獨(dú)立。
????函數(shù)被調(diào)用時(shí)開辟棧內(nèi)存,函數(shù)結(jié)束后釋放棧內(nèi)存。
????聲明:返回值?函數(shù)名(類型1,類型2,...);
????定義:返回值?函數(shù)名(類型1?參數(shù)名1,類型2?參數(shù)名2,...)
????{
????????函數(shù)體
????}
????注意:函數(shù)的定義如果出現(xiàn)調(diào)用之前,聲明可以忽略
????注意:調(diào)用函數(shù)時(shí)如果沒有找到函數(shù)聲明,也沒有定義,編譯器也不報(bào)錯(cuò),而是先猜測(cè)函數(shù)的格式,鏈接時(shí)在嘗試尋找函數(shù)的定義。
????????return?語句只是把數(shù)據(jù)存儲(chǔ)到一個(gè)特定的位置,當(dāng)函數(shù)運(yùn)行結(jié)束后,調(diào)用者就可以從這個(gè)位置獲取到返回值。
????????????函數(shù)有返回值(格式),而沒寫return語句,調(diào)用者會(huì)得到一個(gè)不確定的返回值。
????常見編譯錯(cuò)誤:
????????隱式聲明函數(shù),沒有找到函數(shù)聲明和定義。1
????????undefined?reference?to?'',有函數(shù)聲明,但無函數(shù)定義
????函數(shù)的本質(zhì):函數(shù)就是存儲(chǔ)在代碼段中的一段數(shù)據(jù)(二進(jìn)制指令的集合),函數(shù)名就是這段數(shù)據(jù)的開始位置
????????因此函數(shù)名就是地址,可以定義指向這段數(shù)據(jù)的指針變量,
????????返回值?(*函數(shù)指針)?(類型1,類型2,...);
????????函數(shù)的傳參:
????????????1、只能值傳遞(內(nèi)存拷貝),使用指針可提高效率(const?int?*)
????????????2、函數(shù)之間共享變量,全局變量(盡量少用),指針(注意安全)
????????????3、數(shù)組當(dāng)作函數(shù)的參數(shù)時(shí)就蛻變成了指針(長度丟失),額外增加一個(gè)參數(shù)傳遞數(shù)組長度。
修飾變量的關(guān)鍵字
????auto:用來修飾自動(dòng)創(chuàng)建、釋放的變量(局部變量、塊變量),不加就代表加。
????????注意:靜態(tài)變量、全局變量不能用它來修飾。
????static:
????????限制作用域:全局變量、普通函數(shù)
????????改變存儲(chǔ)位置:把局部變量、塊變量的存儲(chǔ)位置由棧改為bss、data
????????延長生命周期:把局部變量、塊變量的生命周期延長與全局變量一樣。
????????static?int?fun(void);
????const:為數(shù)據(jù)提供一種"保護(hù)"機(jī)制,變量被它修飾后就不能顯示修改。
????????也可以修飾函數(shù)的參數(shù)、返回值等。
????????const?int?fun(void);
????volatile:告訴編譯器此變量的值不穩(wěn)定、易變(不優(yōu)化變量的取值)。
????????多線程共享變量、硬件編程(裸機(jī)、驅(qū)動(dòng))
????register:申請(qǐng)把變量的存儲(chǔ)位置改為寄存器,但申請(qǐng)不一定成功
????????注意:被它修飾過的變量不能取地址
????extern:聲明變量,用于不同.c之間共享全局變量(只能解決編譯時(shí)問題)
?????
????注意:全局變量、局部變量、塊變量的變量名可以同名,由于作用域不同,會(huì)互相屏蔽。
????????塊變量?>?局部變量?>?全局變量?(塊變量屏蔽同名的局部變量)
?
程序在內(nèi)存的分段:
????代碼段?test:存儲(chǔ)的是代碼所編譯成的二進(jìn)制指令、字符串字面值、常量
????????具有只讀屬性,一旦修改會(huì)發(fā)生段錯(cuò)誤。
????全局?jǐn)?shù)據(jù)段?data:初始化過的全局變量、靜態(tài)變量
????bss段(靜態(tài)數(shù)據(jù)段):未初始化的全局變量、靜態(tài)變量
????????程序運(yùn)行前會(huì)清理為0;
????棧?stack:存儲(chǔ)局部變量、塊變量、大小有限,安全。
????????由操作系統(tǒng)管理,以函數(shù)為單位使用(函數(shù)調(diào)用結(jié)束后自動(dòng)釋放)。
????堆?heap:一般由程序員手動(dòng)管理(讓系統(tǒng)去映射),與指針配合使用,足夠大,使用麻煩,釋放的時(shí)間受控制
????????但不安全,容易產(chǎn)生內(nèi)存碎片、內(nèi)存泄漏。
指針:
????什么是指針:指針是一種數(shù)據(jù)類型(無符號(hào)整數(shù),代表內(nèi)存編號(hào)),使用它定義指針變量。
????????0~4G(32個(gè)1)4294967295?byte
????什么情況下使用指針:
????????1、函數(shù)之間共享變量(全局變量有命名沖突,不會(huì)被釋放,浪費(fèi)內(nèi)存)
????????2、優(yōu)化傳遞效率
????????????因?yàn)镃語言采用的是值傳遞(內(nèi)存拷貝),會(huì)隨著變量字節(jié)數(shù)的增加而降低運(yùn)行效率。
????????????而傳遞變量的地址,永遠(yuǎn)只拷貝4|8字節(jié)。
????????????void?func(const?int?*?p);
????????????但使用指針變量的值可能會(huì)被修改,可以配合const進(jìn)行保護(hù)。??
????????3、配合堆內(nèi)存
????如何使用指針:
????????定義:類型?*變量名_p;
????????????1、與普通變量一樣,默認(rèn)值不確定,為了安全一般初始化NULL。
????????????2、一個(gè)*只能定義一個(gè)指針變量
????????????????int?*p1,*p2;
????????????3、指針變量與普通的用法不同,為了避免混用,一般從名字上加以區(qū)別。
????????????4、指針變量的類型決定了解決引用時(shí)訪問的字節(jié)數(shù)。
????????賦值:變量名_p?=?地址;
????????????int*?p?=?NULL;
????????????1、注意地址的類型
????????????2、void*可以與任意類型的指針進(jìn)行自動(dòng)轉(zhuǎn)換(C++中不可以)
????????????3、要保障地址與物理內(nèi)存有對(duì)應(yīng)關(guān)系(映射過)。
????????解引用:*p;
????????????根據(jù)指針變量中存儲(chǔ)的內(nèi)存編號(hào),而訪問內(nèi)存中的數(shù)據(jù)。
????????????這個(gè)過程可以會(huì)有段錯(cuò)誤,但這是由于賦值了有問題的地址。
????使用指針要注意的問題:
????????1、野指針:指向的目標(biāo)不確定,解引用時(shí)不一定會(huì)出錯(cuò),但未知的危險(xiǎn)最可怕。
????????????而且野指針一旦產(chǎn)生就無法分辨,而預(yù)防的方法就是不制造野指針。
????????????1、定義指針時(shí)一定要初始化。
????????????2、指向的目標(biāo)被釋放后,要及時(shí)置空。
????????????3、不要指向隨時(shí)可能被釋放的目標(biāo)。
????????2、空指針:指針變量的值等于NULL,對(duì)這個(gè)地址解引用訪問時(shí),一定會(huì)產(chǎn)生段錯(cuò)誤。
????????????因?yàn)樗鎯?chǔ)的是操作系統(tǒng)重啟時(shí)所需要的數(shù)據(jù)。
????????????而預(yù)防的方法就是解引用前判斷(來歷不明)?if(NULL?==?p)
????指針的運(yùn)算:
????????指針+/-整數(shù)?=?指針+/-(寬度)*整數(shù)
????????指針-指針?=?(指針-指針)/寬度
????指針與數(shù)組名:
????????1、數(shù)組名就一個(gè)特殊的地址,它就代表數(shù)組的第一個(gè)元素的首地址,也能當(dāng)指針使用。
????????????arr[i]?<=>?*(地址+i);
????????????因此指針也能使用[]運(yùn)算符
????????2、指針與目標(biāo)內(nèi)存是指向關(guān)系,而數(shù)組名是對(duì)應(yīng)關(guān)系。
????????3、數(shù)組當(dāng)函數(shù)的參數(shù)就蛻變?yōu)榱酥羔樧兞?,長度丟失,安全性不保障。
????????????void?fun(int*?const?arr,size_t?len);
????指針與const的配合使用:
????????const?int*?p;
????????int?const?*?p;
????????int?*?const?p;
????????const?int?*?p;
????????int?const?*?const?p;
????指針的高級(jí)應(yīng)用:
????????指針數(shù)組:可以把無序的離散的數(shù)據(jù),歸納到一起。
????????數(shù)組指針:專門指向數(shù)組指針
????????二級(jí)指針:指向指針的指針
????????函數(shù)指針:指向函數(shù)的指針
字符串:
????由字符組成的串型數(shù)據(jù)結(jié)構(gòu),它的結(jié)束標(biāo)志是'\0'。
????字符串存在的形式:
????????字符數(shù)組:char?arr[5]?=?{'a','b','c','d'};
????????????一般存儲(chǔ)在棧,也可以存儲(chǔ)在堆。
????????????要考慮'\0'的位置
????????字符串字面值:由雙引號(hào)包括的若干個(gè)字符,"hehe"。
????????????以地址形式存在,需要使用const?char*?str;指針指向。
????????????數(shù)據(jù)存在只讀段,如果強(qiáng)行修改只會(huì)出現(xiàn)段錯(cuò)誤。
????????????背后隱藏著'\0';
????????char?str[]?=?"hehe";
????????一般使用字符串字面值來初始化字符數(shù)組。
????字符串的輸出:
????????printf?%s,puts,fprintf
????字符串的輸入:
????????scanf?%s:不能輸入空格
????????gets:不限制長度
????????fgets:可能會(huì)接受到'\n',或者輸入緩沖區(qū)中殘留數(shù)據(jù)
????字符串常見的操作:
????????strlen/strcat/strcpy/strcmp
????????strncat/strncpy/strncmp
????????memset/memcpy/strstr/strchr
????????sprintf/sscanf?用于拼接/解析字符串,非常好用
????????字符數(shù)據(jù)?->?數(shù)據(jù)?計(jì)算?數(shù)據(jù)?->?字符數(shù)據(jù)
堆內(nèi)存管理
????C語言中沒有內(nèi)存管理的語句,只能借助標(biāo)準(zhǔn)庫中的函數(shù)進(jìn)行管理堆內(nèi)存。
????void?*malloc(size_t?size);
????void?free(void?*ptr);
????void?*calloc(size_t?nmemb,?size_t?size);
????void?*realloc(void?*ptr,?size_t?size);
????當(dāng)向malloc首次申請(qǐng)內(nèi)存時(shí),malloc手中也沒有內(nèi)存,malloc會(huì)向系統(tǒng)申請(qǐng),系統(tǒng)會(huì)映射33頁內(nèi)存交給malloc管理,
????之后再向malloc申請(qǐng)內(nèi)存,malloc會(huì)直接從33頁內(nèi)存中分配,直到33頁用完,再向操作系統(tǒng)申請(qǐng)。
????????訪問malloc分配的內(nèi)存時(shí),可以越界,但不要超過33頁范圍。
????內(nèi)存泄漏:
????????1、指針管理失誤,指向其他位置。
????????2、free語句沒有執(zhí)行到。
????????3、free語句忘記寫。
????????就內(nèi)存沒釋放,有申請(qǐng)新內(nèi)存,導(dǎo)致可用的內(nèi)存越來越少,速度越來越慢。
????????前提:程序沒有結(jié)束,當(dāng)程序結(jié)束后屬于它的所有資源都會(huì)被系統(tǒng)回收。
????內(nèi)存碎片:
????????已經(jīng)釋放的內(nèi)存,但不能被再次使用,這叫內(nèi)存叫做內(nèi)存碎片。
????????內(nèi)存碎片不是錯(cuò)誤,它是由于內(nèi)存的釋放時(shí)間和分配時(shí)間不協(xié)調(diào)造成的。
????????內(nèi)存碎片無法避免(天然形成的),只能盡量減少:
????????????1、盡量使用棧內(nèi)存,只有在數(shù)據(jù)量比較多的時(shí)候再使用堆內(nèi)存。
????????????2、盡量申請(qǐng)大塊內(nèi)存自己管理。
????????????3、不要頻繁的申請(qǐng)釋放內(nèi)存。
預(yù)處理指令:
????把C代碼翻譯成標(biāo)準(zhǔn)的C代碼叫預(yù)處理、負(fù)責(zé)翻譯的程序叫預(yù)處理器、被翻譯的代碼叫預(yù)處理指令。
????查看預(yù)處理的結(jié)果:
????????gcc?-E?code.c?直接查看預(yù)處理的結(jié)果
????????gcc?-E?code.c?-o?code.i?把預(yù)處理的結(jié)果保存到文件中
????宏定義:
????????宏常量:用一個(gè)有意義的單詞代表一個(gè)字面值數(shù)據(jù)在代碼中使用,在預(yù)處理時(shí)把單詞替換成數(shù)據(jù)
????????????優(yōu)點(diǎn):提高可讀性、安全、擴(kuò)展方便
????????宏函數(shù):宏函數(shù)不是真正的函數(shù),是帶參數(shù)的宏,只是使用的方法類似函數(shù)
????????????預(yù)處理時(shí)參數(shù)會(huì)代入到表達(dá)式中,宏名會(huì)替換成后面的表達(dá)式。
????????????優(yōu)點(diǎn):運(yùn)行速度快(沒有參數(shù)傳遞),類型通用,只有極精簡(jiǎn)的代碼段才適合定義宏函數(shù)
????????????缺點(diǎn):不會(huì)進(jìn)行類型檢查,也沒有返回值,只有一個(gè)計(jì)算結(jié)果,大量使用會(huì)增加代碼段的冗余。
????????預(yù)定義的宏:
????????????__FILENAME__
????????????__func__
????????????__DATE__
????????????__TIME__
????????????__LINE__
????????條件編譯:
????????????#if
????????????#elif
????????????#else
????????????#endif
????????????#ifndef
????????????#ifndef
????????????頭文件衛(wèi)士
復(fù)合數(shù)據(jù)類型:
????結(jié)構(gòu)?struct
????設(shè)計(jì)數(shù)據(jù)類型
????typedef?struct?Student
????{
????????char?name[20];
????????char?sex;
????????short?age:1;
????}Student;
????定義結(jié)構(gòu)變量
????????Student?stu;
????????Student*?stup?=?malloc(sizeof(Student));
????訪問結(jié)構(gòu)成員
????????stu.name,stu.sex,stu.age
????????stup->name,stup->sex,stup->age
????計(jì)算結(jié)構(gòu)的字節(jié)數(shù):
????????注意:成員的順序不同會(huì)影響結(jié)構(gòu)的字節(jié)數(shù)。
????????對(duì)齊:假定從零地址開始,每成員的起始地址編號(hào),必須是它本身字節(jié)數(shù)的整數(shù)倍。
????????補(bǔ)齊:結(jié)構(gòu)的總字節(jié)數(shù)必須是它最大成員的整數(shù)倍。
????????注意:在Linux系統(tǒng)下計(jì)算補(bǔ)齊、對(duì)齊時(shí),成員超過4字節(jié)按4字節(jié)計(jì)算
????聯(lián)合?union
????????從語法上來說與結(jié)構(gòu)的用法基本類似,每個(gè)成員都從零地址開始,所有成員共有一塊內(nèi)存。
????????1、使用聯(lián)合判斷大小端
????????2、聯(lián)合的總字節(jié)數(shù)計(jì)算,不需要對(duì)齊,但有補(bǔ)齊
????枚舉?enum
????????值受限的int類型,把變量合法的值列舉出來,除此以外不能等于其他的值
????????枚舉值是常量,可以直接使用在case后,常與switch語句配合使用
文件操作:
????文件分類:
????????文本文件:記錄的是字符串的二進(jìn)制
????????二進(jìn)制文件:直接把數(shù)據(jù)補(bǔ)碼記錄到文件中
????文件打開:
????????FILE?*fopen(const?char?*path,?const?char?*mode);
????????"r"?以只讀方式打開文件,如果文件不存在則打開失敗,返回值為空。
????????"r+"?在"r"的基礎(chǔ)上增加寫權(quán)限。
????????"w"?以只寫方式打開文件,如果文件不存在則創(chuàng)建,如果文件存在則把內(nèi)容清空。
????????"w+"?在"w"的基礎(chǔ)上增加讀取權(quán)限。
????????"a"?以只寫方式打開文件,如果文件不存在則創(chuàng)建,如果文件存在則把內(nèi)容保留,與"w"區(qū)別是當(dāng)有新數(shù)據(jù)寫入,會(huì)追加到文件的末尾。
????????"a+"?在"a"的基礎(chǔ)上增加讀權(quán)限。?
????????"b"?在linux系統(tǒng)下沒有用,表示以二進(jìn)制格式打開文件。
????????????在Windows系統(tǒng)下不加b?'\n'?寫到文件中?系統(tǒng)會(huì)寫入'\n\r',加b則寫'\n'時(shí)只寫入'\n'.
????讀寫文本內(nèi)容:
????????int?fprintf(FILE?*stream,?const?char?*format,?...);
????????功能:把數(shù)據(jù)以文本形式寫入到文件中
????????stream:文件指針,fopen函數(shù)的返回值
????????format:格式化控制符,點(diǎn)位符等
????????...:要寫入的變量。
????????返回值:成功寫入的變量個(gè)數(shù)。??
????????int?fscanf(FILE?*stream,?const?char?*format,?...);
????????功能:從文件中讀取數(shù)據(jù)到變量,要求文件的內(nèi)容是字符。
????????stream:文件指針,fopen函數(shù)的返回值
????????format:格式化控制符,點(diǎn)位符等
????????...:變量的地址
????????返回值:成功讀取到返回0,失敗返回-1。????????
????讀寫二進(jìn)制內(nèi)容:
????????size_t?fwrite(const?void?*ptr,?size_t?size,?size_t?nmemb,FILE?*stream);
????????功能:內(nèi)存中的數(shù)據(jù),以二進(jìn)制形式寫入到文件中。
????????ptr:要寫入的內(nèi)存的首地址
????????size:要寫入的字節(jié)數(shù)
????????nmemb:要寫入的次數(shù)
????????stream:文件指針,fopen函數(shù)的返回值
????????返回值:成功寫入的次數(shù)?
????????size_t?fread(void?*ptr,?size_t?size,?size_t?nmemb,?FILE?*stream);
????????功能:從文件中以二進(jìn)制方式讀取數(shù)據(jù)到內(nèi)存中。
????????ptr:用來存放數(shù)據(jù)的內(nèi)存首地址
????????size:要讀取的字節(jié)數(shù)
????????nmemb:要讀取的次數(shù)
????????stream:文件指針,fopen函數(shù)的返回值
????????返回值:成功讀取的次數(shù)
????文件位置指針:
????????每個(gè)打開的文件系統(tǒng)都會(huì)用一個(gè)指針記錄著它的讀寫位置,這個(gè)指針指向哪里,
????????接下來對(duì)文件的讀取就會(huì)從哪里繼續(xù),指針的位置會(huì)隨著文件的讀寫自動(dòng)發(fā)生變化
????文件結(jié)構(gòu)體中有一個(gè)成員記錄文件的讀寫位置,稱它位文件位置指針,有些情況下需要調(diào)整它的位置,獲取到正確的數(shù)據(jù)。
????????int?fseek(FILE?*stream,?long?offset,?int?whence);
????????功能:根據(jù)基礎(chǔ)位置+偏移值調(diào)整文件指針的位置。
????????stream:文件指針,fopen函數(shù)的返回值
????????offset:可以為正負(fù),正往右(偏移值)
????????whence:(基礎(chǔ)位置)
????????????SEEK_SET?文件頭
????????????SEEK_CUR?當(dāng)前位置
????????????SEEK_END?文件尾
????????long?ftell(FILE?*stream);
????????功能:返回文件位置指針?biāo)诘奈恢谩?/p>
????????void?rewind(FILE?*stream);
????????功能:把文件位置指針調(diào)整到開頭
????文件關(guān)閉:
????????int?fclose(FILE?*fp);
????????功能:把文件關(guān)閉,以釋放相關(guān)資源,避免數(shù)據(jù)丟失。
多文件編程:
????隨著代碼量的增加,不得不把代碼分成若干個(gè).c文件編寫,這樣能夠給文件。。。
????但缺點(diǎn)是不方便編譯,需要借助編譯腳本。
????如何進(jìn)行多文件編譯:根據(jù)功能、責(zé)任分成若干個(gè).c文件,然后為每個(gè).c文件配備一個(gè)輔助文件.h然后單獨(dú)編譯每個(gè).c文件,
????????生成目標(biāo)文件.o,然后再把.o文件合并成可執(zhí)行文件。
????頭文件中應(yīng)該寫什么:
????????1、頭文件衛(wèi)士
????????2、宏常量、宏函數(shù)
????????3、結(jié)構(gòu)、聯(lián)合、枚舉的設(shè)計(jì)
????????4、變量、函數(shù)的聲明
????????5、static函數(shù)的實(shí)現(xiàn)
編譯腳本:
????把用于編譯的命令記錄到文件中(makefile/Makefile),在終端里執(zhí)行make程序時(shí),make程序會(huì)自動(dòng)讀取當(dāng)前目錄中的。。。
????make程序會(huì)監(jiān)控每個(gè)文件的最后修改時(shí)間,如果沒有被修改的文件不需要重新編譯,這樣可以節(jié)約大量的時(shí)間
????注意:一定要使用tab縮進(jìn)
GDB調(diào)試:
????1、設(shè)置ubuntu系統(tǒng),當(dāng)段錯(cuò)誤時(shí)產(chǎn)生core
????????ulimit?-c?unlimited
????2、編譯時(shí)增加-g參數(shù)
????3、再次執(zhí)行新編譯的程序,重新產(chǎn)生core文件
????4、gdb?a.out?core?進(jìn)行調(diào)試
????????run/where