51单片机的控制语句

描述

Cx51流程控制共有3种基本结构:顺序结构、选择结构以及循环结构。

一、顺序结构

顺序结构是最基本、最简单的编程结构,程序按先后顺序执行指令代码。

下图是8051单片机的P0口和P1口上分别连接了8个LED,请分别用P0和P1口显示加法125+34和减法176-98的运算结果

顺序结构

#include
int main(void)  
{ 
 unsigned char a=125,b=34,c=176,d=98;
 P1=a+b; //加法运算结果送P1端口,P1=159=1001 1111B
 P0=c-d;  //减法运算结果送P0端口,P0=78=0100 1110B
 while(1); //循环等待,防止主程序退出后单片机跑飞
 }

二、选择结构

2.选择结构

(1)if语句

if语句用于根据条件判定结果决定执行的语句。if语句有三种基本形式:

if(表达式)
    {语句组}

说明:如果“表达式”为真,则执行花括号中的语句组,否则跳过花括号执行下面的语句。

if(表达式)
     {语句组1}
    else
     {语句组2}

说明:如果“表达式”真,则执行语句组1,否则执行语句组2。

if(表达式1)
      {语句1}
     else if(表达式2)
      {语句组2 }
     else if(表达式3)
      {语句组3}
     else if(表达式m)
      {语句组m}
     else
      {语句组n}

说明:如果“表达式1”为真,则执行“语句组1”,否则如果“表达式2”为真,则执行“语句组2”…,如果所有的表达式都不满足,则执行语句组n。

同图4-2,用if语句根据54/18的计算结果选择P0口8位LED的状态。

顺序结构

#include  //包含单片机寄存器的头文件
int main(void)
{ 
   unsigned char a=54,b=18;
   if (a/b==1)P0=0xfe; //第一个LED亮
   else if (a/b==2) P0=0xfd;  //第二个LED亮
   else if (a/b==3) P0=0xfb; //第三个LED亮
   else if (a/b==4) P0=0xf7; //第四个LED亮
   else if (a/b==5) P0=0xef;  //第五个LED亮 
   else if (a/b==6) P0=0xdf;  //第八个LED亮      
   else if (a/b==7) P0=0xbf;  //第七个LED亮          
   else if (a/b==8) P0=0x7f;  //第八个LED亮       
   else P0=0xff;  //缺省值,关闭所有LED 
   while(1); 
 }

(2)switch/case语句

根据表达式的值决定要执行的语句组,用于实现多中选一,形式如下:

switch(表达式)
 {
case常量表达式1//如果1满足,则执行语句组1
  语句组1;
  break;          //跳出switch结构
case常量表达式2//如果2满足,则执行语句组2
 语句组2;
  break;          //跳出switch结构default:          //条件都不满足时,执行语句组n
 语句组n;
  }

同图4-2,用swtich语句根据54/18的计算结果选择P0口8位LED的状态

顺序结构

#include  //包含单片机寄存器的头文件
int main(void)
{ 
  unsigned char a=56,b=18;
  switch(a/b)   //使用多分支选择语句
 {
     case 1: P0=0xfe; break;   //第一个LED亮
   case 2: P0=0xfd; break;   //第二个LED亮
   case 3: P0=0xfb; break;   //第三个LED亮
   case 4: P0=0xf7; break;   //第四个LED亮
   case 5: P0=0xef; break;   //第五个LED亮      
   case 6:P0=0xdf; break;    //第六个LED亮       
   case 7:P0=0xbf; break;    //第七个LED亮          
   case 8:P0=0x7f; break;    //第八个LED亮       
   default: P0=0xff;  //缺省值,关闭所有LED 
 }   
 while(1);
}

1、for循环

for 循环结构用于按指定的次数循环执行一组语句,格式如下:

for(表达式1;表达式2;表达式3)
{语句;}

for循环语句执行过程如下:

(1)先执行表达式1,一般是对循环变量赋初值;

(2)执行表达式2,若表达式2结果为真,则执行循环体语句,并求解表达式

