C語言知識點整理
一、 C語言簡介
1、 特點
- ·結構化的程式語言(函式、程式的分割)
- ·有豐富的資料型別(44種運算子)
- ·結構緊湊,使用方便(語法限制不大嚴格,自由度高)
- ·具有自我擴充的能力(函式庫的擴充)
- ·有低級語言功能(可直接訪問物理地址)
- ·可移植性強(可在不同系統間運行)
- ·面向程序(C++面向物件)
2、 歷史:CPL>>BCPL>>B>>C>>C#
3、 關鍵字(保留字):型別說明(int等)、陳述句定義(if等)、儲存說明(static等)、sizeof(長度運算子)
4、 識別符號:用戶自定義的各類物件(變數、函式等)的名稱
規則:·由字母、下劃線及數字組成,且必須由前二者開頭
·不能與關鍵字或已定義函式同名
·大小寫敏感(區分大小寫)
·要求顧名知義
·不易混淆
5、 運行與除錯
- ·不帶除錯的運行(空心三角;Ctrl+F5):運行到最后暫停(按任意鍵退出)
- ·帶除錯的運行(實心三角;F5):在斷點和出錯時暫停(shift+F5退出除錯,F5繼續除錯),可在暫停時查看區域變數的值
- ·生成檔案的運行(檔案夾Debug中的EXE檔案,遇錯強退,運行至最后不暫停)
|
型別 |
關鍵字 |
位元組數 |
表示范圍 |
|
整型 |
short |
2 |
-32768~32767 |
|
int |
4 |
(-231 ~ 231-1) |
|
|
long int |
4 |
(-231 ~ 231-1) |
|
|
實型 |
float |
4 |
-3.4x10-38 ~ 3.4x1038 |
|
double |
8 |
-1.7x10-308 ~ 1.7x10308 |
|
|
long double |
8 |
-1.7x10-308 ~ 1.7x10308 |
|
|
字符型別 |
char |
1 |
-128~127 |
6、 注釋(//以后的本行內容或/*與*/之間的內容)
- ·注釋不被程式執行,方便讀程式用;
- ·復雜的程式應當養成寫注釋的習慣;
二、 資料型別
1、 資料型別
- ·分類:基本型別(整型、實型、字符型別)、構造型別(陣列、結構體、共用體、列舉型別)、指標型別與空型別
- ·字符型別(char)只能儲存單字符
- ·基本型別及其儲存位元組數和表示范圍(右圖,VS2010)
拓:機器字長:CPU一次能處理資料的位數,通常與CPU的暫存器位數有關,
存盤字長:存盤器中一個存盤單元(存盤地址)所存盤的二進制代碼的位數,
指令字長:計算機指令字的位數,
資料字長:計算機資料存盤所占用的位數,
存盤字長取決于機器字長
- ·整型和字符型別存在無符號(unsigned)形式,即記錄儲存非負數
- ·除表中列舉外,實型還有一類為指數型
指數形式是浮點數的一種表示方法;
指數形式,即科學計數法,其形式為:aEb;
代表a乘10的b次冪, E也可以是小寫,b必須為整數;
指數形式在輸出的時候,可以指定浮點數輸出為指數形式,格式為%e或%E,
區別為輸出的指數形式浮點數E為小寫或者大寫;
如printf("%e", 100000.0),會輸出1.000000e+05,
- ·陣列即為某一類變數的有序集合,如name[10]就表示10個(0到9)同型變數
- ·特別的,char型的陣列即為字串
- ·結構體為不同型別變數的集合
- ·指標保存的是地址,其型別名表示其保存地址對應的變數的型別
- ·不同資料型別的變數溢位后,都會在其變數取值內回圈,而不是報錯
2、 變數的定義
- ·基本格式:型別名 變數名(=初值)(如int sum=3)
(不能int x1=x2=0; 但可以int x1,x2; x1=x2=0;)
- ·用逗號可以同時定義多個同型變數,但改變變數型別時需用分號
- ·定義變數時可不賦初值,則變數初始值不定(VS2010中為-858993460)
- ·陣列定義:型別名 變數名[長度](={······} 或 “xxxxx”)
- ·陣列長度可使用整形常量或整形常量運算式,但不能使用變數
- ·一維陣列定義時若賦初值則可不規定長度,以輸入數的個數為陣列長度
- ·一維陣列定義時若同時規定長度和賦初值,則順序賦值,不足的賦為0
·參考越界的陣列數(如int x[10] = { 1,2,3,4 }; printf("%d", x[10]);)
編譯時不報錯,運行時出錯,x[10]是一個亂數(即上一次堆疊遺留的數或者未初始化的數)
- ·C語言只能單個參考陣列元素而不能一次參考整個陣列(待定,答案認為正確,實際討論結果認為錯誤)
- ·陣列記憶體大小取決于資料型別和定義的元素個數(不是已賦值的元素個數)
- ·高維陣列的長度規定方式為[lenth1][lenth2]···其初值賦值方式有{A}和{{B},{C}··}兩種,以二維陣列array[2][5]為例,前者按[0][0] , [0][1]···[0][4] , [1][0]···[1][4]的行順序賦值,后者{B}賦給array[0],{C}賦給array[1],
- ·高維陣列的賦值省略規則同一維陣列,但只有[lenth1]可省略
- ·結構體定義:struct+結構名{型別名+成員名(=初值); 型別名+成員名(=初值);}
- ·結構體中的成員可以是任何型別的變數(包括結構體變數)
例:struct student {char name[10]; long number; float score;}
- ·同一函式內同一變數名不能重復定義,但可以與全域變數重名
3、 變數的呼叫與范圍
- ·普通變數直接呼叫(auto int)
- ·陣列:陣列名[lenth1][lenth2]···
- ·結構體:結構名.成員名
- ·指標見后文
- ·變數的呼叫必須在變數的定義陳述句后
按作用域分:
- ·區域變數(函式內定義)只能在本函式初內被呼叫/修改
- ·全域變數(函式外定義)可以在所有函式內被呼叫/修改
生存期是從定義該變數的位置開始至源檔案結束,
- ·全域變數與區域變數重名時區域變數優先
按存盤方式分:
- ·自動變數(auto):
- ·靜態變數(static):在整個程式運行程序中僅賦值一次
ü 靜態區域變數:保存在全域資料區,而不是保存在堆疊中,每次的值保持到下一次呼叫,直到下次賦新值, 靜態區域變數的用途有許多:可以使用它確定某函式是否被呼叫過,?C語言中靜態變數只能被初始化一次,下次即使程式執行到初始化陳述句也會忽略
ü 靜態全域變數:使得該變數成為定義該變數的源檔案所獨享,(非靜態全域變數是如果在一個檔案中使用extern關鍵字來宣告另一個檔案中存在的全域變數,那么這個檔案可以使用這個資料,)
暫存器變數(register):存盤在CPU中,容量小,速度快
4、 常量(#define)
- ·實質是預編譯陳述句而非C陳述句,確定的是替換關系
- ·有全域常量和區域常量之分,與變數規則相同
- ·常量可在其范圍內被呼叫,但不能在此程序中被修改
- ·常量使用的優點:方便修改程式引數
5、 資料的輸入
- ·十進制數整型:正常輸入
- ·八進制數整型:以0開頭,后接八進制數(注意:是零,下同)
- ·十六進制數整型:以0x或0X開頭,后接十六進制數(大小寫不敏感)(最大為f)
- ·長整型:后綴L或l,可以是以上三種進制整型數
- ·無符號整型:后綴U或u,可以是以上三種進制及長整型(LU)
- ·實型(浮點數)小數形式:有小數點才算實型,小數點前后可省略至多一處
- ·實型指數形式:即科學計數法,E代表×10,前置十進制數,后置十進制整數
- ·(單)字符常量:’ ’內接單個普通字符或轉義字符
- ·字串常量:” ”內接單或多個普通字符或轉義字符
- ·合法轉義字符(ASCII碼):
·\b:退格(8)
·\n:換行(10)
·\f:換頁
·\r:回車
·\t:水平制表
·\v:垂直制表
·\’:單引號
·\”:雙引號
·\?:問號
·\ \:反斜線\(92)
·\ddd:1至3位八進制數對應的字符(特別的,\0代表空字符,即終止符)
·\xhh:1至2位十六進制數對應的字符(如:\x41即\101,表示A)
·%的輸出為’%%’
6、 資料型別的轉換
- ·顯式轉換(強制轉換):(型別名)運算式,型別名的括號不可省略
- ·隱式轉換:非顯式轉換,包括運算轉換、賦值轉換(轉換為左值型別)、輸出轉換、函式呼叫轉換(如sqrt、pow函式回傳值是double)
- ·顯式轉換可能導致精度丟失,如由實型到整型時會導致小數點丟失(不四舍五入),值得注意的是:向char型后保留的是0到255內的數(先取整再對256取余)
- ·隱式轉換的規則:(short int、char)int-->unsigned int-->long-->double(float)其中括號內必然向外轉換,其他從左向右轉換
三、 運算子與運算式
|
優先級 |
結合性 |
名稱 |
符號或關鍵字 |
輸入值(左) |
輸入值(右) |
回傳值 |
|
1 |
左 |
圓括號 |
() |
\ |
\ |
\ |
|
下標 |
[] |
\ |
\ |
\ |
||
|
2 |
右 |
邏輯非 |
! |
\ |
常量或運算式 |
!0=1;!(其他)=0 |
|
負號 |
- |
\ |
常量或運算式 |
相反數 |
||
|
自增/減(A) |
++ -- |
變數 |
\ |
|||
|
強制型別轉換 |
(型別名) |
\ |
常量或運算式 |
規定型別對應數 |
||
|
間接參考 |
* |
\ |
地址 |
對應的值 |
||
|
取地址符 |
& |
\ |
變數或陣列名 |
對應的地址 |
||
|
長度運算子 |
Sizeof |
\ |
型別名 |
型別長度 |
||
|
3 |
左 |
算術運算子(B) |
* / %(取余) |
常量或運算式 |
常量或運算式 |
數學運算值 |
|
+ - |
常量 或運算式 |
常量或運算式 |
數學運算值 |
|||
|
4 |
左 |
關系運算子 |
< <= > >= |
常量或運算式 |
常量或運算式 |
真即1,假即0 |
|
5 |
左 |
== != |
常量或運算式 |
常量或運算式 |
真即1,假即0 |
|
|
6 |
左 |
邏輯運算子(C) |
&&(邏輯與) |
常量或運算式 |
常量或運算式 |
一假則假,同真為真 |
|
7 |
左 |
||(邏輯或) |
常量或運算式 |
常量或運算式 |
一真則真,同假為假 |
|
|
8 |
右 |
條件運算子 |
(條件)?(選擇1):(選擇2) |
常量或運算式 |
常量或運算式 |
真取左,假取右 |
|
9 |
右 |
賦值運算子(D) |
= 及其擴展 (復合運算子) |
常量或運算式 |
常量或運算式 |
修改后的左值 |
|
10 |
左 |
逗號運算子 |
, |
常量或運算式 |
常量或運算式 |
最右邊運算式的值 |
1、 常用運算子:
(計算時先進行高優先級計算,同優先級計算順序由結合性決定)
A、變數在左則執行計算后自增/減,反之先自增/減后執行計算
B、取余要求兩邊均為整型,除號兩側均為整數則執行整除
C、自增自減整型實型變數皆可,
C、&&左為假則不執行右側運算式,||左為真亦不執行右側運算式
D、運算子=及其拓展要求左值可修改(不能是運算式、常量、陣列名等),
=的拓展即為+=等,x+=b即為x=x+b
2、 運算式:變數、常量以及運算子的組合,按上述規律運算
拓:逗號運算式:從左往右一次執行陳述句,以逗號作為分界,最后回傳最后一個陳述句的值
3、 運算式陳述句:在運算式后加分號構成陳述句
4、 運算式的真值:0為假,非零為真(!!-1=1)
5、 易錯:表示a不等于0的關系是!a(×),是a(√)
6、 尤其注意‘=’和‘==’!它們的回傳值不同
四、 常用函式及其頭檔案
|
頭檔案 |
名稱 |
函式名 |
形參格式(a, b··) |
回傳值格式 |
功能 |
回傳值 |
|
|
stdio .h |
格式化輸入 |
scanf |
char*等 |
int |
按格式輸入 |
成功賦值的個數 |
|
|
格式化輸出 |
printf |
char*等 |
int |
按格式輸出 |
輸出的字符數 |
||
|
單字符輸入 |
getchar |
\ |
int |
輸入單個字符 |
輸入字符的ASCII |
||
|
單字符輸出 |
putchar |
Char |
int |
輸出單個字符 |
輸出字符的ASCII |
||
|
字串輸入 |
gets |
char* |
char* |
輸入字串 |
輸入的字串 |
||
|
字串輸出 |
puts |
char* |
int |
輸出字串 |
是否成功輸出 |
||
|
math .h |
取絕對值 |
(f)abs |
double/int |
double/int |
求a的絕對值 |
見左 |
|
|
取算數平方根 |
sqrt |
double |
double |
求a的算數平方根 |
見左 |
||
|
取n次方值 |
pow |
double, double |
double |
求a的b次方 |
見左 |
||
|
string .h |
字串連接 |
strcat |
char*, char* |
char* |
連接并保存在前者 |
修改后的前形參 |
|
|
字串復制 |
strcpy |
char*, char* |
char* |
將后者拷貝到前者 |
修改后的前形參 |
||
|
字串比較 |
strcmp |
char*, char* |
int |
比較兩字串 |
異±1同0 |
||
|
字串長度 |
strlen |
char* |
int |
求字串長度 (不包括’\0’,sizeof包括)’\0’】 |
見左 |
||
|
小寫字串 |
strlwr |
char* |
char* |
將字母全小寫 |
修改后的形參 |
||
|
大寫字串 |
strupr |
char* |
char* |
將字母全大寫 |
修改后的形參 |
||
|
stdlib .h |
亂數函式 |
rand |
\ |
int |
隨機生成0到32767的整數 |
見左 |
|
1、 格式字符(%)
- ·%d:十進制帶符號整數輸入/出
- ·%ld:十進制帶符號長整數輸入/出
- ·%u:十進制無符號整數輸入/出
- ·%o:八進制無符號整數輸入/出(注意:是字母o)
- ·%x(X):十六進制無符號整數輸入/出(字母大小寫與x大小寫一致)
- ·%f:以小數形式輸入/出實型數
- ·%e(E):以指數形式輸入/出實型數(指數符號大小寫與e一致)
- ·%g(G):輸入或以上述兩種方式中較短寬度的方式輸出整型數(大小寫與g一致)
- ·%c:單個字符輸入/出
- ·%s:字串輸入/出
2、 修飾符
- ·m:整數m規定了資料的最小輸出長度和最大輸入長度
- ·.n:整數n規定了輸出的小數位數(實型)或截取的字串字符個數(字串)
(先取小數,四舍五入;再看整數,如果整數位數+小數點(也算一位)+小數位數小于總位數,則補空格,若此時加上整數位數超了,則以實際位數為準)
(若n=0,則表示不要小數部分)
- ·0:輸出時空位以0補齊(反之為默認補空格)
- ·-:輸出時左對齊(反之為默認右對齊)
- ·l(L):按長整型輸出或按長整型(雙精度)輸入
- ·h:按短整型輸入
- ·*:跳過該項不進行賦值 (%*d)
3、 格式化輸入輸出
- ·格式化輸入(scanf)基本格式:scanf(“%c, %3s, %f”, &c, s, p);//char c, s[10]; float *p
注:scanf()不能指定浮點數的精度,如 %5.2f錯誤,
n 對scanf() 函式輸入時要看前面占位符之間有無逗號,有則輸入時也要加,無則別加否則結果錯誤,
n scanf()是以洗掉的方式從緩沖區讀取字符(根據字符寬度),遇到非目標型別字符則跳轉至下一占位符,讀取后根據資料位元組舍棄字符,
ü 如scanf_s(“%1c%2c%3c”,&m,&n,&p) 輸入1_22_333,則會依次讀取1、_ 2、2_3,然后受限于字符位元組,m、n、p分別為第一位1、_、2
ü 又如scanf_s(“%2d”,&a);輸入字符2a3,只讀取到2就停止, 然后由于字符寬度,最終輸出_2,
ü 總結:根據輸入資料型別要求(優先考慮)和字符寬度(資料型別相同時考慮)要求讀取,根據位元組長度舍棄,再根據輸出字符寬度要求補全,
n 資料分隔符:空格、Enter、Tab
n 對于高版本的VS,使用scanf_s讀入%c或%s的時候必須多傳入一個引數用來指定讀取的長度,否則會出錯
- ·scanf中%c將無差別讀入任何字符
- ·scanf中%s遇空格、Tab、回車或非法輸入會結束(gets同)
(scanf不會讀取空格、Tab、回車)
- ·scanf中串用型別會導致嚴重錯誤(不要玩弄scanf)
- ·scanf中必須在對應位置原樣輸入普通字符和轉義字符才能正常賦值
- ·scanf中可以規定輸入長度,但無法規定輸入精度(小數點后長度)
- ·格式化輸出(printf)基本格式:printf(“%-07.2f, %s\n”,123.456, s); //char s[10]
l (字串輸入的時候,有首地址就夠了)
l printf占位符賦值是從右到左執行,輸出是從左到右
l Printf回傳的是輸出字符的個數
- ·printf中普通字符原樣輸出,轉義字符對應輸出
- ·printf陳述句中串用輸出形式可能會導致出錯,現列舉如下:
%d, float/ (long) double: 0
%d, char: ASCII碼值
%c, int: 該數對256取余后對應的字符
%c, float/ (long) double:空字符
%f, char/ int: 0.000000
- ·特別的,對于printf(“%d”,1e3);其輸出為0(實型包含指數型)
- ·C語言本身沒有輸入輸出陳述句,依賴庫函式
- ·getchar()是stdio.h中的庫函式,它的作用是從stdin流中讀入一個字符,也就是說,第一次呼叫getchar()時,確實需要人工的輸入,但是如果你輸了多個字符,(并以回車為結束標志,回車也放在了緩沖區),以后的getchar()再執行時就會直接從緩沖區中讀取了,
4、 表中math.h下的函式double型均可替換為float或long double型,且保持一致
五、 選擇結構
1、 特點/功能:根據不同情況做出不同選擇
2、 運算式的真值:回傳值不為0即為真,反之為假
3、 條件運算子(?:):基本形式x=(exp1)? (exp2):(exp3);exp1為真則x=exp2,反之x=exp3
4、 if陳述句:基本形式:if(exp) sentence; exp為真時執行sentence反之不執行
- ·如果要執行多條陳述句,則須使用if(exp){body;}
5、 else陳述句:基本形式:if(exp) sts1; else sts2; exp為真時執行sts1,反之執行sts2
- ·else陳述句會向上與最近的同級別未配對的if陳述句配對
- ·注意if(exp) sts與else間不能加入陳述句
- ·若if與else陳述句數量不對等,則建議使用花括號建立配對關系
- ·注意:不要在if(exp)或else后直接加分號,否則將會被認為管轄空陳述句
6、 if陳述句的嵌套結構
- ·嵌套結構:某種結構內部套用其同型別結構
- ·if陳述句的嵌套結構可表現為if(exp1){if(exp2) sts1;else sts2;} else sts3;
7、 else if陳述句
- ·基本形式:if(exp1) sts1;else if(exp2) sts2;else sts3;
- ·其本質上也是一種嵌套結構
8、 switch陳述句
- ·基本結構:switch(exp){case exp1:sts1;case exp2:sts2;}
- ·switch后接的運算式回傳值必須為整型,case必須后接常量運算式(不能是變數運算式)
- ·當switch后接的運算式回傳值與某一case后接的運算式的值相同,將開始執行該case之后的陳述句,且若無break陳述句,將順序執行完{}內所有陳述句
(無視后面遇到的case值,直至遇到break停止)
(default在結尾則可以不加break,在中間要加)
9、 break陳述句:用于跳出switch陳述句或回圈結構,詳情見后
六、 回圈結構
1、 特點/功能:重復相似陳述句,提高程式效率
2、 while回圈:基本形式:while(exp) sts; exp為真時執行sts并回傳while陳述句繼續判斷
- ·多陳述句應使用{},視情況決定在while(exp)后是否直接加分號
- ·死回圈:反復執行回圈體陳述句而不退出回圈
- ·若使用回圈變數,則應注意在回圈體陳述句中改變回圈變數的值以避免死回圈
3、 do-while回圈:基本形式:do{body;} while(exp);先執行一次然后同上
- ·注意此處的while(exp)后的分號不能省略
While回圈后的while()后沒有分號,do-while回圈后的while后一定有個分號,
4、 for回圈:基本形式:for(exp1;exp2;exp3){body;}從exp1進入;然后緊接著就判斷exp2,若為真執行body,反之離開回圈;執行完body后再經過exp3重新判斷exp2,回圈
- ·順序簡記(12b 32b 32b 32)
- ·注意不要漏掉for()內的分號
- ·exp允許使用逗號運算式,特別的,exp2只根據最后一個運算式的值判斷
- ·多陳述句應使用{},視情況決定for(exp1;exp2;exp3)后是否直接加分號
5、 continue陳述句:用于回圈結構中跳過本次回圈回到判斷陳述句
- ·在while或do-while回圈結構里,continue跳回到while陳述句
- ·在for回圈結構里,continue跳回到for陳述句并從exp3開始執行
6、 break陳述句:離開回圈體結構,若存在嵌套結構,則僅跳出當前所在回圈體
易錯:break陳述句不能用于回圈陳述句和switch陳述句外的任何其它陳述句(√)
7、 goto陳述句:在存在標簽(形式為name:)的情況下,使用goto name可以直接移動到標簽所在位置并順序執行陳述句
- ·goto陳述句在某些場合可能有奇效,但由于其可能出現資料混亂應限制使用
七、 陣列與字串
陣列:一系列相互關聯的變數之間的有序集合與統一定義
·下標(方括號[]):在定義的時候規定數列長度,在呼叫的時候表明序數
·呼叫時下標內可以是常量或變數運算式(方便了與回圈的結合)
·(大部分知識點見上文 資料型別)
字串:字符形式的數列,其賦初值方式可以是”xxx”或{‘x’, ’x’, ’x’, 0},二者等效
·字串必須以終止符(\0)結尾,否則不能成為完整結構的字串
·字串從第一個字符讀到終止符結束,和陣列長度有異(定義長度時應長一點)
·單字符輸入和格式化輸入都不會帶上終止符,而gets會自動添加
·終止符:’\0’或’\000’,即ASCII為0的字符(NULL)
·終止符的輸出結果類似空格,但不是空格(space,32)
八、 自定義函式
1、 函式:函式是程式的組成單位,執行某一功能的模塊,main函式是程式的主函式
2、 函式分類:
- ·函式形式:無參函式(無形參,通常用來執行固定操作)、有參函式(有形參)
- ·用戶使用角度:標準函式(庫函式,如上表列舉)、用戶自定義函式
3、 自定義函式
基本格式:型別名 函式名(形參串列){body;}
- ·若為無參函式,則無需形參串列
- ·作為宣告時,格式為:型別名 函式名(形參串列);//分號不可省略//可以只有形參型別double fun(double,double);
- ·若為void則呼叫函式時不能用一個值去接識訓傳值,這種呼叫是錯誤的
- ·若無型別名則默認為int,return回傳值型別取決于函式型別,而不取決于return的變數的型別
- ·若函式型別需要一個回傳值而沒有return陳述句,則函式自動回傳一個不確定的值,
4、 實參與形參
- ·形參:定義函式時規定的形式引數,是一種特殊的區域變數
- ·實參:主調函式向被調函式傳遞的按形參規定的常量,稱為實際引數
(可以是賦值了的變數,也可以是常量,還可以是有回傳值的函式呼叫運算式,但不能是陳述句(陳述句帶了;沒有回傳值))
- ·形參規定了實參的格式型別
5、 return陳述句
- ·函式在遇到return陳述句后即結束,并將return陳述句后的值作為函式帶回的值
- ·return的值應與函式的型別相一致/匹配
- ·void函式無return陳述句
- ·非void函式有至少一句return函式,但理應有且只會有一句會被執行
6、 主調函式與被調函式的關聯
- ·引數形式(主調函式向被調函式)
- ·回傳值(被調函式向主調函式)
- ·全域變數(雙向)
- ·地址作為形參(雙向):可以是指標和陣列等
7、 函式的遞回呼叫:在函式中呼叫自身,從而實作迭代等功能,是一種高級的回圈
·分類:直接遞回呼叫就是在函式a(或程序)中直接參考(呼叫)函式a本身
間接遞回呼叫就是在函式a(或程序)中呼叫另外一個函式b,而該函式 b又參考(呼叫)了函式
- ·函式遞回呼叫的時候要注意終止條件和回傳值接收
- ·要注意輸出陳述句的執行順序
- ·終止條件可由引數形式或靜態變數來實作
8、 內部函式與外部函式:根據函式能否被其他源檔案呼叫,將函式區分為內部函式和外部函式,
內部函式 static int fun(int a,int b)
外部函式(extern) int fun (int a, int b)
一般默認為外部函式
在需要呼叫此函式的檔案中,用extern宣告所用的函式是外部函式,
九、 指標
1、 指標變數是一類儲存地址而非值的變數,以間接訪問的方式讀取值
2、 指標變數的定義:型別名 *變數名(對于char *a, b; 只有a是指標變數)
3、 只有指標變數能儲存地址,而指標變數也只能儲存地址
4、 指標變數的值變為0(NULL)時表示不指向任何變數
5、 對指標變數的賦值可以使用取地址符&,或是直接使用陣列名或字串名(本質是地址)
6、 對于int i=3, *p=&i; *p等價于i而不是3,故后置陳述句*p=4不會報錯,而會將4賦值給普通整型變數i;
7、 要先對指標變數進行初始化才能解參考(*)
8、 對指標型別變數p,p+n的意義為p后的第n個有效地址,而不是簡單加上n,至于相鄰地址的間隔,與變數的型別等有關;
9、 陣列a[2][2]地址順序為&a[0][0],&a[0][1],&a[1][0],&a[1][1];
10、 注意:使用指標的時候應時刻注意指標指向物件
11、 特殊指標型別:
u 指標陣列:char *arr[4]; arr先跟[]結合成為一個陣列,再跟*結合成指標,即為指標陣列,
u 陣列指標:char (*pa)[4];
拓:既然pa是一個指標,存放一個陣列的地址,那么在我們定義一個陣列時,陣列名稱就是這個陣列的首地址,那么這二者有什么區別和聯系呢?
char a[4];,
a是一個長度為4的字符陣列,a是這個陣列的首元素首地址,既然a是地址,pa是指向陣列的指標,那么能將a賦值給pa嗎?答案是不行的!因為a是陣列首元素首地址,pa存放的卻是陣列首地址,a是char 型別,a+1,a的值會實實在在的加1,而pa是char[4]型別的,pa+1,pa則會加4,雖然陣列的首地址和首元素首地址的值相同,但是兩者操作不同,所以型別不匹配不能直接賦值,但是可以這樣:pa = &a,pa相當與二維陣列的行指標,現在它指向a[4]的地址,
二維陣列的指標:行指標常用陣列指標表示,如char x[3][4];char(*p)[4]=x;(表示指向它行首元素,p+1則移動到下一行,*(p+1)表示整個第二行的元素,但放到運算式中自動轉化為第二行首個元素的地址,如*(p+1)+1表示第二行第二個元素的地址,*(*(p+1)+1)表示第二行第二個元素的值,**p表示陣列首行首元素的值)
l 函式的指標:如int max(int a, int b);
l 對應的函式指標為 int (*pmax)(int, int) = max;
l //也可以寫作int (*pmax)(int a, int b);(=max是對其進行初始化)
12、 指標相減
指標相減=(地址1-地址2)/sizeof(型別) ——定律 ,記牢,
指標相減得出的結果就是兩個元素相差的單元,地址1和地址2以%d求出結果,不要用十六進制,要用十進制,在同一個陣列中,相鄰元素相差1個單元,這一個單元不一定是一個位元組,具體多少位元組,看你當初是怎么分配的,
十、 字串
1、 賦值:1)逐字符賦值
char c[20]={'c', ' ', 'p', 'r', 'o', 'g', 'r', 'a','m'}; // 給部分陣列元素賦值//剩下的自動初始化為’\0’
char d[]={'c', ' ', 'p', 'r', 'o', 'g', 'r', 'a', 'm' }; //對全體元素賦值時可以省去長度//存盤的時候沒有’\0’
char str[4]; str[0] = 'a'; str[1] = 'b'; str[2] = 'c';str[3]=’\0’;//逐元素賦值要手動添加’\0’
2)字串直接賦值(’\0’也被存入陣列中)
char str[30] = {"c.biancheng.net"};
char str[30] = "c.biancheng.net";
char str[] = {"c.biancheng.net"};
char str[] = "c.biancheng.net";
注意:字符陣列只有在定義時才能將整個字串一次性地賦值給它,一旦定義完了,就只能一個字符一個字符地賦值了,如char str[7]; str = "abc123"; //錯誤
str[3] = '1'; str[4] = '2'; str[5] = '3'; //正確
2、 輸入
3、 輸出
易錯總結:
- 注意符號,如分號(;)、逗號(,),等號(=/==)
- 注意關鍵字,如break
- 注意0和‘0’和‘\0’
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/480159.html
標籤:其他
上一篇:使用Qt制作的簡易音樂播放器
