C語言大總結(jié)

C語言大總結(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)類型、字符類型。
整型類型:長整形(long 4/8)、整形(int 4)、短整型(short 2)
浮點(diǎn)類型:單精度(float 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); -=; *=; /=; %=;(語法含義同上)
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中只有小布爾沒有大布爾; 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é)果為真)
?。ㄟ壿嫹牵?:對(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):按照語句順序執(zhí)行

2、分支結(jié)構(gòu):判斷條件在兩個(gè)語句序列中選擇,一旦進(jìn)行判斷必須選擇其中一個(gè)。

if語句:形式一:if (條件表達(dá)式) {語句;}
形式二:if (條件表達(dá)式) {語句1;} else{語句2;}
形式三:if (條件表達(dá)式1) {語句1;} else if條件表達(dá)式2){語句2;} else{語句3;}
switch語句:多分支語句,通過判斷整形表達(dá)式的值,來判斷執(zhí)行那個(gè)語句。常與case配合使用。
break:跳出本層循環(huán),如果外層還有循環(huán)的話,則執(zhí)行外層循環(huán),如果外層沒有循環(huán),則執(zhí)行循環(huán)后面的代碼。(常與if、switch連用)
continue:跳出本次循環(huán),跳出本次循環(huán),遇到continue后,不管continue后面有無代碼,均不執(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)語句:在滿足一個(gè)條件的情況下反復(fù)執(zhí)行一個(gè)語 句序列。

while語句:while(條件表達(dá)式){語句;}條件表達(dá)式為真執(zhí)行循環(huán)體,一旦為假立即停止執(zhí)行。
do…while…語句:do{語句;} while (條件表達(dá)式),先執(zhí)行循環(huán)體,再判斷循環(huán)條件直到不滿足,才結(jié)束循環(huán)。
for語句:for(循環(huán)變量初始化;循環(huán)條件;循環(huán)增量){語句;}循環(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ù)組長度(注:定義數(shù)組時(shí),可以省略元素個(gè)數(shù),因?yàn)榫幾g器會(huì)自動(dòng)推斷出元素個(gè)數(shù),但是“[]”堅(jiān)決不能省略。) { } :給數(shù)組賦值,元素之間用逗號(hào)分隔開(注:1)定義數(shù)組時(shí),可以不給每一個(gè)元素賦值,沒有賦值的元素系統(tǒng)會(huì)默認(rèn)為0。2)定義數(shù)組時(shí),給定了數(shù)組長度,首元素為0,其他元素不賦值,則默認(rèn)為0,這樣五個(gè)元素均為0。3)大括號(hào)中最好賦上初始值,因?yàn)闆]有賦值是系統(tǒng)會(huì)根據(jù)Xcode編譯環(huán)境來賦值,有時(shí)可能有,有時(shí)可能無,這樣就會(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ù)組元素的訪問方式:數(shù)組名+下標(biāo)

1)int array[6] = {12, 21, 32, 23, 25};
訪問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
(注:可以直接訪問,打印出來,也可以把值賦給另一個(gè)相同類型的變量再打印出來)
2)數(shù)組下標(biāo)越界:數(shù)組下標(biāo)超過了數(shù)組長度,訪問了不屬于數(shù)組的內(nèi)存空間。在C中是沒有“數(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ù)組中不能整體訪問數(shù)組元素,也不能整體賦值,而要逐一的遍歷數(shù)組元素,進(jìn)行訪問、賦值、輸出。
//  定義一個(gè)具有20個(gè)元素的數(shù)組,每個(gè)元素的取值范圍是【30,70】,求數(shù)組元素的和
     // 1.定義一個(gè)整型數(shù)組長度為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í)將元素累加起來
    for (int i = 0; i < 20; i++) {
        // 3.2.1 獲取當(dāng)前數(shù)組元素并將獲取到的元素加起來
        sum = sum + array[i];
        
    }
    printf("元素總和為%d\n", sum);
//   定義三個(gè)數(shù)組,將隨機(jī)產(chǎn)生的數(shù)放入其中兩個(gè)數(shù)組中,將這兩個(gè)數(shù)組的值加起來放入第三個(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è)元素加起來,交給第三個(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)是沒有問題的。
                    //滿足交換條件,開始交換位置。
                    //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ù)組長度、賦初值
