C語言基本語法
#include <reg52.h> //包含文件
#include <stdio.h>
void main(void) //主函數
{
SCON=0x52;
TMOD=0x20;
TH1=0xf3;
TR1=1; //此行及以上 3 行為PRINTF 函數所必須
printf(“Hello I am KEIL. \n”); //打印程序執行的信息
printf(“I will be your friend.\n”);
while(1);
}
3.1 C 語言的標識符和關鍵字
用來標識變量名、符號常量名、函數名、數組名、類型名等的有效字符序列稱為標識符。簡單地說,標識符就是一個名字。 C 語言規定標識符只能由字母、數字和下划線三種
字符組成,且第一個字符必須為字母或下划線,要注意的是C 語言中大寫字母與小寫字母被認為是兩個不同的字符
例:
Char char
PI pi
abc123 _abc123 123abc abc_123
3.2 數據類型
數據——具有一定格式的數字或數值叫數據
數據類型——數據的不同格式叫做數據類型。
數據結構——數據按一定的數據類型進行的排列、組合及架構稱為數據結構。
C51提供的數據結構是以數據類型的形式出現的,C51的數據類型如下所示:
位型(bit)
字浮型(char)
整型(int)
基本類型: 長整型(long)
浮點型(float)
雙精度浮點型(double)
數據類型: 數組類型(array)
構造類型: 結構體類型(struct)
共用體(union)
枚舉(enum)
指針類型:
空類型:
收據類型 |
長度/bit |
長度/Byte |
值域 |
bit unsigned char signed char unsigned int signed int unsigned long signed long float uouble 一般指針 |
1 8 8 16 16 32 32 32 64 24 |
… 1 1 2 2 4 4 4 8 3 |
0,1 0~255 -128~127 0~65535 -32768~32767 0~4294967295 -2147483648~2147483647 1.76E-38~3.40E+38(6位數字) 1.76E-38~3.40E+38(10位數字) 存儲空間 0~65535 |
3.2.1 常量
常量——在程序運行的過程中,其值不能改變的量稱為常量。
常量的數據類型只有整型、浮點型、字符型、字符串型和位標量。
#define CONST 60
#define PI 3.1415926
好處:
1、見名知意
2、改一全變
轉義字符 |
含義 |
碼(16進制數形式) |
\o |
空字符(NULL) |
0x00 |
\n |
換行符(LF) |
0x0A |
\r |
回車符(CR) |
0x0D |
\t |
水平制表符(HT) |
0x09 |
\b |
退格符(BS) |
0x08 |
\f |
換頁符(FF) |
0x0C |
\’ |
單引符 |
0x27 |
\” |
雙引符 |
0x22 |
\\ |
反斜杠 |
0x5C |
字符型常量
\o \n \r \t \b \\
字符串常量
“test” “\\abc\\”
3.2.2 變量
變量——在程序運行中,其值可以改變的量稱為變量。
一個變量主要由兩部分構成:一個是變量名,一個是變量值。每個變量都有一個變量名,在內存中占據一定的存儲單元(地址),並在該單元中存放該變量的值。
1.位變量(bit)——變量的類型是位,位變量的值可以是1(true)或0(false)。
bit flag;
2.字符變量(char)——字符變量的長度為1字節(Byte)即8位
3.整型變量(int)——整型變量的長度為16位,長度為兩個字節,用於存放一個雙字節數據。
4. long 長整型變量
long 長整型長度為四個字節,用於存放一個四字節數據。
5.浮點型變量(float)——浮點型變量為32位,占4字節。
6.* 指針型變量
指針型本身就是一個變量,在這個變量中存放的指向另一個數據的地址。
7. sfr 特殊功能寄存器
sfr 也是一種擴充數據類型,點用一個內存單元,值域為0~255。
8.sfr16 16 位特殊功能寄存器sfr16 占用兩個內存單元,值域為0~65535。
9. sbit 可尋址位sbit 同位是C51 中的一種擴充數據類型,利用它可以訪問芯片內部的RAM中的可尋址位或特殊功能寄存器中的可尋址位。
Sbit flag=0x20^1;
Sbit flag=wo^1;
Sbit flag=0x00h;
3.2.3 變量的存儲種類
按變量的有效作用范圍可以將其划分為局部變量和全局變量;還可以按變量的的存儲方式為其划分存儲種類。在C語言中變量有四種存儲種類,即自動(auto)、外部(extern)、靜態(static)和寄存器(register)。這四種存儲種類與全局變量和局部變量之間的關系如圖3.2所示
自動變量(auto)
內部變量(inner) 靜態變量(static)
寄存器變量(register)
變量
全局變量(global)
外部變量(extern)
靜態變量(static)
1、自動變量(auto)
定義一個變量時,在變量名前面加上存儲種類說明符“auto”,即將該變量定義為自動變量。自動變量是C語言中使用最為廣泛的一類變量。
auto int high;
int high;
自動變量的作用范圍在定義它的函數體或復合語句內部,只有在定義它的函數內被調用,或是定義它的復合語句被執行時,編譯器才為其分配內存空間,開始其生存期。當函數調用結束返回,或復合語句執行結束時,自動變量所占用的內存空間就被釋放,變量的值當然也就不復存在,其生存期結束。
當函數被再次調用或復合語句被再次執行,編譯器又會為它們內部的自動變量重新分配內存空間,但它不會保留上次運行時的值,而必須被重新賦值。因此自動變量始終是相對於函數或復合語句的局部變量。
2、外部變量(extern)
使用存儲種類說明符“extern”定義的變量稱為外部變量。
按照缺省規則,凡是在所有函數之前,在函數外部定義的變量都是外部變量,定義時可以不寫extern說明符。
在一個函數體內說明一個已在該函數體外或別的程序模塊文件中定義過的外部變量時,則必須要使用extern說明符。
個外部變量被定義之后,它就被分配了固定的內存空間。外部變量的生存期為程序的整個執行時間,即在程序的執行期間外部變量可被隨意使用,當一條復合語句執行
完畢或是從某一個函數返回時,外部變量的存儲空間並不被釋放,其值也仍然保留。因此外部變量屬於全局變量。
3、靜態變量(static)
使用存儲種類說明符“static”定義的變量稱為靜態變量。在例4-2的模塊2程序文件中使用了一個靜態變量:static int a=5;由於這個變量是在函數funl()內部定義的,因此稱為內部靜態變量或局部靜態變量。局部靜態變量不象自動變量那樣只有當函數調用它時才存在,退出函數后它就消失,局部靜態變量始終都是存在的,但只能在定義它的函數內部進行訪問,退出函數之后,變量的值仍然保持,但不能進行訪問。還有一種全局靜態變量,它是在函數外部被定義的,作用范圍從它的定義點開始,一直到程序結束。
4、寄存器變量(register)
為了提高程序的執行效率,C語言允許將一些使用頻率最高的那些變量,定義為能夠直接使用硬件寄存器的所謂寄存器變量。定義一個變量時在變量名前而冠以存儲種類符號“register”即將該變量定義成為了寄存器變量。
寄存器變量可以被認為是自動變量的一種,它的有效作用范圍也與自動變量相同。由於計算機中的寄存器是有限的,不能將所有變量都定義成寄存器變量。通常在程序中定義的寄存器變量時只是給編譯器一個建議,該變量是否能真正成為寄存器變量,要由編譯器根據實際情況來確定。另一方面,c51編譯器能夠識別程序中使用頻率最高的變量,在可能的情況下,即使程序中並未將該變量定義為寄存器變量,編譯器也會自動將其作為寄存器變量處理。
3.2.4 變量及其存儲模式
一個變量應該有一個名字,在內存中占據一定的存儲單元,在該存儲單元中存放變量的值。
在C 語言中,要求對所有用到的變量作強制定義,也就是“先定義,后使用”。在C51中對變量進行定義的格式如下:
[存儲種類] 數據類型 [存儲器類型] 變量名表
存儲模式如下:
存儲模式決定了默認的存儲器類型,此存儲器類型將應用於函數參數,局部變量和定義時未
包含存儲器類型的變量。你可以在命令行用SMALL,COMPACT和LARGE參數定義存儲
模式。定義變量時,使用存儲器類型顯式定義將屏蔽默認存儲器類型。
1.小(SMALL)模式
所有變量都默認在8051的內部數據存儲器中。這和用data顯式定義變量起到相同的作用
2.緊湊(COMPACT)模式
此模式中,所有變量都默認在8051的外部數據存儲器的一頁中。
3.大(LARGE)模式
在大模式下,所有的變量都默認在外部存儲器中(xdata)。
需要特別指出的是,變量的存儲種類與存儲器類型是完全無關的。 為了能夠直接訪問這些特殊功能寄存器 ,C51編譯器擴充了關鍵字sfr和sfrl6,利用這種擴充關鍵字可以在C語言源程序中直接對805l單片機的特殊功能寄存器進行定義。定義方法如下:
sfr特殊功能寄存器名=地址常數;
例如:sfr P0=0x80;/* 定義I/O口P0,其地址為80H */
3.3 用typedef重新定義數據類型
在C語言程序中除了可以采用上面所介紹的數據類型之外,用戶還可以根據自己的需要
對數據類型重新定義。重新定義時需用到關鍵字typedef,定義方法如下:
typedef 已有數據類型 新的數據類型名;
其中“已有的數據類型”是指上面所介紹的C語言中所有的數據類型,包括結構、指針
和數組等,“新的數據類型名”可按用戶自己的習慣或根據任務需要決定。關鍵字typedef
的作用只是將C語言中已有的數據類型作了置換,因此可用置換后的新數據類型名來進
行變量的定義。
如:
typedef unsigned char uchar;
typedef char * POINTER;
POINTER point;
熟悉數據類型的存儲結構
3.4 運算符與表達式
運算符就是完成某種特定運算的符號。運算符按其在表達式中所起的作用,可分為賦值運算符、算術運算符、增量與減量運算符、關系運算符、邏輯運算符、位運算符、復合賦值運算符、逗號運算符、條件運算符、指針和地址運算符、強制類型轉換運算符和sizeof運算符等。運算符按其在表達式中與運算對象的關系可分為單目運算符,雙目運算符和三目運算符。單目就是指需要有一個運算對象,雙目就要求有兩個運算對象,三目則要三個運算對象。表達式則是由運算及運算對象所組成的具有特定含義的式子。C是一種表達式語言,表達式后面加“;”號就構成了一個表達式語句
1、賦值運算符:變量 = 表達式;
2. 算術運算符
+ 加或取正值運算符
- 減或取負值運算符
* 乘運算符
/ 除運算符
% 取余運算符
3. 增量和減量運算符
十十 增量運算符 (++i,i++)
—一 減量運算符 (一一j,j一一 )
4. 關系運算符
“<”(小於)、“<=”(小於等於)、“>”(大於)、“>=(大於等於)”
、“==”(等於)和“!=”(不等於)。
5. 邏輯運算符
“&&”(邏輯與)、“||”(邏輯或)和“!”(邏輯非)。
6. 位運算符
~ 按位取反、& 按位與、| 按位或、^ 按位異或、<< 左移、>> 右移
7. 復合賦值運算符
+= 加法賦值 >>= 右移位賦值
-= 減法賦值 &= 邏輯與賦值
*= 乘法賦值 |= 邏輯或賦值
/= 除法賦值 ^= 邏輯異或賦值
%= 取模賦值 -= 邏輯非賦值
<<= 左移位賦值
8. 逗號運算符
在C語言中逗號是一種特殊的運算符,也就是逗號運算符,可以用它將兩個或多個表達式連
接起來,形成逗號表達式。逗號表達式的一般形式為:表達式1,表達式2,表達式3……表達式n用逗號運算符組成的表達式在程序運行時,是從左到右計算出各個表達式的值,而整個用逗號運算符組成的表達式的值等於最右邊表達式的值,就是"表達式n"的值。
9. 條件運算符
條件運算符“?:”是C 語言中唯一的一個三目運算符.
條件表達式的一般形式如下:
邏輯表達式 ? 表達式1:表達式2
條件運算符的作用簡單來說就是根據邏輯表達式的值選擇使用表達式的值。當邏輯表達式的值為真時(非0值)時,整個表達式的值為表達式1的值;當邏輯表達式的值為假(值為0)時,整個表達式的值為表達式2的值。
10. 指針與地址運算符:
C語言提供了兩個專門的運算符:
* 取內容; & 取地址
變量= * 指針變量
指針變量= & 目標變量
取內容運算是將指針變量所指向的目標變量的值賦給左邊的變量;取地址運算是將目標變量的地址賦給左邊的變量。
11. 強制類型轉換運算符
C語言中的“()”就是強制類型轉換運算符,它的作用是將表達式或變量的類型強制轉換成為
所指定的類型。 強制類型轉換運算符的一般使用形式為:(類型)=表達式顯式類型轉換在給指針變量賦值時特別有用。例如,預先在8051單片機外部數據存儲器(xdata)中定義了一個字符型指針變量px,如果想給這個指針變量賦一初值oxB000,可以寫成:
px=(char xdata*)oxB00;這種方法特別適合於用標識符來存取絕對地址。
12. sizeof 運算符
C語言提供了一種用於求取數據類型、變量以及表達式的字節數的運算符:sizeof,該運算
符的一般使用形式為:Sizeof (表達式) 或sizeof (數據類型)
應該注意的是,sizeof是一種特殊的運算符,不要錯誤地認為它是一個函數。實際上,
字節數的計算在程序編譯時就完成了,而不是在程序執行的過程中才計算出來的。
3.5 C程序設計的基本語句
3.5.1 表達式語句
C語言是一種結構化的程序設計語言。C語言提供了相當豐富的程序控制語句。
表達式語句是最基本的一種語句。在表達式后面加入分號“;”就構成表達式語句。在C語言中有一個特殊的表達式語句,稱為空語句,它僅僅是由一個分號“;”組成。
3.5.2 復合語句
由若干條語句組合而成的語句就叫復合語句。復合語句之間用{}分隔,而它內部的各條語
句還是需要以分號“;”結束。復合語句的一般形式為:
{ 局部變量定義;
語句1;
語句2;
語句n;
}
復合語句是允許嵌套的,也是就是在{}中的{}也是復合語句。復合語句在程序運行時,{}中的各行單語句是依次順序執行的。以C語言中可以將復合語句視為一條單語句,也就是說在語法上等同於一條單語句。
3.5.3 條件語句
條件語句又被稱為分支語句,其關鍵字是由if構成。
C語言提供3種形式的條件語句:
1.if (條件表達式) 語句
當條件表達式的結果為真時,就執行語句,否則就跳過。
2.if (條件表達式) 語句1
else 語句2
當條件表達式成立時,就執行語句1,否則就執行語句2
3.if (條件表達式1) 語句1
else if (條件表達式2) 語句2
else if (條件表達式3) 語句3
else if (條件表達式m) 語句n
else 語句m
3.5.4 開關語句
開關語句是實現多方向條件分支的語句,其關鍵字是switch.它的一般形式如下:switch (表達式)
switch (表達式)
{
case 常量表達式1: 語句1; break;
case 常量表達式2: 語句2; break;
case 常量表達式3: 語句3; break;
case 常量表達式n: 語句n; break;
default: 語句
}
運行中switch后面的表達式的值將會做為條件,與case后面的各個常量表達式的值相對比,如果相等時則執行后面的語句,再執行break(間斷語句)語句,跳出switch語句。如果case沒有和條件相等的值時就執行default后的語句。當要求沒有符合的條件時不做任何處理,則可以不寫default語句。
3.5.5 循環語句
循環語句是幾乎每個程序都會用到的,它的作用就是用來實現需要反復進行多次的操作。在C語言中構成循環控制的語句有while,do-while,for和goto語句。一般形式如下:
1.while 語句;
While 語句用到實現“當型”循環結構,其一般形式如下:while(表達式) 語句;當表達式為非0 值(真)時,執行while 語句中的內嵌語句。其特點是:先判斷表達式,后執行語句。
2.do-while 語句;
do-while 語句用來實現“直到型”循環,特點是先執行循環體,然后判斷循環條件是否成立。其一般形式如下:
do
循環體語句
while(表達式);
3.for 語句;
C語言中的for 語句使用最為靈活,不僅可以用於循環次數已經確定的情況,而且可以用於循環次數不確定而只給出循環結束條件的情況。
for 語句的一般形式為:
for(表達式1;表達式2;表達式3) 語句
它的執行過程是:
(1) 先求解表達式1
(2) 求解表達式2,其值為真,則執行for 語
句中指定的內嵌語句(循環體),然后執行
第(3)步,如果為假,則結束循環。
(3) 求解表達式3
(4) 轉回上面的第(2)步繼續執行。
for 語句典型的應用是這樣一種形式:
for(循環變量初值;循環條件;循環變量增值) 語句
如果變量初值在for 語句前面賦值,則for 語句中的表達式1 應省略,但其后的分號不能省略。表達式2 也可以省略,但是同樣不能省略其后的分號,如果省略該式,將不判斷循環條件,循環無終止地進行下去,也就是認為表達式始終為真。表達式3 也可以省略,但此時編程者應該另外設法保證循環能正常結束。
4.goto 語句
goto 語句是一個無條件轉向語句,它的一般形式為:
goto 語句標號;
其語句標號是個帶冒號的標識符。
常見的是在C程序中采用goto 語句來跳出多重循環。
C 語言中的三種循環語句可以相互嵌套。在一個循環程序中,可以通過循環語句中的表達式來控制循環程序是否結束,除此之外,還可以通過break 語句和continue 語句強行退出循環結構。Continue 語句和break 語名的區別是:continue 語句只結束本次循環,而不是終止整個循環的執行;而break 語句則是結束整個循環過程,不會再去判斷循環條件是否滿足。
3.5.6 返回語句
返回語句用於終止函數的執行,並控制程序返回到調用該函數時所處的位置。返回語句有兩種形式:return(表達式);或者return;如果return語句后面帶有表達式,則要計算表達式的值,並將表達式的值作為該函數的返回值。若使用不帶表達式的第2種形式,則被調用函數返回主調用函數時,函數值不確定。