C語言入門到精通 2020-09-17
一、基礎:
1、進制、位權、1位元組等于8位(位是計算機的最小儲存機關,位元組是計算機最小存儲單元)、十進制轉換其他進制:連除倒取餘,其他進制轉換十進制:按權求和
2、單行注釋:// 多行注釋:/**/ (内容寫在量型号之間)
3、資料類型:整形類型、浮點類型、字元類型。
整型類型:長整形(long 4/8)、整形(int 4)、短整型(short 2)
浮點類型:單精度(float 4)、雙精度(double 8)
字元類型:字元類型(char 1)
4、常量:程式運作期間不能被改變的量。
常量 類型:整型常量、浮點型常量、字元型常量
變量:實際上是儲存區域,也可以做表達式,是程式運 行期間可以被改變的量。
變量定義:由類型符号、變量名、初始值三部分組成(如:int a = 5;)
變量命名規則:由數字、字母、下劃線組成的,但不能 以數字開頭,不能與關鍵字重複,不能重複使用變量名(同一作用域),見名知意。
5、指派運算符:= 把右邊的值賦給左邊 優先級别最低
算數運算符:+, -, *, / 整型兩邊相除取整,除數不能為0,% 兩邊均為正數 ,++ 自增運算符、- - 自減運算符:(它倆在前,先執行,它倆在後,後執行。
6、複合運算符:+= (a += b; 相當于a = a + b); -=; *=; /=; %=;(文法含義同上)
7、表達式:由常量、變量與運算符組合而成(注:表達式會有傳回值)
8、輸出函數:printf();輸入函數 scanf()(注:以回車确定輸入結束,隻有大Enter鍵才會結束;不要再格式串後面加’\n’字元,否則會抵消人工輸入的回車)。
轉化符:%c->char; %d->int; %sd->short; %ld->long;%f->float、double。
9、轉換格式控制:最少占4位:
printf(“%04d”,12); //不足補0
printf(“%4.2f”,1.2345); //保留小數點後兩位
printf(“%-4d”,12); //左對齊
\n回車符;\列印\;%%列印%;
二、運算符
1、BOOL類型:隻有YES(1)和NO(0)兩個值;
bool類型:由ture(非0數字)和flase(0)兩種值;
BOOL和bool差別:1)、在C中隻有小布爾沒有大布爾;2)、在C和OC中小布爾中非零為真,零為假;3)、在OC中大布爾中1為真,0為假,其它數字原樣輸出,不做判斷條件
2、關系運算符:用于比較運算,結果值有真假兩種,結果值由BOOL類型儲存
< >= <= == != 3、邏輯運算符:由邏輯運算符組成,結果也是非真即假 &&(邏輯與):一假即假(有一邊為假則結果為假) ||(邏輯或) :一真即真(有一邊為真則結果為真) !(邏輯非) :對表達式結果取反 4、條件運算符:條件表達式?表達式1:表達式2 如果條件為真,則執行表達式1。如果條件為假,則執行表達式2。 5、枚舉類型:屬于構造類型,是一組由符号的整型常量,一一羅列所有狀态,羅列所有結果。enum枚舉名{枚舉值表} 目的和作用:提高程式可讀性;将人能看懂的标示符與計算機能識别的數字建立對應關系
三、程式的三種結構:
1、順序結構:按照語句順序執行
2、分支結構:判斷條件在兩個語句序列中選擇,一旦進行判斷必須選擇其中一個。
if語句:形式一:if (條件表達式) {語句;}
形式二:if (條件表達式) {語句1;} else{語句2;}
形式三:if (條件表達式1) {語句1;} else if條件表達式2){語句2;} else{語句3;}
switch語句:多分支語句,通過判斷整形表達式的值,來判斷執行那個語句。常與case配合使用。
break:跳出本層循環,如果外層還有循環的話,則執行外層循環,如果外層沒有循環,則執行循環後面的代碼。(常與if、switch連用)
continue:跳出本次循環,跳出本次循環,遇到continue後,不管continue後面有無代碼,均不執行,提前結束目前循環,開啟下一次循環。(常與if連用)
arc4random():傳回随機數的函數。如果要一個随機數在【a, b】範圍内的整數。公式為:arc4random() % (b - a +1) + a;
3、循環語句:在滿足一個條件的情況下反複執行一個語 句序列。
while語句:while(條件表達式){語句;}條件表達式為真執行循環體,一旦為假立即停止執行。
do…while…語句:do{語句;} while (條件表達式),先執行循環體,再判斷循環條件直到不滿足,才結束循環。
for語句:for(循環變量初始化;循環條件;循環增量){語句;}循環條件為真才執行循環體。
四、一維數組
一維數組:屬于構造結構,是由相同類型的成員組成的一組資料。
數組名:存儲不同資料類型的數組有各種對應的名稱(名稱可以随意起),但 要見名知意。
元素:數組由多個成員組合而成,每個成員被稱為“數組的元素”
1、定義一個數組
int array[3] = {1, 2, 3};
int:聲明數組類型 array:數組名 [5]:數組長度(注:定義數組時,可以省略元素個數,因為編譯器會自動推斷出元素個數,但是“[]”堅決不能省略。) { } :給數組指派,元素之間用逗号分隔開(注:1)定義數組時,可以不給每一個元素指派,沒有指派的元素系統會預設為0。2)定義數組時,給定了數組長度,首元素為0,其他元素不指派,則預設為0,這樣五個元素均為0。3)大括号中最好賦上初始值,因為沒有指派是系統會根據Xcode編譯環境來指派,有時可能有,有時可能無,這樣就會出現定義不明,是以建議賦上值。)
2、數組的記憶體占用
1)使用sizeof()函數求數組占位元組數
printf("array[3]數組所占位元組數%ld", sizeof(array));
結果:12 因為每個int類型占4個位元組,有3個元素,是以共12個位元組 。
2)利用sizeof()函數求數組元素個數
先求出數組所占位元組數,再求出其中某個元素所占位元組數,再相除就得出數組元素個數。
int array[5] = {4, 6, 7, 2, 8};
int a = (sizeof(array) / sizeof(array[1]));
printf("a = %d\n", a); 結果為:a = 5
3、數組元素的通路方式:數組名+下标
1)int array[6] = {12, 21, 32, 23, 25};
通路array中的32這個元素:數組名:array,下标:從零開始計數,32在第3個位置上,是以32的下标是2。
int temp = array[2];
printf("temp = %d, array[2] = %d\n", temp, array[2]); 結果:32,32
(注:可以直接通路,列印出來,也可以把值賦給另一個相同類型的變量再列印出來)
2)數組下标越界:數組下标超過了數組長度,通路了不屬于數組的記憶體空間。在C中是沒有“數組下标越界保護”機制,是以在寫代碼時,要避免下标越界。
3)修改數組元素
3.1)修改array中的第二個元素為62
int array[6] = {12, 21, 32, 23, 25};
array[1] = 62;
printf("array[1] = %d\n", array[1]); 結果:array[1] = 62
3.2) 定義一個新的數組,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]; // 數組的下标可以是常量,也可以是變量
printf("array1[%d] = %d\n", i, array1[i]); // 數組的輸出需要for循環進行周遊
}
// array1 = array; 數組中不能整體通路數組元素,也不能整體指派,而要逐一的周遊數組元素,進行通路、指派、輸出。
// 定義一個具有20個元素的數組,每個元素的取值範圍是【30,70】,求數組元素的和
// 1.定義一個整型數組長度為20
int array[20] = {0};
// 2.開啟一個for循環,使用循環給數組元素指派
for (int i = 0; i < 20; i++) {
// 2.1 生成【30,70】之間的數
int temp = arc4random() % (70 - 30 + 1) + 30;
//2.2 将生成的随機數指派給對應的元素
array[i] = temp;
printf("array[%d] = %d\n", i, array[i]);
// 3.求數組元素的和
// 3.1定義一個儲存和的變量
int sum = 0;
//3.2 使用for循環周遊數組元素,同時将元素累加起來
// 3.2.1 擷取目前數組元素并将擷取到的元素加起來
sum = sum + array[i];
// 定義三個數組,将随機産生的數放入其中兩個數組中,将這兩個數組的值加起來放入第三個數組中
// 1、 定義三個數組,并初始化。
int array1[10] = {0};
int array2[10] = {0};
int array3[10] = {0};
// 2、 使用一個for循環,給第一個數組和第二個數組指派,将兩個數組個元素加起來,交給第三個元素。
for (int i = 0; i < 10; i++) {
// 2.1、 分别把生成的随機數賦給兩個數組
array1[i] = arc4random() % (40 - 20 + 1) + 20;
array2[i] = arc4random() % (40 - 20 + 1) + 20;
// 2.2、兩數組進行相加
array3[i] = array1[i] + array2[i];
// 3、 列印驗證結果是否正确
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};
//趟數 = 元素個數 - 1;每趟比較的次數 = 元素個數 - 目前的趟數
//兩層for循環,外層叢植比較趟數、内層控制比較次數
//趟數
for (int j = 0; j < 5 - 1; j++) {
//次數
for (int k = 0; k < 5 - (j+ 1); k++) {
if (array[k] > array[k + 1]){ //因為每趟比較都要從下标為0開始,j在每次從外層循環進入内層時,都要被初始化為0。因為每次比較,下标都要加一,j在每次内層循環時,也會加一,是以,在這裡是用j做下标是沒有問題的。
//滿足交換條件,開始交換位置。
//1.定義一個臨時變量
int temp = array[k]; 6
array[k] = array[k + 1];
array[k + 1] = temp;
printf("%d ", array[i]);
5、字元數組
字元數組:儲存字元的數組就是字元數組。有’\0’結束辨別的字元數組也稱為字元串。
定義一個字元數組:聲明類型、數組名、數組長度、賦初值
char char_Array[5] = {'h', 'e', 'l', 'l', ‘o’};
//每個字元占一個位元組,數組長度是5,是以數組占5*1個位元組的記憶體。
char char_Array[5] = {'h', 'e', 'l', 'l', 'o', '\0'};和char char_Array[5] =“hello”;
是同一個意思都便是定義字元串hello。
字元串和字元數組的差別:
如果字元數組最後一個字元末尾沒有‘\0’,則是一個字元數組
如果字元數組最後一個字元末尾有‘\0’,則是這個字元數組就是字元串。
字元串操作函數
strlen():傳回字元串的有效字元個數
strcpy():字元串拷貝函數:把第二個參數的值拷貝給第一個參數
strcat() 字元串拼接:把第二個參數的值,拼接到第一個參數的後面
strcmp() 字元串比較:第一個參數大于第二個參數傳回一個正整數,第一個參數小于第二個參數,傳回一個負整數,兩個參數相等,傳回零。
五、函數
1、函數:完成某一功能的代碼段。
函數名:給這段代碼取一個名字,以後就可以通過這個名字來代替這段代碼,遵守變量名的命名法則。
函數參數:有的函數在完成某一任務時需要的材料,我們把在完成任務所需的材料叫函數的參數。在被調函數中,參數叫“形參”,在主調函數中,參數叫“實參”。
函數參數傳遞:将實參的值拷貝一份到形參變量的空間中,在被調用函數中操作的參數是新開辟的記憶體的數值,和實參沒有關系。
參數清單:如果沒有參數,可以用void修飾,也可以什麼都不寫,但是小括号不能省略。
函數的傳回值:有的函數在完成任務之後,需要把任務結果傳回給主調函數,就可以通過return語句來将值傳回。注意:return隻能傳回一個值,同時不能傳回數組。
return:return标志着函數的結束,如果return後邊有數值,則将這個數值交給主調函數。當return隻負責結束函數執行時,可以省略return。return後⾯的語句不再執行。
函數定義:一般定義在main函數前,函數會遭遇嵌套定義。
傳回值類型 函數名 (參數清單) {函數實作……return 傳回值;}
函數的調用:必須要先定義出來這個函數,定義之後才能調用
函數調用方式:函數名+參數清單
函數類型:無返無參,無返有參,有返無參,有返有參
傳回值類型:如果無傳回值,必須要使用void修飾符
2、.h和.m檔案
1)如果使用多個檔案來管理定義函數時,函數的聲明要放在.h檔案中,函數定義在.m檔案中。
2)由于函數的聲明和定義在其他檔案中,是以想使用該函數,必須先引入聲明部分,也就是.h檔案
import"檔案名.h" 把這個放在 主函數和系統頭檔案之間
3) 如果函數定義在主調函數(main)函數之前,函數的聲明可以省略,因為在編譯時,編譯到主調函數時,已經知道該函數被調函數的意義,是以不會出現異常。如果函數定義在主調函數(main)函數之後,務必要在main函數之前對函數進行聲明。
4)聲明的意義在于:告訴系統,後面将會出現一個該類型的函數。一個完整的自定義函數,應該包括:函數聲明、函數定義、函數調用,共三部分。
5)函數聲明的方法:将函數的“傳回值類型+函數名+形參清單+;”寫在導入頭檔案語句下面,就是一個函數聲明。
3、函數的嵌套調用
1)函數可以嵌套調用:在一個函數中,調用另一個函數完成某項功能,這就是函數的嵌套調用。函數可以嵌套調用,但是函數不可以嵌套定義。
2)函數不可以嵌套定義:在定義一個函數時,又定義另一個函數,就叫函數的嵌套定義,這種行為是不允許的。
4、函數的遞歸調用
函數遞歸時一定要有出口,否則會造成程式遞歸環路(死遞歸),那麼程式一定會崩潰。遞歸調用:自己調用自己完成某項功能。
5、變量的作用域
// 局部變量:隻在目前作用域中起效
// 全局變量:不屬于任何一個作用域的變量就是全局變量,全局變量可以在目前檔案中任何一個地方被通路到(從建立的位置開始,一直到檔案結束)
// 如何确定作用域?使用{}來确定作用域,一對大括号,就确定了一個作用域。