3(一般是改变循环变量的值);然后再次执行表达式2;并判断结果真假

(3)若表达式2结果为假,则退出for循环。

三、循环结构

while循环

while循环语句先判断条件真假,若表达式为真,则执行花括号内的语句组,否则终止循环,格式如下:

while(表达式)
      {语句组}

同图4-3,用while循环计算7的阶乘并送P1和P0口显示结果。

顺序结构

#include  //包含单片机寄存器的头文件
int main(void)
{ 
  unsigned char i=1;
  unsigned int s=1;  
  while(i<=7)
  {
     s=s*i;//计算阶乘
     i++;  //i自增运算
  }
  P1=s/256;   //高8位送P1显示
  P0=s%256;   //低8位送P0显示
  while(1);
}

do while 循环

先执行花括号内的语句组,然后执行表达式,若结果为真,则重复执行花括号内的语句组,否则终止循环,格式如下:

do
  {语句组}
while(表达式);

根据下图用do while循环计算7的阶乘并送P1和P0口显示结果。

顺序结构

#include  //包含单片机寄存器的头文件
int main(void)
{ 
  unsigned char i=1;
  unsigned int s=1;  
 do
  {
     s=s*i;//计算阶乘
     i++;  //i自增运算
    } while(i<=7);
  P1=s/256; //高8位送P1显示
  P0=s%256; //低8位送P0显示
  while(1);
}

四、数组

1.一维数组

(1)一维数组的定义方式为:

数据类型 数组名 [常量表达式];

例如定义有3个元素字符型数组m:

charm[3];

m的3个元素分别是m[0], m[1], m[2]。数组的类型指数组元素的取值类型。对于同一个数组,其所有元素的数据类型都是相同的。

(2)一维数组的初始化

数组初始化是指在数组定义时给数组元素赋予初值。

例如:

int m[3]={ 0,1,2};

相当于a[0]=0,a[1]=1,a[2]=2。

当{ }中值的个数少于元素个数时,只给前面部分元素赋值,其他元素自动赋0值。

例如:

int m[3]={0,1}

(3)一维数组元素的引用

数组必须预先定义才能使用。数组只能逐个地使用各元素,而不能一次引用整个数组。例如,输出有10个元素的数组必须使用循环语句逐个输出各下标变量:

for(i=0;i<3; i++)
   printf("%d",m[i]);

而不能用一个语句输出整个数组。因此,下面的写法是错误的:

printf("%d",m);

用一维数组实现流水点亮P0口的8位LED

顺序结构

int main(void) //主函数
{ 
  unsigned char i;
  unsigned char code Tab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //定义无符号字符型数组 
  while(1)
  {
   for(i=0;i<8;i++)
      {
        P0=Tab[i];//依次引用数组元素,并将其送P0口显示
        delay();//调用延时函数
     }
  }
}

2.二维数组

二维数组是以行列矩阵的形式存储数据。

** (1)二维数组定义**

数据类型 数组名[下标1][下标2];

第一个下标代表行,第二个下标代表列。例如语句 int a[2][3] 定义了二维整形数组,共有2行3列6个元素。

(2)二维数组的初始化

可以采用以下两种方式初始化:

按先行后列的存储顺序整体赋值,例如:

int a[2][3]={0,1,2,3,4,5}

按每行分别赋值,例如:

int a[2][3]={{0,1,2},{3,4,5}};

用二维数组实现流水点亮P0口的8位LED。

顺序结构

int main(void)
{ 
  unsigned char i,j;
  unsigned char codeTab[2][4]={{0xfe,0xfd,0xfb,0xf7},{0xef,0xdf,0xbf,0x7f}}; //定义无符  //号字符型数组 
  while(1)
  {
   for(i=0;i<2;i++)
   for(j=0;j<4;j++)
      {
        P0=Tab[i][j];//依次引用数组元素,并将其送P0口显示
        delay();//调用延时函数
     }
  }
}

变量的指针就是变量的地址。在C语言中,允许用一个变量来存放指针,这种变量称为指针变量。

