1.字符串
字符串就是一個字符數(shù)組,結(jié)尾以'\0'作為標(biāo)志
一個字符占用一個字節(jié)(漢字占用兩個字節(jié)),從左到右依次存放,在字符串的結(jié)尾自動加入一個字節(jié)的結(jié)束標(biāo)志'\0'
'a'與"a"的不同:'a'代表一個字符占用一個字節(jié);"a"代表一個字符串占用兩個字節(jié).
字符串初始化:char str[10]="abc123!@#";//不能寫成char str[10];str="dfh";(初始化聲明的時候的=不代表賦值操作,只是初始化)
2.sizeof(類型名)
sizeof返回的值是無符號的整數(shù)
可以用sizeof(a)/sizeof(a[0])計算數(shù)組長度
3.類型定義(typedef)
typedef int Bool; ? ?//(后面變量名的首字母最好大寫)
Bool flag; ? ?//類似與使用了int flag
4.宏定義
【定義宏】#define BOOL int
數(shù)組和指針不能用宏定義,宏定義中的替換列表為空也是合法的,也可以包含對另一個宏的調(diào)用,但宏不能調(diào)用它本身.
一個數(shù)字常量,如果不是0和1,就最好定義成宏.
【帶參數(shù)的宏】 #define ?標(biāo)示符(x1,x1,…,xn) ?替換列表 ? ?//參數(shù)在替換列表中都要放在圓括號中
5..數(shù)組
定義數(shù)組時韩容,數(shù)組名不能和變量名相同款违,也不能和系統(tǒng)關(guān)鍵字一樣
數(shù)組的地址就是數(shù)組元素的首地址,使用數(shù)組名a群凶,代表的就是數(shù)組a[]的地址
多維數(shù)組:不常用插爹,因為指針數(shù)組更加的靈活好用
無論是一維數(shù)組還是多維數(shù)組,通過單詞const作為數(shù)組聲明的開始可以把數(shù)組變?yōu)椤俺A俊保?/p>
(如:const int months[]={31,28,31,30,31,30,31,31,30,31,30,31};)
6..函數(shù)
在調(diào)用函數(shù)前请梢,都需要先聲明函數(shù)赠尾,函數(shù)聲明類似與函數(shù)定義的第一行,函數(shù)的聲明必須與函數(shù)的定義一樣毅弧。
【函數(shù)聲明】 返回類型 ?函數(shù)名(形式參數(shù)); ? ?【編譯器只預(yù)處理函數(shù)气嫁,但是不分配內(nèi)存】
【函數(shù)定義】 返回類型 ?函數(shù)名(形式參數(shù)) ? ?【開辟內(nèi)存空間,分配內(nèi)存給函數(shù)形真,函數(shù)入口地址為函數(shù)名所在地址】
2)從返回值的角度:
有返回值:return,(函數(shù)有且只能返回一個返回值),可以是基本數(shù)據(jù)類型和指針等杉编。
無返回值:void,在C89標(biāo)準(zhǔn)中可以忽略返回值類型,UNIX中默認(rèn)為int咆霜,Window VC中為void邓馒;在C99標(biāo)準(zhǔn)中不可以忽略返回值類型。
3)從參數(shù)的角度:
帶參數(shù):需要告訴編譯器參數(shù)的類型和數(shù)量
int main(int argc,char *argv[]);
int main(int argc,char **argv);
不帶參數(shù):參數(shù)列表為空蛾坯,void光酣,可以省略,即int main()或int main(void)脉课;就是不需要參數(shù)來參與運算救军。
.返回語句
return:【return 表達(dá)式】如果return中表達(dá)式的類型和函數(shù)返回的類型不一致,系統(tǒng)會把表達(dá)式的類型轉(zhuǎn)換成返回類型
exit:任何函數(shù)中都可以使用倘零,【exit(表達(dá)式)】唱遭;包含在#include 頭文件中。
main函數(shù)的返回值是狀態(tài)碼呈驶,0表示正常結(jié)束拷泽,非0為異常結(jié)束。
7..遞歸
遞歸是函數(shù)嵌套調(diào)用的一種特殊形式袖瞻,就是當(dāng)一個函數(shù)調(diào)用另外一個函數(shù)的過程時司致,另一個函數(shù)恰好是它本身。
遞歸產(chǎn)生的條件:直接或間接的調(diào)用它本身聋迎,有一個出口(即結(jié)束遞歸的條件)脂矫,要有一個明顯的公理或公式,有規(guī)律可循霉晕。
1)直接遞歸調(diào)用
2)間接遞歸調(diào)用
注意:
1)遞歸調(diào)用在發(fā)生時庭再,消耗了大量的系統(tǒng)資源捞奕,反復(fù)讀寫棧內(nèi)存,CPU資源佩微,會降低系統(tǒng)性能缝彬,不可控或深層遞歸都會造成系統(tǒng)不穩(wěn)定
2)我們在開發(fā)過程中使用的都是淺層遞歸,如Windows搜索哺眯,使用了多線程,淺層遞歸(一般不超過3層)
3)遞歸調(diào)用也被用于分治算法
4)能不用就不用遞歸扒俯,如:.(){ .|. };. ?(.本身是一個函數(shù)奶卓,()為.函數(shù)的參數(shù)列表,;前為.函數(shù)的定義撼玄,最后一個.是調(diào)用這個函數(shù))
8..迭代
迭代法又叫做遞推夺姑,凡是能用遞歸來實現(xiàn)的迭代或遞推都能實現(xiàn)。
9..指針
簡單的說掌猛,指針就是地址盏浙。
內(nèi)存中的最小存儲單元是字節(jié),一個字節(jié)有8位荔茬,每一位都有自己的地址废膘,指針就是他們的首地址。
基本數(shù)據(jù)類型的指針慕蔚,就是他們在內(nèi)存中的首地址丐黄。
構(gòu)造類型的指針,數(shù)組孔飒,他的位置就是灌闺,數(shù)組名稱所在內(nèi)存的首地址,即a[0]的地址或者是數(shù)組名坏瞄。
函數(shù)類型的指針桂对,就是函數(shù)的入口地址,即函數(shù)名所在內(nèi)存的首地址鸠匀。
指針變量:和其他基本數(shù)據(jù)類型的變量類似蕉斜,特殊的是他是能保存地址的變量。
1.定義指針的時候沒有初始化
2.指針指向一個局部變量狮崩,當(dāng)局部變量執(zhí)行完畢釋放后蛛勉,仍然指向該局部變量的時候(用完置NULL即可)
3.當(dāng)指針指向一塊動態(tài)的內(nèi)存空間時malloc(new)使用完畢被free(delete)釋放后,仍然指向該空間睦柴,(用完置NULL即可)
10.指針和常量的關(guān)系
常量指針:指針指向了一個常量的指針變量诽凌,常量的內(nèi)容不可以修改,但是地址可以修改坦敌。
int const *p; ? ?const在*號后侣诵,是p的值不能修改痢法;const在*號前,是*p的內(nèi)容不能修改
指針常量:是個常量杜顺,是指指針變量P的值不能被修改财搁,p是個常量,而指針指向的對象的值是可以改變的躬络。
11.指針和數(shù)組的關(guān)系
數(shù)組指針:指向一維數(shù)組的指針尖奔,即數(shù)組的首元素
int a[10];int *p=NULL;p=a;
是一個指向二維數(shù)組一行的指針變量,即二維數(shù)組的首行的地址
int (*p)[表達(dá)式];
指針數(shù)組:數(shù)組元素是指針變量
int *p[表達(dá)式];
12.結(jié)構(gòu)體(struct)
能夠保存不同數(shù)據(jù)類型的一種構(gòu)造數(shù)據(jù)類型
【關(guān)鍵字】struct
【定義結(jié)構(gòu)體】 ? ?struct 結(jié)構(gòu)體名{
成員變量1;
成員變量2;
…
成員變量n;
}; ?
【結(jié)構(gòu)體和指針】
1)指向結(jié)構(gòu)體的指針
struct struct_name *p; ? ?//p是指針變量名
p=&object_name; ? ? ? ?//&取地址符不能忘
【結(jié)構(gòu)體的嵌套】
一個結(jié)構(gòu)體中嵌套了另一個結(jié)構(gòu)體
struct struct_name{
成員變量1;
成員變量2;
struct struct_name_a{
成員變量a;
成員變量b;
}object_name_a;
}object_name;
【結(jié)構(gòu)體數(shù)組】
數(shù)組中的每個元素都是一個結(jié)構(gòu)體變量
struct struct_name{
成員變量1;
成員變量2;
}數(shù)組名[表達(dá)式]; ? ? ? ?//表達(dá)式可以為空穷当,為空的時候是不定長度的數(shù)組
13.枚舉(enum)
枚舉的成員中只能用一種類型,成員內(nèi)不指定序號的時候都以0開始,C語言把枚舉變量和常量作為整數(shù)來處理
enum color{red, black, blue}a,b; ? ?//中間以逗號隔開
14.鏈表
鏈表是線性表的一種,是線性表的鏈?zhǔn)酱鎯?是一種使用動態(tài)內(nèi)存分配的,能保存不同數(shù)據(jù)類型的一種數(shù)據(jù)結(jié)構(gòu).構(gòu)成鏈表的最小單位稱為節(jié)點.
C語言執(zhí)行過程中,在內(nèi)存中的情況:
1)代碼段(靜態(tài)區(qū)域)
代碼段由程序中的機(jī)器碼組成,C語言中源代碼編譯后就形成了機(jī)器碼,執(zhí)行的時候,CPU的程序計數(shù)器指向了代碼段的每一條代碼,并由CPU依次執(zhí)行
2)數(shù)據(jù)段(靜態(tài)區(qū)域)
只讀數(shù)據(jù)段,是程序使用一些不會被修改的數(shù)據(jù),使用這些數(shù)的方式類似與查表式的操作,放置在只讀存儲器中;
已初始化讀寫數(shù)據(jù)段,是在程序中聲明,有初值的變量,需占用寄存器空間,在程序執(zhí)行時,位于可讀寫的內(nèi)存區(qū)域內(nèi),供程序運行時讀寫
4)堆空間(動態(tài)區(qū)域)
只在程序運行時出現(xiàn),一般由程序員分配和釋放,在具有操作系統(tǒng)的情況下,若程序員忘記釋放,在程序結(jié)束后,系統(tǒng)會自動回收內(nèi)存
5)棧內(nèi)存(動態(tài)區(qū)域)
只在程序運行時出現(xiàn),在函數(shù)內(nèi)部使用的變量,函數(shù)參數(shù)及返回值,函數(shù)調(diào)用(遞歸)都將使用椞嶙拢空間.棧空間是由編譯器自動分配和釋放的內(nèi)存.
C語言提供的兩種內(nèi)存分配的方式:
1).靜態(tài)內(nèi)存分配(棧內(nèi)存)
由編譯器自動為我們分配的內(nèi)存空間,一般棧內(nèi)存的大小為10M~30M
內(nèi)存的對齊:是指整型占4個字節(jié),大于4個字節(jié)的數(shù)據(jù)類型,也按照4個字節(jié)來計算,而且是4的整數(shù)倍
內(nèi)存的補(bǔ)齊:只在結(jié)構(gòu)體中有,如果所占字節(jié)數(shù)不足4個數(shù)據(jù)類型,比如char,需將不足的字節(jié)數(shù)補(bǔ)空,補(bǔ)夠4個字節(jié)
2).動態(tài)分配內(nèi)存(malloc向堆申請內(nèi)存)
malloc函數(shù)(分配后不初始化)
void *malloc(size_t size); ? ?//返回值是萬能指針,在Mac下占8個字節(jié),在Win下占4個字節(jié)
用于動態(tài)的向堆內(nèi)存申請內(nèi)存空間,使用完后,要使用free()函數(shù)釋放該內(nèi)存
一旦指針p指向動態(tài)分配的內(nèi)存塊,就可以忽略p是指針的事實,并且把它用作數(shù)組的名字,p[i].
靜態(tài)庫(.a): 是指在編譯鏈接時, 把庫文件中的代碼全部加入到可執(zhí)行文件中, 因此生成的文件比較大, 但在運行時就不再需要庫文件了.
動態(tài)庫(.so): 在編譯鏈接時, 并沒有把庫文件的代碼加入到可執(zhí)行文件中, 而是在程序執(zhí)行時由運行時鏈接文件加載庫, 節(jié)省了系統(tǒng)開銷.