C語(yǔ)言大總結(jié)
一夸研、基礎(chǔ):
1狰域、進(jìn)制媳拴、位權(quán)、1字節(jié)等于8位(位是計(jì)算機(jī)的最小儲(chǔ)存單位兆览,字節(jié)是計(jì)算機(jī)最小存儲(chǔ)單元)屈溉、十進(jìn)制轉(zhuǎn)換其他進(jìn)制:連除倒取余,其他進(jìn)制轉(zhuǎn)換十進(jìn)制:按權(quán)求和
2抬探、單行注釋:// 多行注釋: /**/ (內(nèi)容寫在量型號(hào)之間)
3子巾、數(shù)據(jù)類型:整形類型、浮點(diǎn)類型小压、字符類型线梗。
整型類型:長(zhǎng)整形(long 4/8)、整形(int 4)怠益、短整型(short 2)
浮點(diǎn)類型:?jiǎn)尉龋╢loat 4)仪搔、雙精度(double 8)
字符類型:字符類型(char 1)
4、常量:程序運(yùn)行期間不能被改變的量蜻牢。
常量 類型:整型常量烤咧、浮點(diǎn)型常量偏陪、字符型常量
變量:實(shí)際上是儲(chǔ)存區(qū)域,也可以做表達(dá)式煮嫌,是程序運(yùn) 行期間可以被改變的量笛谦。
變量定義:由類型符號(hào)、變量名昌阿、初始值三部分組成(如: int a = 5;)
變量命名規(guī)則:由數(shù)字饥脑、字母、下劃線組成的宝泵,但不能 以數(shù)字開頭好啰,不能與關(guān)鍵字重復(fù),不能重復(fù)使用變量名(同一作用域)儿奶,見名知意。
5鳄抒、賦值運(yùn)算符:= 把右邊的值賦給左邊 優(yōu)先級(jí)別最低
算數(shù)運(yùn)算符:+闯捎, -, *许溅, / 整型兩邊相除取整瓤鼻,除數(shù)不能為0,% 兩邊均為正數(shù) 贤重,++ 自增運(yùn)算符茬祷、- - 自減運(yùn)算符:(它倆在前,先執(zhí)行并蝗,它倆在后祭犯,后執(zhí)行。
6滚停、復(fù)合運(yùn)算符:+= (a += b; 相當(dāng)于a = a + b); -=; *=; /=; %=;(語(yǔ)法含義同上)
7沃粗、表達(dá)式:由常量、變量與運(yùn)算符組合而成(注:表達(dá)式會(huì)有返回值)
8键畴、輸出函數(shù):printf()最盅; 輸入函數(shù) scanf()(注:以回車確定輸入結(jié)束,只有大回車鍵才會(huì)結(jié)束起惕;不要再格式串后面加’\n’字符涡贱,否則會(huì)抵消人工輸入的回車)。
轉(zhuǎn)化符:%c->char; %d->int; %sd->short; %ld->long;%f->float惹想、double问词。
9、轉(zhuǎn)換格式控制:最少占4位:
printf(“%04d”,12); //不足補(bǔ)0
printf(“%4.2f”,1.2345); //保留小數(shù)點(diǎn)后兩位
printf(“%-4d”,12); //左對(duì)齊
\n回車符勺馆; \打印\戏售; %%打印%侨核;
二、運(yùn)算符
1灌灾、BOOL類型:只有YES(1)和NO(0)兩個(gè)值搓译;
bool類型:由ture(非0數(shù)字)和flase(0)兩種值;
BOOL和bool區(qū)別:1)锋喜、在C中只有小布爾沒(méi)有大布爾些己; 2)、在C和OC中小布爾中非零為真嘿般,零為假段标;3)、在OC中大布爾中1為真炉奴,0為假逼庞,其它數(shù)字原樣輸出,不做判斷條件
2瞻赶、關(guān)系運(yùn)算符:用于比較運(yùn)算赛糟,結(jié)果值有真假兩種,結(jié)果值由BOOL類型儲(chǔ)存
> < >= <= == 砸逊!=
3璧南、邏輯運(yùn)算符:由邏輯運(yùn)算符組成,結(jié)果也是非真即假
&&(邏輯與):一假即假(有一邊為假則結(jié)果為假)
||(邏輯或) :一真即真(有一邊為真則結(jié)果為真)
Jσ荨(邏輯非) :對(duì)表達(dá)式結(jié)果取反
4司倚、條件運(yùn)算符:條件表達(dá)式?表達(dá)式1:表達(dá)式2
如果條件為真篓像,則執(zhí)行表達(dá)式1动知。 如果條件為假,則執(zhí)行表達(dá)式2遗淳。
5拍柒、枚舉類型:屬于構(gòu)造類型,是一組由符號(hào)的整型常量屈暗,一一羅列所有狀態(tài)拆讯,羅列所有結(jié)果。 enum枚舉名{枚舉值表}
目的和作用:提高程序可讀性养叛;將人能看懂的標(biāo)示符與計(jì)算機(jī)能識(shí)別的數(shù)字建立對(duì)應(yīng)關(guān)系
三种呐、程序的三種結(jié)構(gòu):
1、順序結(jié)構(gòu):按照語(yǔ)句順序執(zhí)行
2弃甥、分支結(jié)構(gòu):判斷條件在兩個(gè)語(yǔ)句序列中選擇爽室,一旦進(jìn)行判斷必須選擇其中一個(gè)。
if語(yǔ)句:形式一:if (條件表達(dá)式) {語(yǔ)句淆攻;}
形式二:if (條件表達(dá)式) {語(yǔ)句1阔墩;} else{語(yǔ)句2嘿架;}
形式三:if (條件表達(dá)式1) {語(yǔ)句1;} else if條件表達(dá)式2){語(yǔ)句2啸箫;} else{語(yǔ)句3耸彪;}
switch語(yǔ)句:多分支語(yǔ)句,通過(guò)判斷整形表達(dá)式的值忘苛,來(lái)判斷執(zhí)行那個(gè)語(yǔ)句蝉娜。常與case配合使用。
break:跳出本層循環(huán)扎唾,如果外層還有循環(huán)的話召川,則執(zhí)行外層循環(huán),如果外層沒(méi)有循環(huán)胸遇,則執(zhí)行循環(huán)后面的代碼荧呐。(常與if、switch連用)
continue:跳出本次循環(huán)狐榔,跳出本次循環(huán)坛增,遇到continue后,不管continue后面有無(wú)代碼薄腻,均不執(zhí)行,提前結(jié)束當(dāng)前循環(huán)届案,開啟下一次循環(huán)庵楷。(常與if連用)
arc4random():返回隨機(jī)數(shù)的函數(shù)。 如果要一個(gè)隨機(jī)數(shù)在【a, b】范圍內(nèi)的整數(shù)楣颠。公式為:arc4random() % (b - a +1) + a;
3尽纽、循環(huán)語(yǔ)句:在滿足一個(gè)條件的情況下反復(fù)執(zhí)行一個(gè)語(yǔ) 句序列。
while語(yǔ)句:while(條件表達(dá)式){語(yǔ)句童漩;}條件表達(dá)式為真執(zhí)行循環(huán)體弄贿,一旦為假立即停止執(zhí)行。
do…while…語(yǔ)句:do{語(yǔ)句矫膨;} while (條件表達(dá)式),先執(zhí)行循環(huán)體差凹,再判斷循環(huán)條件直到不滿足,才結(jié)束循環(huán)侧馅。
for語(yǔ)句:for(循環(huán)變量初始化危尿;循環(huán)條件;循環(huán)增量){語(yǔ)句馁痴;}循環(huán)條件為真才執(zhí)行循環(huán)體谊娇。
四、一維數(shù)組
一維數(shù)組:屬于構(gòu)造結(jié)構(gòu)罗晕,是由相同類型的成員組成的一組數(shù)據(jù)济欢。
數(shù)組名:存儲(chǔ)不同數(shù)據(jù)類型的數(shù)組有各種對(duì)應(yīng)的名稱(名稱可以隨意起)赠堵,但 要見名知意。
元素:數(shù)組由多個(gè)成員組合而成法褥,每個(gè)成員被稱為“數(shù)組的元素”
1茫叭、定義一個(gè)數(shù)組
int array[3] = {1, 2, 3};
int:聲明數(shù)組類型 array:數(shù)組名 [5]:數(shù)組長(zhǎng)度(注:定義數(shù)組時(shí),可以省略元素個(gè)數(shù)挖胃,因?yàn)榫幾g器會(huì)自動(dòng)推斷出元素個(gè)數(shù)杂靶,但是“[]”堅(jiān)決不能省略。) { } :給數(shù)組賦值酱鸭,元素之間用逗號(hào)分隔開(注:1)定義數(shù)組時(shí)吗垮,可以不給每一個(gè)元素賦值,沒(méi)有賦值的元素系統(tǒng)會(huì)默認(rèn)為0凹髓。2)定義數(shù)組時(shí)烁登,給定了數(shù)組長(zhǎng)度,首元素為0蔚舀,其他元素不賦值饵沧,則默認(rèn)為0,這樣五個(gè)元素均為0赌躺。3)大括號(hào)中最好賦上初始值狼牺,因?yàn)闆](méi)有賦值是系統(tǒng)會(huì)根據(jù)Xcode編譯環(huán)境來(lái)賦值,有時(shí)可能有礼患,有時(shí)可能無(wú)是钥,這樣就會(huì)出現(xiàn)定義不明,所以建議賦上值缅叠。)
2悄泥、數(shù)組的內(nèi)存占用
1)使用sizeof()函數(shù)求數(shù)組占字節(jié)數(shù)
printf("array[3]數(shù)組所占字節(jié)數(shù)%ld", sizeof(array));
結(jié)果:12 因?yàn)槊總€(gè)int類型占4個(gè)字節(jié),有3個(gè)元素肤粱,所以共12個(gè)字節(jié) 弹囚。
2)利用sizeof()函數(shù)求數(shù)組元素個(gè)數(shù)
先求出數(shù)組所占字節(jié)數(shù),再求出其中某個(gè)元素所占字節(jié)數(shù)领曼,再相除就得出數(shù)組元素個(gè)數(shù)鸥鹉。
int array[5] = {4, 6悯森, 7宋舷, 2, 8};
int a = (sizeof(array) / sizeof(array[1]));
printf("a = %d\n", a); 結(jié)果為:a = 5
3瓢姻、數(shù)組元素的訪問(wèn)方式:數(shù)組名+下標(biāo)
1)int array[6] = {12, 21, 32, 23, 25};
訪問(wèn)array中的32這個(gè)元素: 數(shù)組名:array祝蝠,下標(biāo):從零開始計(jì)數(shù),32在第3個(gè)位置上,所以32的下標(biāo)是2绎狭。
int temp = array[2];
printf("temp = %d, array[2] = %d\n", temp, array[2]); 結(jié)果:32细溅,32
(注:可以直接訪問(wèn),打印出來(lái)儡嘶,也可以把值賦給另一個(gè)相同類型的變量再打印出來(lái))
2)數(shù)組下標(biāo)越界:數(shù)組下標(biāo)超過(guò)了數(shù)組長(zhǎng)度喇聊,訪問(wèn)了不屬于數(shù)組的內(nèi)存空間。在C中是沒(méi)有“數(shù)組下標(biāo)越界保護(hù)”機(jī)制蹦狂,所以在寫代碼時(shí)誓篱,要避免下標(biāo)越界。
3)修改數(shù)組元素
3.1)修改array中的第二個(gè)元素為62
int array[6] = {12, 21, 32, 23, 25};
array[1] = 62;
printf("array[1] = %d\n", array[1]); 結(jié)果:array[1] = 62
3.2) 定義一個(gè)新的數(shù)組凯楔,array1,將array的元素窜骄,原樣賦給arrary1.
int array[5] = {12, 21, 32, 23};
int array1[5] = {0};
for (int i = 0; i < 5; i++) {
array1[i] = array[i]; // 數(shù)組的下標(biāo)可以是常量,也可以是變量
printf("array1[%d] = %d\n", i, array1[i]); // 數(shù)組的輸出需要for循環(huán)進(jìn)行遍歷
}
// array1 = array; 數(shù)組中不能整體訪問(wèn)數(shù)組元素摆屯,也不能整體賦值邻遏,而要逐一的遍歷數(shù)組元素,進(jìn)行訪問(wèn)虐骑、賦值准验、輸出。
// 定義一個(gè)具有20個(gè)元素的數(shù)組廷没,每個(gè)元素的取值范圍是【30糊饱,70】,求數(shù)組元素的和
// 1.定義一個(gè)整型數(shù)組長(zhǎng)度為20
int array[20] = {0};
// 2.開啟一個(gè)for循環(huán)颠黎,使用循環(huán)給數(shù)組元素賦值
for (int i = 0; i < 20; i++) {
// 2.1 生成【30济似,70】之間的數(shù)
int temp = arc4random() % (70 - 30 + 1) + 30;
//2.2 將生成的隨機(jī)數(shù)賦值給對(duì)應(yīng)的元素
array[i] = temp;
printf("array[%d] = %d\n", i, array[i]);
}
// 3.求數(shù)組元素的和
// 3.1定義一個(gè)保存和的變量
int sum = 0;
//3.2 使用for循環(huán)遍歷數(shù)組元素,同時(shí)將元素累加起來(lái)
for (int i = 0; i < 20; i++) {
// 3.2.1 獲取當(dāng)前數(shù)組元素并將獲取到的元素加起來(lái)
sum = sum + array[i];
}
printf("元素總和為%d\n", sum);
// 定義三個(gè)數(shù)組盏缤,將隨機(jī)產(chǎn)生的數(shù)放入其中兩個(gè)數(shù)組中,將這兩個(gè)數(shù)組的值加起來(lái)放入第三個(gè)數(shù)組中
// 1蓖扑、 定義三個(gè)數(shù)組唉铜,并初始化。
int array1[10] = {0};
int array2[10] = {0};
int array3[10] = {0};
// 2律杠、 使用一個(gè)for循環(huán)潭流,給第一個(gè)數(shù)組和第二個(gè)數(shù)組賦值,將兩個(gè)數(shù)組個(gè)元素加起來(lái)柜去,交給第三個(gè)元素灰嫉。
for (int i = 0; i < 10; i++) {
// 2.1、 分別把生成的隨機(jī)數(shù)賦給兩個(gè)數(shù)組
array1[i] = arc4random() % (40 - 20 + 1) + 20;
array2[i] = arc4random() % (40 - 20 + 1) + 20;
// 2.2嗓奢、兩數(shù)組進(jìn)行相加
array3[i] = array1[i] + array2[i];
// 3讼撒、 打印驗(yàn)證結(jié)果是否正確
printf("array1[%d] = %d, array2[%d] = %d, array3[%d] = %d\n", i, array1[i], i,array2[i], i,array3[i]);
}
4、冒泡排序
int array[5] = {12, 45, 23, 42, 56};
//趟數(shù) = 元素個(gè)數(shù) - 1;每趟比較的次數(shù) = 元素個(gè)數(shù) - 當(dāng)前的趟數(shù)
//兩層for循環(huán)根盒,外層叢植比較趟數(shù)钳幅、內(nèi)層控制比較次數(shù)
//趟數(shù)
for (int j = 0; j < 5 - 1; j++) {
//次數(shù)
for (int k = 0; k < 5 - (j+ 1); k++) {
if (array[k] > array[k + 1]){ //因?yàn)槊刻吮容^都要從下標(biāo)為0開始,j在每次從外層循環(huán)進(jìn)入內(nèi)層時(shí)炎滞,都要被初始化為0敢艰。因?yàn)槊看伪容^,下標(biāo)都要加一册赛,j在每次內(nèi)層循環(huán)時(shí)钠导,也會(huì)加一,所以森瘪,在這里是用j做下標(biāo)是沒(méi)有問(wèn)題的牡属。
//滿足交換條件,開始交換位置柜砾。
//1.定義一個(gè)臨時(shí)變量
int temp = array[k]; 6
array[k] = array[k + 1];
array[k + 1] = temp;
}
}
}
for (int i = 0; i < 5; i++) {
printf("%d ", array[i]);
}
5湃望、字符數(shù)組
字符數(shù)組:保存字符的數(shù)組就是字符數(shù)組。有’\0’結(jié)束標(biāo)識(shí)的字符數(shù)組也稱為字符串痰驱。
定義一個(gè)字符數(shù)組:聲明類型证芭、數(shù)組名、數(shù)組長(zhǎng)度担映、賦初值
char char_Array[5] = {'h', 'e', 'l', 'l', ‘o’};
//每個(gè)字符占一個(gè)字節(jié)废士,數(shù)組長(zhǎng)度是5,所以數(shù)組占5*1個(gè)字節(jié)的內(nèi)存蝇完。
char char_Array[5] = {'h', 'e', 'l', 'l', 'o', '\0'};和char char_Array[5] =“hello”;
是同一個(gè)意思都便是定義字符串hello官硝。
字符串和字符數(shù)組的區(qū)別:
如果字符數(shù)組最后一個(gè)字符末尾沒(méi)有‘\0’,則是一個(gè)字符數(shù)組
如果字符數(shù)組最后一個(gè)字符末尾有‘\0’短蜕,則是這個(gè)字符數(shù)組就是字符串氢架。
字符串操作函數(shù)
strlen():返回字符串的有效字符個(gè)數(shù)
strcpy():字符串拷貝函數(shù):把第二個(gè)參數(shù)的值拷貝給第一個(gè)參數(shù)
strcat() 字符串拼接:把第二個(gè)參數(shù)的值,拼接到第一個(gè)參數(shù)的后面
strcmp() 字符串比較:第一個(gè)參數(shù)大于第二個(gè)參數(shù)返回一個(gè)正整數(shù)朋魔,第一個(gè)參數(shù)小于第二個(gè)參數(shù)岖研,返回一個(gè)負(fù)整數(shù),兩個(gè)參數(shù)相等警检,返回零孙援。
五、函數(shù)
1扇雕、函數(shù):完成某一功能的代碼段拓售。
函數(shù)名:給這段代碼取一個(gè)名字,以后就可以通過(guò)這個(gè)名字來(lái)代替這段代碼镶奉,遵守變量名的命名法則础淤。
函數(shù)參數(shù): 有的函數(shù)在完成某一任務(wù)時(shí)需要的材料崭放,我們把在完成任務(wù)所需的材料叫函數(shù)的參數(shù)。 在被調(diào)函數(shù)中值骇,參數(shù)叫“形參”莹菱,在主調(diào)函數(shù)中,參數(shù)叫“實(shí)參”吱瘩。
函數(shù)參數(shù)傳遞:將實(shí)參的值拷貝一份到形參變量的空間中道伟,在被調(diào)用函數(shù)中操作的參數(shù)是新開辟的內(nèi)存的數(shù)值,和實(shí)參沒(méi)有關(guān)系使碾。
參數(shù)列表:如果沒(méi)有參數(shù)蜜徽,可以用void修飾,也可以什么都不寫票摇,但是小括號(hào)不能省略拘鞋。
函數(shù)的返回值:有的函數(shù)在完成任務(wù)之后,需要把任務(wù)結(jié)果返回給主調(diào)函數(shù)矢门,就可以通過(guò)return語(yǔ)句來(lái)將值返回盆色。注意:return只能返回一個(gè)值,同時(shí)不能返回?cái)?shù)組祟剔。
return:return標(biāo)志著函數(shù)的結(jié)束隔躲,如果return后邊有數(shù)值,則將這個(gè)數(shù)值交給主調(diào)函數(shù)物延。當(dāng)return只負(fù)責(zé)結(jié)束函數(shù)執(zhí)行時(shí)宣旱,可以省略return鞋拟。return后?的語(yǔ)句不再執(zhí)行褒搔。
函數(shù)定義:一般定義在main函數(shù)前,函數(shù)會(huì)遭遇嵌套定義查描。
返回值類型 函數(shù)名 (參數(shù)列表) {函數(shù)實(shí)現(xiàn)……return 返回值耗溜;}
函數(shù)的調(diào)用:必須要先定義出來(lái)這個(gè)函數(shù)组力,定義之后才能調(diào)用
函數(shù)調(diào)用方式:函數(shù)名+參數(shù)列表
函數(shù)類型:無(wú)返無(wú)參,無(wú)返有參抖拴,有返無(wú)參忿项,有返有參
返回值類型:如果無(wú)返回值,必須要使用void修飾符
2城舞、.h和.m文件
1)如果使用多個(gè)文件來(lái)管理定義函數(shù)時(shí),函數(shù)的聲明要放在.h文件中寞酿,函數(shù)定義在.m文件中家夺。
2)由于函數(shù)的聲明和定義在其他文件中,所以想使用該函數(shù)伐弹,必須先引入聲明部分拉馋,也就是.h文件
#import"文件名.h" 把這個(gè)放在 主函數(shù)和系統(tǒng)頭文件之間
3) 如果函數(shù)定義在主調(diào)函數(shù)(main)函數(shù)之前,函數(shù)的聲明可以省略,因?yàn)樵诰幾g時(shí)煌茴,編譯到主調(diào)函數(shù)時(shí)随闺,已經(jīng)知道該函數(shù)被調(diào)函數(shù)的意義,所以不會(huì)出現(xiàn)異常蔓腐。如果函數(shù)定義在主調(diào)函數(shù)(main)函數(shù)之后矩乐,務(wù)必要在main函數(shù)之前對(duì)函數(shù)進(jìn)行聲明。
4)聲明的意義在于:告訴系統(tǒng)回论,后面將會(huì)出現(xiàn)一個(gè)該類型的函數(shù)散罕。一個(gè)完整的自定義函數(shù),應(yīng)該包括:函數(shù)聲明傀蓉、函數(shù)定義欧漱、函數(shù)調(diào)用,共三部分葬燎。
5)函數(shù)聲明的方法:將函數(shù)的“返回值類型+函數(shù)名+形參列表+误甚;”寫在導(dǎo)入頭文件語(yǔ)句下面,就是一個(gè)函數(shù)聲明谱净。
3窑邦、函數(shù)的嵌套調(diào)用
1)函數(shù)可以嵌套調(diào)用:在一個(gè)函數(shù)中,調(diào)用另一個(gè)函數(shù)完成某項(xiàng)功能岳遥,這就是函數(shù)的嵌套調(diào)用奕翔。函數(shù)可以嵌套調(diào)用,但是函數(shù)不可以嵌套定義浩蓉。
2)函數(shù)不可以嵌套定義:在定義一個(gè)函數(shù)時(shí)派继,又定義另一個(gè)函數(shù),就叫函數(shù)的嵌套定義捻艳,這種行為是不允許的驾窟。
4、函數(shù)的遞歸調(diào)用
函數(shù)遞歸時(shí)一定要有出口认轨,否則會(huì)造成程序遞歸環(huán)路(死遞歸)绅络,那么程序一定會(huì)崩潰。遞歸調(diào)用:自己調(diào)用自己完成某項(xiàng)功能嘁字。
5恩急、變量的作用域
// 局部變量:只在當(dāng)前作用域中起效
// 全局變量:不屬于任何一個(gè)作用域的變量就是全局變量,全局變量可以在當(dāng)前文件中任何一個(gè)地方被訪問(wèn)到(從創(chuàng)建的位置開始纪蜒,一直到文件結(jié)束)
// 如何確定作用域衷恭?使用{}來(lái)確定作用域,一對(duì)大括號(hào)纯续,就確定了一個(gè)作用域随珠。
六灭袁、結(jié)構(gòu)體
1、什么是結(jié)構(gòu)體窗看?
1茸歧、)結(jié)構(gòu)體是一種構(gòu)造類型,由其他基本數(shù)據(jù)類型組合而成一種新類型显沈。與數(shù)組的區(qū)別是:構(gòu)成結(jié)構(gòu)體的基本數(shù)據(jù)類型可以不相同软瞎,數(shù)組必須是相同類型的數(shù)據(jù)構(gòu)成。
2构罗、)結(jié)構(gòu)體必須先聲明铜涉,聲明結(jié)構(gòu)體由哪些數(shù)據(jù)類型構(gòu)成的,相當(dāng)于基本數(shù)據(jù)類型的“int/char/double”之類的類型說(shuō)明遂唧。
3芙代、)聲明完成后,就在文件中創(chuàng)造出了這種新的類型盖彭,就可以使用這種新的類型定義變量來(lái)保存數(shù)據(jù)了纹烹。
2、結(jié)構(gòu)體類型的聲明
struct+結(jié)構(gòu)體名+{成員標(biāo)量}+召边; 結(jié)構(gòu)體聲明在.h文件或主函數(shù)與系統(tǒng)頭文件之間铺呵。
eg:struct student {
char name[20];
int age;
char gender;
};
3、結(jié)構(gòu)體定義
1)struct關(guān)鍵字+結(jié)構(gòu)體名隧熙,共同組成了變量的類型修飾符片挂。
struct+結(jié)構(gòu)體名+結(jié)構(gòu)體變量名 = {值1,值2}贞盯;
eg:struct student stu1 = {"zhangSan", 23, 'm'};
2)結(jié)構(gòu)體成員變量的訪問(wèn)
方式:使用結(jié)構(gòu)體變量名+“.”+”成員變量”的方式訪問(wèn)
eg:訪問(wèn)姓名:stu1.name 訪問(wèn)年齡:stu1.age 訪問(wèn)性別:stu1.gender
3)結(jié)構(gòu)體成員變量的修改
先訪問(wèn)到對(duì)應(yīng)的成員變量音念,然后再修改值
修改成員年齡:stu1.age = 22;
修改成員性別:stu1.gender = ‘f’;(輸出打印時(shí)用%c)
修改成員姓名:stu1.name = "shuKui"; (這是錯(cuò)誤的形式)
因?yàn)樽址贑中使用時(shí),字符數(shù)組類型保存的數(shù)組不能整體賦值躏敢,所以使用普通的修改成員變量方法在這里無(wú)效闷愤,需要使用字符串拷貝函數(shù),達(dá)到修改的目的件余。
strcpy(stu1.name, “shuKui"); (使用strcpy()函數(shù)進(jìn)行字符串的復(fù)制替換)
4讥脐、結(jié)構(gòu)體數(shù)組
保存結(jié)構(gòu)體變量的數(shù)組,就是結(jié)構(gòu)體數(shù)組啼器。結(jié)構(gòu)體數(shù)組和基本數(shù)據(jù)類型的數(shù)組一樣旬渠,只能保存相同的數(shù)據(jù)元素(結(jié)構(gòu)體變量類型必須相同)
1)聲明一個(gè)father類型的結(jié)構(gòu)體數(shù)組
typedef struct father {
char name[20];
int age;
}father;
2)定義一個(gè)father類型的結(jié)構(gòu)體數(shù)組
father father[4] = {
{"zhangsan", 12},
{"laowang", 55},
{"xiaotian", 66},
{"xiaoyan", 22}
};
3)訪問(wèn)成員變量的方式:數(shù)組變量名 + 下標(biāo) + ‘.’ + 成員變量名
訪問(wèn)姓名:father[0].name
訪問(wèn)年齡:father[2].age
七、指針
1端壳、指針:指針就是內(nèi)存單元編號(hào)的另一種稱呼坟漱。每個(gè)內(nèi)存單元都有一個(gè)編號(hào),這個(gè)編號(hào)就是內(nèi)存單元的地址更哄,也被稱作指針芋齿。
指針變量:用來(lái)保存“內(nèi)存單元”地址的變量,就是指針變量成翩。
2觅捆、定義一個(gè)指針變量
1)int p = NULL; int a = 12;
// int * : 類型聲明符,表示變量p是一個(gè)整型指針變量麻敌。
// int:告訴系統(tǒng)取值時(shí)栅炒,應(yīng)該從當(dāng)前位置取多少字節(jié)數(shù)據(jù)。int表示連續(xù)取4個(gè)字節(jié)术羔。它與指針變量所占字節(jié)無(wú)關(guān)赢赊,指針變量所占字節(jié)數(shù)只與操作系統(tǒng)有關(guān),64位環(huán)境下占8字節(jié)级历,32位環(huán)境下占4字節(jié)释移。
// 不能使用指針計(jì)算數(shù)組元素的個(gè)數(shù),因?yàn)橹羔標(biāo)嫉膬?nèi)存的字節(jié)數(shù)至于操作系統(tǒng)的位數(shù)有關(guān)
// p:變量名寥殖,一般我們將指針類型的變量取名叫p玩讳。
// NULL:C語(yǔ)言中,使用NULL代替“空”的意思嚼贡,將NULL賦給指針熏纯,則指針此時(shí)保存的是內(nèi)存起始地址,指針指向內(nèi)存的起始位置粤策。
printf("%p\n", p); // 打印結(jié)果0x0樟澜,表示內(nèi)存的起始位置。
// 使用%p作為占位符叮盘,來(lái)打印指針變量所保存的地址秩贰。
2) &:取地址符號(hào),將后邊變量的地址取出來(lái)熊户,交給指針保存萍膛。
將整型變量a的地址,交給整型指針變量p保存嚷堡。
p = &a; printf("%p\n", p);
3):取值運(yùn)算符蝗罗,將指針?biāo)傅膬?nèi)存地址中保存的數(shù)據(jù)取出來(lái)。
注意:在不同的位置的含義不同蝌戒,出現(xiàn)在指針定義的位置串塑,表示證明后邊的變量名是一個(gè)指針。如果前邊沒(méi)有類型修飾符北苟,則表示指針?biāo)赶虻牡刂返臄?shù)值桩匪。
int b = *p; printf("%d\n", b);
4)用指針修改變量 a 的值
*p = 23; printf("%d\n", a);
5)指針重指向:就是指針把它里面保存的地址進(jìn)行個(gè)更換。
p = &c; 指針發(fā)生了重指向友鼻,有原來(lái)的指向a改變?yōu)橹赶騜傻昙。
3闺骚、指針的算術(shù)運(yùn)算
p++; // 指針變量進(jìn)行加法操作,指針?biāo)4娴牡刂穼?huì)加若干個(gè)單位的字節(jié)妆档,每個(gè)單位占用的字節(jié)數(shù)取決于指針的類型僻爽。指針從低地址向高地址移動(dòng)。
p- -; // 指針變量進(jìn)行減法操作贾惦,指針?biāo)4娴牡刂穼?huì)減若干個(gè)單位的字節(jié)胸梆,每個(gè)單位占用的字節(jié)數(shù)取決于指針的類型。指針從高地址向低地址移動(dòng)须板。
// 普通的加減運(yùn)算:如果沒(méi)有小括號(hào)干預(yù)優(yōu)先級(jí)碰镜,則先取值,再將值進(jìn)行加減操作
// 自增习瑰、自減運(yùn)算:先處理自增绪颖、增減,處理完成后杰刽,再進(jìn)行取值操作菠发。
4、指針與數(shù)組
1)數(shù)組名就是數(shù)組的首元素地址,我們可以定義一個(gè)指針變量,來(lái)存儲(chǔ)數(shù)組的首地址,這樣指針變量指向的就是這個(gè)數(shù)組贺嫂。
// 定義一個(gè)指針滓鸠,將指針指向數(shù)組array的首地址
int *p = array; // 數(shù)組名本身就是地址,所以不需要取地址符&
// 訪問(wèn)數(shù)組元素:數(shù)組名+下標(biāo)\指針+下標(biāo)
printf("array[1] = %d\n", array[1]);
printf("p[1] = %d\n", p[1]);
// 打印指針指向的地址和數(shù)組首元素的地址以及數(shù)組名指向的地址
printf("%p\n", p);
printf("%p\n", &array[0]);
printf("%p\n", array);
2)數(shù)組名和指針的區(qū)別:
2.1)指針指向數(shù)組的首地址后第喳,可以向數(shù)組名一樣訪問(wèn)數(shù)組元素(數(shù)組名/指針)糜俗;
2.2) 指針變量的地址可以被修改,但是數(shù)組名是一個(gè)常量曲饱,它所保存的地址不能被修改(數(shù)組名不能重指向悠抹,但是指針可以重指向)
3)// 使用指針的方式來(lái)訪問(wèn)數(shù)組元素
int temp = *p; int temp1 = *(p + 1); int temp2 = *(array + 1);
// 此時(shí)指針P的指向并沒(méi)有發(fā)生改變,而是產(chǎn)生了一個(gè)"新指針(p + 1)"指向了第二個(gè)元素扩淀。
// 通過(guò)修改指針P的指向楔敌,來(lái)訪問(wèn)數(shù)組元素;
int temp3 = * (++p); printf("temp3 = %d\n", temp3);
int temp4 = * (++array); // 因?yàn)閿?shù)組名是常量驻谆,所以不能通過(guò)修改數(shù)組名的地址修改數(shù)組元素卵凑。(這種表示是錯(cuò)誤的)
5、使用指針遍歷數(shù)組
int array[5] = {23, 12, 34, 23, 45};
int *p = array;
6胜臊、指針與字符串
1)// 定義一個(gè)字符數(shù)組用來(lái)保存字符串"hello"
char string[] = “hello"; // hello 是存儲(chǔ)在常量區(qū)的勺卢,string將hello拷貝一份放到棧區(qū)進(jìn)行使用。
// 定義一個(gè)char類型指針指向string
char *p = string; //這種情況是指針指向有string開辟的棧區(qū)的hello的首地址
// 使用指針下標(biāo)為0的元素改為’a’
- p = ‘a(chǎn)’;
// 使用指針操作字符串:輸出字符串象对,使用%s做占位符黑忱,參數(shù)用指針名,或數(shù)組名均可。
printf("%s\n", p);
// 使用指針便利字符串
for (int i = 0; i < strlen(string); i++) {
printf("%c\n", *(p+i));
}
2)// 指針p此時(shí)指向常量區(qū)甫煞,所以不能修改常量字符串的值菇曲。常量字符串,只能訪問(wèn)不能修改抚吠。
// char *p1 = “hfjhsdjfh"; // 這種情況是指針指向常量區(qū)
// printf("%s\n", p1);
// 總結(jié):指針指向棧區(qū)的字符串羊娃,可以訪問(wèn)進(jìn)行修改,但是當(dāng)指針指向常量區(qū)時(shí)埃跷,只能訪問(wèn)不能修改。
7邮利、指針數(shù)組
1)char *str[3] = {"ios", "ipad", “imac”};這是指針數(shù)組
// str[0],相等于第一個(gè)指針弥雹,指向ios首地址。
// str[1]延届,相當(dāng)于第二個(gè)字符指針剪勿,指向常量區(qū)的ipad字符串的首地址。
// str[2]方庭,相當(dāng)于第三個(gè)字符指針厕吉,指向常量區(qū)的imac字符串的首地址。
char srt[3][5] = {"ios", "ipad", “imac"};這是二位數(shù)組(兩個(gè)表達(dá)意思一致)
// char * 類型的數(shù)組里存的并不是三個(gè)字符串械念,而是三個(gè)字符串的首地址头朱。如果用數(shù)組存儲(chǔ)三個(gè)字符串,需要使用二維數(shù)組龄减。
// 指針數(shù)組中保存的元素都是指針项钮。
// str本質(zhì)是一位數(shù)組,str數(shù)組中存儲(chǔ)的時(shí)char類型的指針希停。
2)訪問(wèn)
printf("%s\n", str[1]); // 這就訪問(wèn)了str[3]中的第二個(gè)元素(字符串)
3)修改:修改指針數(shù)組的元素烁巫。在這里,就是修改指向宠能。
str1[2] = "Happy Birthday";
printf("%s\n", str1[2]);
4)使用指針打友窍丁:1、字符串的地址2违崇、一個(gè)完整的字符串3阿弃、字符串中,下標(biāo)為3的字符
// char *p2 = "i love";
// printf("%p\n", p2);
// printf("%s\n", p2);
// printf("%c\n", *(p2+3));
// 打印ipad中的第二個(gè)字符亦歉。
char *str2[3] = {"ios", "ipad", “imac"}; printf("%c\n", *(str2[1]+1));
8恤浪、指針作為函數(shù)的參數(shù)
// 對(duì)兩個(gè)整型數(shù)值進(jìn)行交換
// 1、函數(shù)exchangeNum定義
void exchangeNum(int *a, int *b){ 傳入的參數(shù)必須是指針(地址)肴楷,這里堅(jiān)決不能傳入數(shù)組名水由,雖然數(shù)組名是地址,但是數(shù)組是常量怒能被改變所以不能傳赛蔫。(用指針傳參本質(zhì)是把要交換的變量的地址傳過(guò)去)
int temp = *a;
*a = *b;
*b = temp;
}
int main(int argc, const char * argv[]) {
int x = 23, y = 88;
int *p1 = &x;
int *p2= &y;
// 調(diào)用exchangeNum函數(shù)
exchangeNum(p1, p2);
printf("x= %d, y = %d\n", x, y);
return 0;
}
9砂客、結(jié)構(gòu)體指針
指向結(jié)構(gòu)體變量的指針就是結(jié)構(gòu)體指針泥张。結(jié)構(gòu)體指針的類型必須和結(jié)構(gòu)體變量的類型一致。
// 聲明一個(gè)Student類型的結(jié)構(gòu)體變量
typedef struct student {
char name[20];
int age;
float score;
char gender;
}Stu;
// 定義一個(gè)Student類型的結(jié)構(gòu)體變量鞠值,并賦值
Stu stu1 = {"xiaoZeMaLiYa", 22, 98.15, ‘f'};
// 使用結(jié)構(gòu)體變量名+.+成員變量名的方式訪問(wèn)
printf("%s\n", stu1.name);
printf("%c\n", stu1.gender);
// 定義一個(gè)指針媚创,來(lái)指向這個(gè)結(jié)構(gòu)體變量
Stu *p = &stu1; // 結(jié)構(gòu)體變量名只是一個(gè)名稱所以需要取地址符
// 使用指針訪問(wèn)結(jié)構(gòu)體變量的成員變量
// 方法一:先取出結(jié)構(gòu)體變量的值,再通過(guò)“.”找到它的成員變量
printf("%s\n", (*p).name); // 由于.運(yùn)算的優(yōu)先級(jí)高于*彤恶,所以需要用小括號(hào)干預(yù)他們的運(yùn)算順序钞钙。
printf("%d\n", (*p).age);
// 方法二:使用指針名+ -> 訪問(wèn)結(jié)構(gòu)體的成員變量。
printf ("%s\n", p->name);
printf("%d\n", p->age);
// 訪問(wèn)name成員變量的首個(gè)字符及第六個(gè)字符
printf("%c\n", *(p->name));
printf("%c\n", *(p->name+5));
10声离、指針與結(jié)構(gòu)體
結(jié)構(gòu)體數(shù)組的數(shù)組名就是一個(gè)結(jié)構(gòu)體指針芒炼,只不過(guò)數(shù)組名是一個(gè)常量,不能修改數(shù)組名保存的地址术徊。
typedef struct teacher{
int num;
char name[20];
char gender;
float score;
}Teacher;
Teacher *stuu = student;
// 使用數(shù)組名+下標(biāo)的方式本刽,訪問(wèn)第一個(gè)元素的name成員變量
printf ("%s\n", student[0].name);
// 使用指針取值的方式來(lái)訪問(wèn)第二個(gè)元素的num成員變量(不常用)
printf("%d\n", (*(stuu+1)).num);
// 使用指針和 -> 的方式訪問(wèn)第三和元素的gender成員變量
printf("%c\n", (stuu+3)->gender);
八、宏
###1赠涮、普通宏
#define kMac 33 // 宏定義:在程序子寓,只要遇到kMac,在編譯之前會(huì)自動(dòng)替換為后面的數(shù)。 宏不是變量
命名規(guī)則: 純大寫或 k + 駝峰法
2笋除、帶參宏
#define SUM(A,B) ((A) * (B)) // 帶參宏只是將參數(shù)原樣替換所以一般情況下斜友,要在表示參數(shù)的字符上,添加小括號(hào)株憾,防止出現(xiàn)運(yùn)算符優(yōu)先級(jí)別的問(wèn)題蝙寨。
// 帶參宏和函數(shù)區(qū)別: 帶參宏會(huì)增加預(yù)編譯的時(shí)間,但是不會(huì)加大CPU的運(yùn)算速度嗤瞎;函數(shù)雖然在預(yù)編譯階段非城酵幔快但是占用的CPU內(nèi)存會(huì)加大,增大硬件損耗贝奇。
3虹菲、條件編譯指令
作用:按條件不同,編譯不同的代碼
1)第一種形式:如果宏定義了標(biāo)示符掉瞳,則編譯第一段代碼毕源,否則編譯第二段代碼
#ifdef 標(biāo)識(shí)符
代碼段1
#else
代碼段2
#endif
2)第二種形式:如果沒(méi)有定義表示符,則編譯代碼段1陕习,否則編譯代碼段2
#ifndef 標(biāo)識(shí)符
代碼段1
#else
代碼段2
#endif
3)第三種形式:如果 常量表達(dá)式結(jié)果非0 編譯器編譯代碼1霎褐,否則編譯代碼段2
#if 常量表達(dá)式
代碼段1
#else
代碼段2
#endif
完