指针变量是一种特殊的变量,它也和一般变量一样,具有变量名、类型和值,但它的值就是变量所存放的地址。

通过指针对变量进行操作是间接操作,比直接操作变量更费时间,且不够直观,但可以通过灵活运用指针使程序代码更为简洁、有效。

四、指针

1、指针变量的定义

指针变量同普通变量一样,使用之前要进行定义。指针变量定义的一般形式为:

数据类型 *变量名;

其中,数据类型表示本指针变量所指向变量的数据类型,*表示这是一个指针变量。

例如:定义:int*point,表示point指向一个整型变量,但point具体指向哪一个整型变量,取决于point中所存储的地址。一个指针变量只能指向同类型的变量,如上述point 只能指向整形变量,不能指向一个字符变量。

2、指针变量的引用

指针变量在使用之前必须赋予具体的地址,使用未经赋值的指针变量会引起严重后果。指针变量的引用有两个重要运算符:

&:取地址运算符;

*:指针运算符(或称“间接访问” 运算符)。

在指针变量定义中所出现的“ ”是类型说明符,表示其后的变量是指针类型,而指针运算符“ ”则出现在表达式中,用以表示指针指向的变量值。

地址运算符&用来取出变量的地址。其形式为:

&变量名;

Ø指针运算符*用来取出指针指向变量的值,其形式为:

*指针变量名;
inti,j;
int *point;
point= &i;
j=*point;

表示取出变量i的值赋予变量j,与语句j=i的效果相同。对*point的任何操作与直接对变量i的操作效果相同。

3、数组指针

一个变量有一个地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,它们都有相应的地址。数组的指针是指数组的起始地址,数组元素的指针是数组元素的地址。

一个数组是由连续的一块内存单元组成的。数组名就是这块连续内存单元的首地址。一个数组也是由各个数组元素(下标变量)组成的。每个数组元素按其类型不同占有几个连续的内存单元。一个数组元素的首地址也是指它所占有的几个内存单元的首地址。

定义一个指向数组元素的指针变量,与定义普通变量的指针相同。例如:

intm[]={1,2,3};4int*p;4p=&m[0];

经上述定义后,p就是数组m的指针。因为数组名代表数组的首地址,也就是第一个元素的地址,因此下面两个语句等价:

p=&m[0];
p=m;

p指向数组m的首地址后,p+i就是数组的元素m[i]。

例题:用一维数组实现流水点亮P0口的8位LED。

顺序结构

int main(void)
{ 
 unsigned char i;
 unsigned char code Tab[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; /*定义无符号字符型数组*/ 
 unsigned char *p;
  p=&Tab[0];/*定义指针变量并指向Tab数组,也可写为unsigned char   *p=Tab */
 while(1)
 {
   for(i=0;i<8;i++)
   {
        P0=*(p+i);//通过指针变量依次引用数组元素,并将其送P0口显示
        delay();//调用延时函数
   }
 }
}

指向二维数组的指针变量的说明形式为

类型说明符 (*指针变量名)[长度];

“长度”是二维数组的列数。二维数组的每一行都代表一个一维数组,该一维数组的长度就是二维数组的列数。若该指针变量指向二组数组A[m][n]的首地址,则 (指针变量名+i)就是A[i],而A[i]是一维数组A[i][n]的首地址, (*(指针变量名+i)+j)就是A[i][j]的值。

例题:用二维数组实现流水点亮P0口的8位LED。

顺序结构

int main(void)
{ 
 unsigned char i,j;
 unsigned char codeTab[2][4]={{0xfe,0xfd,0xfb,0xf7},{0xef,0xdf,0xbf,0x7f}}; //定
                                           //义无符号字符型数组
 unsigned char (*p)[4]; //定义二维数组指针
 p=Tab;//指向二维数组首地址
 while(1)
 {
   for(i=0;i<2;i++)
    for(j=0;j<4;j++)
   {
        P0=*(*(p+i)+j);//依次引用数组元素,并将其送P0口显示
        delay();//调用延时函数 
   }
 }
}
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分