char char_Array[5] = {'h', 'e', 'l', 'l', ‘o’};
//每個(gè)字符占一個(gè)字節(jié),數(shù)組長度是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è)字符末尾沒有‘\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è)名字,以后就可以通過這個(gè)名字來代替這段代碼,遵守變量名的命名法則。
函數(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í)參沒有關(guān)系。
參數(shù)列表:如果沒有參數(shù),可以用void修飾,也可以什么都不寫,但是小括號(hào)不能省略。
函數(shù)的返回值:有的函數(shù)在完成任務(wù)之后,需要把任務(wù)結(jié)果返回給主調(diào)函數(shù),就可以通過return語句來將值返回。注意: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后?的語句不再執(zhí)行。
函數(shù)定義:一般定義在main函數(shù)前,函數(shù)會(huì)遭遇嵌套定義。
返回值類型 函數(shù)名 (參數(shù)列表) {函數(shù)實(shí)現(xiàn)……return 返回值;}
函數(shù)的調(diào)用:必須要先定義出來這個(gè)函數(shù),定義之后才能調(diào)用
函數(shù)調(diào)用方式:函數(shù)名+參數(shù)列表
函數(shù)類型:無返無參,無返有參,有返無參,有返有參
返回值類型:如果無返回值,必須要使用void修飾符

2、.h和.m文件

1)如果使用多個(gè)文件來管理定義函數(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)入頭文件語句下面,就是一個(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è)地方被訪問到(從創(chuàng)建的位置開始,一直到文件結(jié)束)
//  如何確定作用域?使用{}來確定作用域,一對(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”之類的類型說明。
 3、)聲明完成后,就在文件中創(chuàng)造出了這種新的類型,就可以使用這種新的類型定義變量來保存數(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)體成員變量的訪問
方式:使用結(jié)構(gòu)體變量名+“.”+”成員變量”的方式訪問
eg:訪問姓名:stu1.name 訪問年齡:stu1.age 訪問性別:stu1.gender
3)結(jié)構(gòu)體成員變量的修改
先訪問到對(duì)應(yīng)的成員變量,然后再修改值
修改成員年齡:stu1.age = 22;
修改成員性別:stu1.gender = ‘f’;(輸出打印時(shí)用%c)
修改成員姓名:stu1.name = "shuKui"; (這是錯(cuò)誤的形式)
因?yàn)樽址贑中使用時(shí),字符數(shù)組類型保存的數(shù)組不能整體賦值,所以使用普通的修改成員變量方法在這里無效,需要使用字符串拷貝函數(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)訪問成員變量的方式:數(shù)組變量名 + 下標(biāo) + ‘.’ + 成員變量名
訪問姓名:father[0].name
訪問年齡:father[2].age

七、指針

1、指針:指針就是內(nèi)存單元編號(hào)的另一種稱呼。每個(gè)內(nèi)存單元都有一個(gè)編號(hào),這個(gè)編號(hào)就是內(nè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é)無關(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語言中,使用NULL代替“空”的意思,將NULL賦給指針,則指針此時(shí)保存的是內(nèi)存起始地址,指針指向內(nèi)存的起始位置。
printf("%p\n", p); // 打印結(jié)果0x0,表示內(nèi)存的起始位置。
// 使用%p作為占位符,來打印指針變量所保存的地址。
2) &:取地址符號(hào),將后邊變量的地址取出來,交給指針保存。
將整型變量a的地址,交給整型指針變量p保存。
p = &a; printf("%p\n", p);
3)
:取值運(yùn)算符,將指針?biāo)傅膬?nèi)存地址中保存的數(shù)據(jù)取出來。
注意:在不同的位置的含義不同,出現(xiàn)在指針定義的位置,表示證明后邊的變量名是一個(gè)指針。如果前邊沒有類型修飾符,則表示指針?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ā)生了重指向,有原來的指向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)算:如果沒有小括號(hào)干預(yù)優(yōu)先級(jí),則先取值,再將值進(jìn)行加減操作
// 自增、自減運(yùn)算:先處理自增、增減,處理完成后,再進(jìn)行取值操作。

4、指針與數(shù)組

