按照之前的計(jì)劃,這篇文章本該寫(xiě)C語(yǔ)言簡(jiǎn)介,包括一些歷史背景,發(fā)展?fàn)顩r, 語(yǔ)言特點(diǎn)什么的,這些東西著實(shí)比較啰嗦。
吃飯用的筷子,到現(xiàn)在我都不知道它的由來(lái),不知道它是在什么歷史背景下誕生的
有些東西還是有必要了解一下,比如,C語(yǔ)言所產(chǎn)生的代碼運(yùn)行速度比匯編語(yǔ)言編寫(xiě)的代碼運(yùn)行速度稍慢一點(diǎn),但還是有得一拼,同時(shí)C語(yǔ)言要比匯編語(yǔ)言編寫(xiě)的代碼可讀性高,可移植性好。另外,相對(duì)于其他高級(jí)語(yǔ)言,比如C++、java、C#等來(lái)說(shuō),C語(yǔ)言編寫(xiě)的代碼運(yùn)行效率要高。
在介紹C語(yǔ)言的數(shù)據(jù)類型和基本語(yǔ)法之前,先說(shuō)說(shuō)C程序結(jié)構(gòu)和C文件結(jié)構(gòu)。
1、C程序結(jié)構(gòu):
①預(yù)處理指令;
②變量、函數(shù)、語(yǔ)句、表達(dá)式、注釋等;
③返回值;
以一段簡(jiǎn)單的打印輸出“hello world”代碼為例:
注意:一個(gè)完整的C語(yǔ)言程序,是由一個(gè)、且只能有一個(gè)main()函數(shù)(又稱主函數(shù))和若干個(gè)其他函數(shù)結(jié)合而成,或僅由一個(gè)main()函數(shù)構(gòu)成;
接下來(lái)看看C語(yǔ)言程序運(yùn)行結(jié)構(gòu):基本的三種程序結(jié)構(gòu)為順序結(jié)構(gòu)、選擇結(jié)構(gòu)和循環(huán)結(jié)構(gòu)。
順序結(jié)構(gòu):程序按順序執(zhí)行,不發(fā)生跳轉(zhuǎn)。
選擇結(jié)構(gòu):依據(jù)是否滿足條件,執(zhí)行相應(yīng)功能。
(1)if(表達(dá)式) 語(yǔ)句;
(2)if(表達(dá)式)語(yǔ)句1;else語(yǔ)句2;
(3)if(表達(dá)式1)語(yǔ)句1;else if(表達(dá)式2)語(yǔ)句2;...else語(yǔ)句n;
注意:第三種方式,即: if......else if..........else if.....else,只能響應(yīng)一個(gè)條件。
循環(huán)結(jié)構(gòu):
while ( ) { } 語(yǔ)句 先判斷表達(dá)式后執(zhí)行.
do{ }-while( ) 語(yǔ)句 先執(zhí)行語(yǔ)句后判斷表達(dá)式.
for( ; ; ){ }
2、C文件結(jié)構(gòu):
一個(gè)基于C的軟件系統(tǒng)一般由以下文件構(gòu)成:
若干個(gè)C文件:每個(gè)C文件中包含若干個(gè)函數(shù)。
若干個(gè)頭文件:每個(gè)頭文件中包含一些數(shù)據(jù)結(jié)構(gòu)的定義以及C函數(shù)、變量的原型聲明。
若干個(gè)庫(kù)文件:庫(kù)文件是編譯后的二進(jìn)制文件,一般由若干C文件編譯后組成,其中包含了若干個(gè)函數(shù)的可執(zhí)行代碼;這些庫(kù)文件中的函數(shù)可執(zhí)行代碼在連接的時(shí)候合并到最終的可執(zhí)行文件中。
若干個(gè)make文件:make文件描述了多個(gè)文件中的依賴關(guān)系以及生成最終可執(zhí)行文件或庫(kù)文件所需要的信息。
由于篇幅較小,再加點(diǎn)內(nèi)容,順便寫(xiě)寫(xiě)C語(yǔ)言的關(guān)鍵字和控制語(yǔ)句。
1、關(guān)鍵字:
這里介紹下C語(yǔ)言的32個(gè)關(guān)鍵字(至于ISO推出的C99標(biāo)準(zhǔn)新增的5個(gè)C語(yǔ)言關(guān)鍵字和C11標(biāo)準(zhǔn)新增了7個(gè)C語(yǔ)言關(guān)鍵字目前沒(méi)有做過(guò)過(guò)多了解,這里就不再介紹)
(1)數(shù)據(jù)類型關(guān)鍵字(12個(gè))
char,short,int,long,float,double,unsigned,signed,void,struct,union,enum;
char:字符型類型數(shù)據(jù)
short:短整型數(shù)據(jù),修飾int,一般省略被修飾的int;// short int a = 10;一般寫(xiě)成 int a = 10;
int:整型數(shù)據(jù),通常為編譯器指定的機(jī)器字長(zhǎng);
long:長(zhǎng)整型數(shù)據(jù),修飾int,一般省略被修飾的int;
float:?jiǎn)尉雀↑c(diǎn)型數(shù)據(jù);
double:雙精度浮點(diǎn)型數(shù)據(jù);
unsigned, signed是修飾符,分別表示無(wú)符號(hào)和有符號(hào),我們時(shí)常寫(xiě)的“ int a=123;”其實(shí)就是“signed int a = 123;”,表示有符號(hào)整型
void: 聲明函數(shù)無(wú)返回值或無(wú)參數(shù),修飾指針時(shí)表示無(wú)類型指針,void不可用來(lái)定義變量,但可以用它來(lái)修飾各種變量;
struct:用來(lái)聲明結(jié)構(gòu)體;
union:用來(lái)聲明共用體或者叫聯(lián)合體;
enum:用于枚舉類型的聲明;
關(guān)于結(jié)構(gòu)體,共用體,枚舉的用法以及結(jié)構(gòu)體和共用體的區(qū)別以后單獨(dú)再寫(xiě);(2)控制語(yǔ)句關(guān)鍵字(12個(gè))
if,else,for,do,while,break,case,continue,default,return,switch,goto(盡量別使用);
(3)存儲(chǔ)類關(guān)鍵字(4個(gè))
auto,extern,register,static
auto:聲明自動(dòng)變量(很少使用);
extern:聲明變量外部可用,可以置于變量或者函數(shù)前,以表示變量或者函數(shù)的定義在別的文件中,可以外部使用;
static:聲明靜態(tài)變量,static修飾的變量存儲(chǔ)在靜態(tài)變量區(qū),修飾全局變量時(shí),表示該變量為全局靜態(tài)變量,作用域?yàn)楫?dāng)前文件;修飾函數(shù)時(shí)表示函數(shù)作用域?yàn)楫?dāng)前文件內(nèi)部; 修飾局部變量時(shí),表示該變量為靜態(tài)局部變量,只被初始化一次,賦值之后值會(huì)保持最新的值,也就是說(shuō)局部靜態(tài)變量的生命周期被擴(kuò)展到整個(gè)程序運(yùn)行的時(shí)間段內(nèi)。這里不知道有沒(méi)有說(shuō)清楚,干脆看個(gè)例子簡(jiǎn)單明了:
register:聲明寄存器變量,修飾符暗示編譯程序相應(yīng)的變量將被頻繁地使用,如果可能的話,應(yīng)將其保存在CPU的寄存器中,以加快其存儲(chǔ)速度。
注:register變量必須是能被CPU所接受的類型,這通常意味著register變量必須是一個(gè)單個(gè)的值,并且長(zhǎng)度應(yīng)該小于或者等于整型的長(zhǎng)度。不過(guò),有些機(jī)器的寄存器也能存放浮點(diǎn)數(shù)。因?yàn)閞egister變量可能不存放在內(nèi)存中,所以不能用“&”來(lái)獲取register修飾變量的地址,如:
(4)其他關(guān)鍵字(4個(gè))
const,sizeof,typedef,volatile
const:const修飾變量,表示被修飾的變量不可被當(dāng)前線程或進(jìn)程改變;例如:const int *p = 100; //const修飾int *,表示*p的值不可變*p = 50; //錯(cuò)誤,*p的值不可變?cè)俦热纾篿nt a = 0;int b = 0;int * const p = &a;//const修飾指針p,表示指針變量地址不可變;p = &b; //錯(cuò)誤,地址不可變,不能指向其他地址;
sizeof:計(jì)算數(shù)據(jù)類型長(zhǎng)度或者變量占內(nèi)存空間大小,sizeof長(zhǎng)得像函數(shù),其實(shí)它是個(gè)關(guān)鍵字;
typedef:為某種數(shù)據(jù)類型定義一個(gè)新的名字;
volatile:確保本條指令不會(huì)因編譯器的優(yōu)化而省略,且要求每次直接讀值,簡(jiǎn)單地說(shuō)就是防止編譯器對(duì)代碼進(jìn)行優(yōu)化。比如如下程序:num=0x65;num =0x66;num =0x67;num =0x68;對(duì)外部硬件而言,上述四條語(yǔ)句分別表示不同的操作,會(huì)產(chǎn)生四種不同的動(dòng)作,但是編譯器就不能像對(duì)待純粹的程序那樣對(duì)上述四條語(yǔ)句進(jìn)行優(yōu)化,只認(rèn)為 num=0x65(即忽略前三條語(yǔ)句,只產(chǎn)生一條機(jī)器代碼)。如果鍵入volatile,則編譯器會(huì)逐一的進(jìn)行編譯并產(chǎn)生相應(yīng)的機(jī)器代碼(四條)
2、語(yǔ)句
C語(yǔ)言利用函數(shù)體中的可執(zhí)行語(yǔ)句,向計(jì)算機(jī)系統(tǒng)發(fā)出操作指令;按照語(yǔ)句功能或構(gòu)成的不同,可將C語(yǔ)言的語(yǔ)句分為5類:
(1)控制語(yǔ)句(9條,可以細(xì)分為三種):
選擇結(jié)構(gòu)控制語(yǔ)句
if()~else~, switch()~
循環(huán)結(jié)構(gòu)控制語(yǔ)句
for()~, while()~, do~while(), break, continue
其他控制語(yǔ)句
return, goto
return功能:終止執(zhí)行函數(shù),賦值(可選); 將控制權(quán)返回給調(diào)用函數(shù)的下一條語(yǔ)句
goto:無(wú)條件轉(zhuǎn)移語(yǔ)句,跳轉(zhuǎn)語(yǔ)句;
如上代碼,在不使用goto的情況下,會(huì)分別打印出line 1、line 2、line3,在打印完line 1后使用goto語(yǔ)句,則直接跳轉(zhuǎn)到goto目標(biāo)代碼,即代碼中的end部分;
(2)函數(shù)調(diào)用語(yǔ)句:
函數(shù)調(diào)用語(yǔ)句由一次函數(shù)調(diào)用加一個(gè)分號(hào)構(gòu)成.
例如:
printf(“hello world!”);
scanf(“%d”,&num);
(3)表達(dá)式語(yǔ)句:
表達(dá)式語(yǔ)句是由表達(dá)式后加一個(gè)分號(hào)構(gòu)成,
例如:
“num = 10”是表達(dá)式,
“num = 10;”是賦值語(yǔ);
(4)空語(yǔ)句:
空語(yǔ)句由一個(gè)分號(hào)構(gòu)成,空語(yǔ)句什么操作也不執(zhí)行.。
(5)復(fù)合語(yǔ)句:
復(fù)合語(yǔ)句由大括號(hào)括起來(lái)的一組語(yǔ)句構(gòu)成。
{
{ } //復(fù)合語(yǔ)句,注意大括號(hào)后不需要分號(hào)
}
復(fù)合語(yǔ)句一般與其它語(yǔ)句配合使用:
如for( ; ; ) { }
這玩意兒想的時(shí)候不多,寫(xiě)起來(lái)卻很多,深究起來(lái)就多的完全說(shuō)不完(┬_┬),C語(yǔ)言基礎(chǔ)部分本應(yīng)該在本篇文章中寫(xiě)完,由于時(shí)間問(wèn)題,下次再寫(xiě)吧。
下篇開(kāi)始說(shuō)說(shuō)數(shù)據(jù)類型,運(yùn)算符與表達(dá)式,想了解的小伙伴們,可以關(guān)注收藏,后續(xù)內(nèi)容請(qǐng)見(jiàn)下回分解。
聯(lián)系客服