Cx51流程控制共有3種基本結(jié)構(gòu):順序結(jié)構(gòu)、選擇結(jié)構(gòu)以及循環(huán)結(jié)構(gòu)。
一、順序結(jié)構(gòu)
順序結(jié)構(gòu)是最基本、最簡(jiǎn)單的編程結(jié)構(gòu),程序按先后順序執(zhí)行指令代碼。
下圖是8051單片機(jī)的P0口和P1口上分別連接了8個(gè)LED,請(qǐng)分別用P0和P1口顯示加法125+34和減法176-98的運(yùn)算結(jié)果
#include
int main(void)
{
unsigned char a=125,b=34,c=176,d=98;
P1=a+b; //加法運(yùn)算結(jié)果送P1端口,P1=159=1001 1111B
P0=c-d; //減法運(yùn)算結(jié)果送P0端口,P0=78=0100 1110B
while(1); //循環(huán)等待,防止主程序退出后單片機(jī)跑飛
}
二、選擇結(jié)構(gòu)
2.選擇結(jié)構(gòu)
(1)if語(yǔ)句
if語(yǔ)句用于根據(jù)條件判定結(jié)果決定執(zhí)行的語(yǔ)句。if語(yǔ)句有三種基本形式:
if(表達(dá)式)
{語(yǔ)句組}
說(shuō)明:如果“表達(dá)式”為真,則執(zhí)行花括號(hào)中的語(yǔ)句組,否則跳過(guò)花括號(hào)執(zhí)行下面的語(yǔ)句。
if(表達(dá)式)
{語(yǔ)句組1}
else
{語(yǔ)句組2}
說(shuō)明:如果“表達(dá)式”真,則執(zhí)行語(yǔ)句組1,否則執(zhí)行語(yǔ)句組2。
if(表達(dá)式1)
{語(yǔ)句1}
else if(表達(dá)式2)
{語(yǔ)句組2 }
else if(表達(dá)式3)
{語(yǔ)句組3}
else if(表達(dá)式m)
{語(yǔ)句組m}
else
{語(yǔ)句組n}
說(shuō)明:如果“表達(dá)式1”為真,則執(zhí)行“語(yǔ)句組1”,否則如果“表達(dá)式2”為真,則執(zhí)行“語(yǔ)句組2”…,如果所有的表達(dá)式都不滿(mǎn)足,則執(zhí)行語(yǔ)句組n。
同圖4-2,用if語(yǔ)句根據(jù)54/18的計(jì)算結(jié)果選擇P0口8位LED的狀態(tài)。
#include //包含單片機(jī)寄存器的頭文件
int main(void)
{
unsigned char a=54,b=18;
if (a/b==1)P0=0xfe; //第一個(gè)LED亮
else if (a/b==2) P0=0xfd; //第二個(gè)LED亮
else if (a/b==3) P0=0xfb; //第三個(gè)LED亮
else if (a/b==4) P0=0xf7; //第四個(gè)LED亮
else if (a/b==5) P0=0xef; //第五個(gè)LED亮
else if (a/b==6) P0=0xdf; //第八個(gè)LED亮
else if (a/b==7) P0=0xbf; //第七個(gè)LED亮
else if (a/b==8) P0=0x7f; //第八個(gè)LED亮
else P0=0xff; //缺省值,關(guān)閉所有LED
while(1);
}
(2)switch/case語(yǔ)句
根據(jù)表達(dá)式的值決定要執(zhí)行的語(yǔ)句組,用于實(shí)現(xiàn)多中選一,形式如下:
switch(表達(dá)式)
{
case常量表達(dá)式1://如果1滿(mǎn)足,則執(zhí)行語(yǔ)句組1
語(yǔ)句組1;
break; //跳出switch結(jié)構(gòu)
case常量表達(dá)式2://如果2滿(mǎn)足,則執(zhí)行語(yǔ)句組2
語(yǔ)句組2;
break; //跳出switch結(jié)構(gòu)
…
default: //條件都不滿(mǎn)足時(shí),執(zhí)行語(yǔ)句組n
語(yǔ)句組n;
}
同圖4-2,用swtich語(yǔ)句根據(jù)54/18的計(jì)算結(jié)果選擇P0口8位LED的狀態(tài)
#include //包含單片機(jī)寄存器的頭文件
int main(void)
{
unsigned char a=56,b=18;
switch(a/b) //使用多分支選擇語(yǔ)句
{
case 1: P0=0xfe; break; //第一個(gè)LED亮
case 2: P0=0xfd; break; //第二個(gè)LED亮
case 3: P0=0xfb; break; //第三個(gè)LED亮
case 4: P0=0xf7; break; //第四個(gè)LED亮
case 5: P0=0xef; break; //第五個(gè)LED亮
case 6:P0=0xdf; break; //第六個(gè)LED亮
case 7:P0=0xbf; break; //第七個(gè)LED亮
case 8:P0=0x7f; break; //第八個(gè)LED亮
default: P0=0xff; //缺省值,關(guān)閉所有LED
}
while(1);
}
1、for循環(huán)
for 循環(huán)結(jié)構(gòu)用于按指定的次數(shù)循環(huán)執(zhí)行一組語(yǔ)句,格式如下:
for(表達(dá)式1;表達(dá)式2;表達(dá)式3)
{語(yǔ)句;}
for循環(huán)語(yǔ)句執(zhí)行過(guò)程如下:
(1)先執(zhí)行表達(dá)式1,一般是對(duì)循環(huán)變量賦初值;
(2)執(zhí)行表達(dá)式2,若表達(dá)式2結(jié)果為真,則執(zhí)行循環(huán)體語(yǔ)句,并求解表達(dá)式
3(一般是改變循環(huán)變量的值);然后再次執(zhí)行表達(dá)式2;并判斷結(jié)果真假
(3)若表達(dá)式2結(jié)果為假,則退出for循環(huán)。
三、循環(huán)結(jié)構(gòu)
while循環(huán)
while循環(huán)語(yǔ)句先判斷條件真假,若表達(dá)式為真,則執(zhí)行花括號(hào)內(nèi)的語(yǔ)句組,否則終止循環(huán),格式如下:
while(表達(dá)式)
{語(yǔ)句組}
同圖4-3,用while循環(huán)計(jì)算7的階乘并送P1和P0口顯示結(jié)果。
#include //包含單片機(jī)寄存器的頭文件
int main(void)
{
unsigned char i=1;
unsigned int s=1;
while(i<=7)
{
s=s*i;//計(jì)算階乘
i++; //i自增運(yùn)算
}
P1=s/256; //高8位送P1顯示
P0=s%256; //低8位送P0顯示
while(1);
}
do while 循環(huán)
先執(zhí)行花括號(hào)內(nèi)的語(yǔ)句組,然后執(zhí)行表達(dá)式,若結(jié)果為真,則重復(fù)執(zhí)行花括號(hào)內(nèi)的語(yǔ)句組,否則終止循環(huán),格式如下:
do
{語(yǔ)句組}
while(表達(dá)式);
根據(jù)下圖用do while循環(huán)計(jì)算7的階乘并送P1和P0口顯示結(jié)果。
#include //包含單片機(jī)寄存器的頭文件
int main(void)
{
unsigned char i=1;
unsigned int s=1;
do
{
s=s*i;//計(jì)算階乘
i++; //i自增運(yùn)算
} while(i<=7);
P1=s/256; //高8位送P1顯示
P0=s%256; //低8位送P0顯示
while(1);
}
四、數(shù)組
1.一維數(shù)組
(1)一維數(shù)組的定義方式為:
數(shù)據(jù)類(lèi)型 數(shù)組名 [常量表達(dá)式];
例如定義有3個(gè)元素字符型數(shù)組m:
charm[3];
m的3個(gè)元素分別是m[0], m[1], m[2]。數(shù)組的類(lèi)型指數(shù)組元素的取值類(lèi)型。對(duì)于同一個(gè)數(shù)組,其所有元素的數(shù)據(jù)類(lèi)型都是相同的。
(2)一維數(shù)組的初始化
數(shù)組初始化是指在數(shù)組定義時(shí)給數(shù)組元素賦予初值。
例如:
int m[3]={ 0,1,2};
相當(dāng)于a[0]=0,a[1]=1,a[2]=2。
當(dāng){ }中值的個(gè)數(shù)少于元素個(gè)數(shù)時(shí),只給前面部分元素賦值,其他元素自動(dòng)賦0值。
例如:
int m[3]={0,1}
(3)一維數(shù)組元素的引用
數(shù)組必須預(yù)先定義才能使用。數(shù)組只能逐個(gè)地使用各元素,而不能一次引用整個(gè)數(shù)組。例如,輸出有10個(gè)元素的數(shù)組必須使用循環(huán)語(yǔ)句逐個(gè)輸出各下標(biāo)變量:
for(i=0;i<3; i++)
printf("%d",m[i]);
而不能用一個(gè)語(yǔ)句輸出整個(gè)數(shù)組。因此,下面的寫(xiě)法是錯(cuò)誤的:
printf("%d",m);
用一維數(shù)組實(shí)現(xiàn)流水點(diǎn)亮P0口的8位LED
int main(void) //主函數(shù)
{
unsigned char i;
unsigned char code Tab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //定義無(wú)符號(hào)字符型數(shù)組
while(1)
{
for(i=0;i<8;i++)
{
P0=Tab[i];//依次引用數(shù)組元素,并將其送P0口顯示
delay();//調(diào)用延時(shí)函數(shù)
}
}
}
2.二維數(shù)組
二維數(shù)組是以行列矩陣的形式存儲(chǔ)數(shù)據(jù)。
** (1)二維數(shù)組定義**
數(shù)據(jù)類(lèi)型 數(shù)組名[下標(biāo)1][下標(biāo)2];
第一個(gè)下標(biāo)代表行,第二個(gè)下標(biāo)代表列。例如語(yǔ)句 int a[2][3] 定義了二維整形數(shù)組,共有2行3列6個(gè)元素。
(2)二維數(shù)組的初始化
可以采用以下兩種方式初始化:
按先行后列的存儲(chǔ)順序整體賦值,例如:
int a[2][3]={0,1,2,3,4,5}
按每行分別賦值,例如:
int a[2][3]={{0,1,2},{3,4,5}};
用二維數(shù)組實(shí)現(xiàn)流水點(diǎn)亮P0口的8位LED。
int main(void)
{
unsigned char i,j;
unsigned char codeTab[2][4]={{0xfe,0xfd,0xfb,0xf7},{0xef,0xdf,0xbf,0x7f}}; //定義無(wú)符 //號(hào)字符型數(shù)組
while(1)
{
for(i=0;i<2;i++)
for(j=0;j<4;j++)
{
P0=Tab[i][j];//依次引用數(shù)組元素,并將其送P0口顯示
delay();//調(diào)用延時(shí)函數(shù)
}
}
}
變量的指針就是變量的地址。在C語(yǔ)言中,允許用一個(gè)變量來(lái)存放指針,這種變量稱(chēng)為指針變量。
指針變量是一種特殊的變量,它也和一般變量一樣,具有變量名、類(lèi)型和值,但它的值就是變量所存放的地址。
通過(guò)指針對(duì)變量進(jìn)行操作是間接操作,比直接操作變量更費(fèi)時(shí)間,且不夠直觀,但可以通過(guò)靈活運(yùn)用指針使程序代碼更為簡(jiǎn)潔、有效。
四、指針
1、指針變量的定義
指針變量同普通變量一樣,使用之前要進(jìn)行定義。指針變量定義的一般形式為:
數(shù)據(jù)類(lèi)型 *變量名;
其中,數(shù)據(jù)類(lèi)型表示本指針變量所指向變量的數(shù)據(jù)類(lèi)型,*表示這是一個(gè)指針變量。
例如:定義:int*point,表示point指向一個(gè)整型變量,但point具體指向哪一個(gè)整型變量,取決于point中所存儲(chǔ)的地址。一個(gè)指針變量只能指向同類(lèi)型的變量,如上述point 只能指向整形變量,不能指向一個(gè)字符變量。
2、指針變量的引用
指針變量在使用之前必須賦予具體的地址,使用未經(jīng)賦值的指針變量會(huì)引起嚴(yán)重后果。指針變量的引用有兩個(gè)重要運(yùn)算符:
&:取地址運(yùn)算符;
*:指針運(yùn)算符(或稱(chēng)“間接訪(fǎng)問(wèn)” 運(yùn)算符)。
在指針變量定義中所出現(xiàn)的“ ”是類(lèi)型說(shuō)明符,表示其后的變量是指針類(lèi)型,而指針運(yùn)算符“ ”則出現(xiàn)在表達(dá)式中,用以表示指針指向的變量值。
地址運(yùn)算符&用來(lái)取出變量的地址。其形式為:
&變量名;
?指針運(yùn)算符*用來(lái)取出指針指向變量的值,其形式為:
*指針變量名;
inti,j;
int *point;
point= &i;
j=*point;
表示取出變量i的值賦予變量j,與語(yǔ)句j=i的效果相同。對(duì)*point的任何操作與直接對(duì)變量i的操作效果相同。
3、數(shù)組指針
一個(gè)變量有一個(gè)地址,一個(gè)數(shù)組包含若干元素,每個(gè)數(shù)組元素都在內(nèi)存中占用存儲(chǔ)單元,它們都有相應(yīng)的地址。數(shù)組的指針是指數(shù)組的起始地址,數(shù)組元素的指針是數(shù)組元素的地址。
一個(gè)數(shù)組是由連續(xù)的一塊內(nèi)存單元組成的。數(shù)組名就是這塊連續(xù)內(nèi)存單元的首地址。一個(gè)數(shù)組也是由各個(gè)數(shù)組元素(下標(biāo)變量)組成的。每個(gè)數(shù)組元素按其類(lèi)型不同占有幾個(gè)連續(xù)的內(nèi)存單元。一個(gè)數(shù)組元素的首地址也是指它所占有的幾個(gè)內(nèi)存單元的首地址。
定義一個(gè)指向數(shù)組元素的指針變量,與定義普通變量的指針相同。例如:
intm[]={1,2,3};4int*p;4p=&m[0];
經(jīng)上述定義后,p就是數(shù)組m的指針。因?yàn)閿?shù)組名代表數(shù)組的首地址,也就是第一個(gè)元素的地址,因此下面兩個(gè)語(yǔ)句等價(jià):
p=&m[0];
p=m;
p指向數(shù)組m的首地址后,p+i就是數(shù)組的元素m[i]。
例題:用一維數(shù)組實(shí)現(xiàn)流水點(diǎn)亮P0口的8位LED。
int main(void)
{
unsigned char i;
unsigned char code Tab[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; /*定義無(wú)符號(hào)字符型數(shù)組*/
unsigned char *p;
p=&Tab[0];/*定義指針變量并指向Tab數(shù)組,也可寫(xiě)為unsigned char *p=Tab */
while(1)
{
for(i=0;i<8;i++)
{
P0=*(p+i);//通過(guò)指針變量依次引用數(shù)組元素,并將其送P0口顯示
delay();//調(diào)用延時(shí)函數(shù)
}
}
}
指向二維數(shù)組的指針變量的說(shuō)明形式為
類(lèi)型說(shuō)明符 (*指針變量名)[長(zhǎng)度];
“長(zhǎng)度”是二維數(shù)組的列數(shù)。二維數(shù)組的每一行都代表一個(gè)一維數(shù)組,該一維數(shù)組的長(zhǎng)度就是二維數(shù)組的列數(shù)。若該指針變量指向二組數(shù)組A[m][n]的首地址,則 (指針變量名+i)就是A[i],而A[i]是一維數(shù)組A[i][n]的首地址, (*(指針變量名+i)+j)就是A[i][j]的值。
例題:用二維數(shù)組實(shí)現(xiàn)流水點(diǎn)亮P0口的8位LED。
int main(void)
{
unsigned char i,j;
unsigned char codeTab[2][4]={{0xfe,0xfd,0xfb,0xf7},{0xef,0xdf,0xbf,0x7f}}; //定
//義無(wú)符號(hào)字符型數(shù)組
unsigned char (*p)[4]; //定義二維數(shù)組指針
p=Tab;//指向二維數(shù)組首地址
while(1)
{
for(i=0;i<2;i++)
for(j=0;j<4;j++)
{
P0=*(*(p+i)+j);//依次引用數(shù)組元素,并將其送P0口顯示
delay();//調(diào)用延時(shí)函數(shù)
}
}
}
-
Cx51
+關(guān)注
關(guān)注
0文章
4瀏覽量
7625 -
循環(huán)結(jié)構(gòu)
+關(guān)注
關(guān)注
0文章
22瀏覽量
7723 -
順序結(jié)構(gòu)
+關(guān)注
關(guān)注
0文章
8瀏覽量
6558
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論