1)數(shù)組名就是數(shù)組的首元素地址,我們可以定義一個(gè)指針變量,來存儲(chǔ)數(shù)組的首地址,這樣指針變量指向的就是這個(gè)數(shù)組。
// 定義一個(gè)指針,將指針指向數(shù)組array的首地址
int *p = array; // 數(shù)組名本身就是地址,所以不需要取地址符&
// 訪問數(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ù)組名一樣訪問數(shù)組元素(數(shù)組名/指針);
2.2) 指針變量的地址可以被修改,但是數(shù)組名是一個(gè)常量,它所保存的地址不能被修改(數(shù)組名不能重指向,但是指針可以重指向)
3)// 使用指針的方式來訪問數(shù)組元素
int temp = *p; int temp1 = *(p + 1); int temp2 = *(array + 1);
// 此時(shí)指針P的指向并沒有發(fā)生改變,而是產(chǎn)生了一個(gè)"新指針(p + 1)"指向了第二個(gè)元素。
// 通過修改指針P的指向,來訪問數(shù)組元素;
int temp3 = * (++p); printf("temp3 = %d\n", temp3);
int temp4 = * (++array); // 因?yàn)閿?shù)組名是常量,所以不能通過修改數(shù)組名的地址修改數(shù)組元素。(這種表示是錯(cuò)誤的)

5、使用指針遍歷數(shù)組

int array[5] = {23, 12, 34, 23, 45};
int *p = array;

6、指針與字符串

1)// 定義一個(gè)字符數(shù)組用來保存字符串"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ū),所以不能修改常量字符串的值。常量字符串,只能訪問不能修改。
    // char *p1 = “hfjhsdjfh"; // 這種情況是指針指向常量區(qū)
    // printf("%s\n", p1);
    // 總結(jié):指針指向棧區(qū)的字符串,可以訪問進(jìn)行修改,但是當(dāng)指針指向常量區(qū)時(shí),只能訪問不能修改。

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)訪問
printf("%s\n", str[1]); // 這就訪問了str[3]中的第二個(gè)元素(字符串)
3)修改:修改指針數(shù)組的元素。在這里,就是修改指向。
str1[2] = "Happy Birthday";
printf("%s\n", str1[2]);
4)使用指針打?。?、字符串的地址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ì)是把要交換的變量的地址傳過去)
    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)體變量名+.+成員變量名的方式訪問
    printf("%s\n", stu1.name);
    printf("%c\n", stu1.gender);
//  定義一個(gè)指針,來指向這個(gè)結(jié)構(gòu)體變量
    Stu *p = &stu1;    //   結(jié)構(gòu)體變量名只是一個(gè)名稱所以需要取地址符
//  使用指針訪問結(jié)構(gòu)體變量的成員變量
//  方法一:先取出結(jié)構(gòu)體變量的值,再通過“.”找到它的成員變量
    printf("%s\n", (*p).name);  //  由于.運(yùn)算的優(yōu)先級(jí)高于*,所以需要用小括號(hào)干預(yù)他們的運(yùn)算順序。
    printf("%d\n", (*p).age);
//  方法二:使用指針名+ -> 訪問結(jié)構(gòu)體的成員變量。
    printf ("%s\n", p->name);
    printf("%d\n", p->age);
//  訪問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)體指針,只不過數(shù)組名是一個(gè)常量,不能修改數(shù)組名保存的地址。

typedef struct teacher{
    int num;
    char name[20];
    char gender;
    float score;
}Teacher;
    Teacher *stuu = student;
   //   使用數(shù)組名+下標(biāo)的方式,訪問第一個(gè)元素的name成員變量
   printf ("%s\n", student[0].name);
   //    使用指針取值的方式來訪問第二個(gè)元素的num成員變量(不常用)
   printf("%d\n", (*(stuu+1)).num);
   //   使用指針和 -> 的方式訪問第三和元素的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í)別的問題。   
//  帶參宏和函數(shù)區(qū)別:  帶參宏會(huì)增加預(yù)編譯的時(shí)間,但是不會(huì)加大CPU的運(yùn)算速度;函數(shù)雖然在預(yù)編譯階段非??斓钦加玫腃PU內(nèi)存會(huì)加大,增大硬件損耗。
3、條件編譯指令
作用:按條件不同,編譯不同的代碼
  1)第一種形式:如果宏定義了標(biāo)示符,則編譯第一段代碼,否則編譯第二段代碼
#ifdef 標(biāo)識(shí)符
   代碼段1
#else
   代碼段2
#endif
 2)第二種形式:如果沒有定義表示符,則編譯代碼段1,否則編譯代碼段2
#ifndef 標(biāo)識(shí)符
   代碼段1
#else
   代碼段2
#endif
3)第三種形式:如果 常量表達(dá)式結(jié)果非0  編譯器編譯代碼1,否則編譯代碼段2
#if 常量表達(dá)式
   代碼段1 
#else
   代碼段2
#endif

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容