RYMCU

第5章 单片机 C 语言基础(二)

5.6.4 运算符

平常接触最多的运算符,“加减乘除”。为了让编译器能够识别,在 C 语言中常常用一些特别的符号来代表他们,例如用“+ - * /”分别表示“加减乘除”。
根据功能,将运算符分为:算数运算符、赋值运算符、关系运算符、逻辑运算符、位运算符、其他运算符。如下表所示,介绍了各运算符的意义。

序号 运算符 范例 功能说明
算数运算符
1. + a+b a 变量值和 b 变量值相加
2. - a-b a 变量值和 b 变量值相减
3. * a*b a 变量值乘以 b 变量值
4. / a/b a 变量值除以 b 变量值
5. % a%b a 变量值除以 b 变量值的余数
6. ++ a++ 等同于 a=a+1,a 值自加 1
7. -- a-- 等同于 a=a-1 ,a 值自减 1
赋值运算符
8. = a=1 将 1 赋值给变量 a
9. += a+=b 等同于 a=a+b,将 a 加 b 的结果赋值给 a
10. -= a-=b 等同于 a=a-b,将 a 减 b 的结果赋值给 a
11. *= a*=b 等同于 a=a*b,将 a 乘 b 的结果赋值给 a
12. /= a/=b 等同于 a=a/b,将 a 除 b 的结果赋值给 a
13. %= a%=b 等同于 a=a%b,将 a 除 b 的余数赋值给 a
关系运算符
14. > a>b 测试 a 是否大于 b
15. < a= a>=b
18. <= a<=b 测试 a 是否小于等于 b
19. != a!=b 测试 a 是否不等于 b
逻辑运算符
20. && a&&b 变量 a 与变量 b 作逻辑"与"操作,两个变量都为"真",结果才为"真",否则为"假"
21. || a||b 变量 a 与变量 b 作逻辑"或"操作,只要任何一个变量为"真",结果为"真",否则为"假"
22. ! !a 将变量 a 值取反,即原来为"真",结果为"假",原来为 "假",结果为"真"
位运算符
23. >> a>>b 将 a 变量值右移 b 位
24. << a << b 将 a 变量值左移 b 位
25. | a|b 将变量 a 和变量 b 按位作"或"运算
26. & a&b 将变量 a 和变量 b 按位作"与"运算
27. ^ a^b 将变量 a 和变量 b 按位作"异或"运算
28. ~ ~a 将 a 的每一位取反
其他运算符
29. & a=&b 将 b 变量的地址存入 a 变量
30. * a=*b 将地址 b 中的内容赋值给 a

下面通过程序代码 operator.c,并举例介绍常用运算符的操作。

/*******************************************************************
* 运算符实例
*******************************************************************/
#include
<stdio.h>

void main()    // 程序主函数入口,每个C语言程序有且只有一个
{
int a = 10;
int b = 5;
int c;
/*********************************************
* 算术运算符实例
**********************************************/
printf("----- 算术运算符实例---- nn");
printf("初始值:a=10,b=5nn");
c = a + b; //a 加b,并将结果赋值个变量c
printf("a+b = %dn", c);
c = a - b; //a 减b,并将结果赋值个变量c
printf("a-b = %dn", c);
c = a * b; //a 乘b,并将结果赋值个变量c
printf("a*b = %dn", c);
c = a / b; //a 除以b,并将结果赋值个变量c
printf("a/b = %dnn", c);


a=10;
a++;
printf("a=10,a++之后,a= %dn", a);


a=10;
a--;
printf("a=10,a-- 之后,a= %dnn", a);


/*********************************************
* 关系运算符实例
**********************************************/
printf("----- 关系运算符实例---- nn");


a = 10;// 改变a,b的值下面语句会输出不同结果
b = 5;
printf(" == 运算符实例nn");
printf("初始值:a=%d,b=%dn", a, b);
if (a==b) // 如果a等于b,执行下面{}里面的语句,否则执行 else 的{}里面的语句
{
printf("a 等于bn");
}
else
{
printf("a 不等于bn");
}


printf("n < 运算符实例nn");
printf("初始值:a=%d,b=%dn", a, b);
if (a<b) // 如果a小于b,执行下面{}里面的语句,否则执行 else 的{}里面的语句
{
printf("a 小于bn");
}
else
{
printf("a 不小于bn");
}

printf("n其他关系运算符情况类似!n");
return;
}

图 5-14 运算符练习代码

运行结果如下:

图 5-15 运算符练习结果

单片机 C 语言编程中,位运算符用的相对较多,位的 3 个基本运算符,分别为:&:按位与,|:按位或,^:按位异或,真值表如下:

表 5-6 位运算真值表

a b a&b a|b a^b
0 0 0 0 0
0 1 0 1 1
1 0 0 1 1
1 1 1 1 0

假设 A = 55,B = 21,选转换为二进制,查上表便可计算:
A = 0011 0111
B = 0001 0101


A&B = 0001 0101

A| B = 0011 0111

A^ B = 0010 0010

~:按位取反操作符,即 0 变 1,1 变 0:

A = 0011 0111


~A = 1100 1000

>> :右移运算符

A>>3,将 A 右移动 3 位,并在左边补 3 个 0

A = 0011 0111


= 0 0110 先右移动 3 位

A>>3 = 0 0110 左边补 3 个 0

<<: 左移运算符,与右移类似

A>>3,将 A 左移动 3 位,并在右边补 3 个 0

A = 0011 0111


= 1011 1 先左移动 3 位

A<<3 = 1011 1000 右边补 3 个 0

上面讲解的都是在一条语句中只有一个运算符,如果有多个运算符的情况下该怎么计算呢?例如下面的赋值语句:

a = 1 + 2 * 3;

// 运算结果应该为 7,即先算 2*3,再加 1,原因为" * "的优先级比" + "更高

各运算符的优先级如下表所示:

表 5-7 运算符优先级


类别 运算符 结合性
后缀 () [] -> . ++ -- 从左到右
一元 + - !``~ ++ - - (type)* & sizeof 从右到左
乘除 * / % 从左到右
加减 + - 从左到右
移位 << >> 从左到右
关系 < <= > >= 从左到右
相等 == != 从左到右
位与 AND & 从左到右
位异或 XOR ^ 从左到右
位或 OR | 从左到右
逻辑与 AND && 从左到右
逻辑或 OR || 从左到右
条件 ? : 从右到左
赋值 = += -= *= /= %=``>>= <<= &= ^= |= 从右到左
逗号 , 从左到右

5.6.5 流程控制

C 语言的程序执行方式为,一条一条语句按顺序往下执行,在程序中加入流程控制语句,可以将程序跳转至指定的地方运行。下面讲解 C 语言常用的流程控制语句。

if 语句

表达式如下:

if(条件表达式)

{动作}

语法:

如果"条件表达式"的值为真(非零的数),则执行{ }内"动作",如果"条件表达式"为假,则跳过该"动作"而继续往下执行。

举例说明编写, if.c 文件如下:

/********************************************************
* 程序功能:
*使用 if 语句判断,按键输入的是否为数字
*********************************************************/
#include <stdio.h>

void main() {
    int number;
    printf("n请按下键盘的一个按键,并按回车键:");
    scanf("%d", &number);
    // 先判断按的按键是否小于等于9,是的话,执行{}里的内容
    if (number <= 9) {
        printf("n输入了数字:%dn", number);
    }
    printf("n程序结束!n");
    return;
}

图 5-16 if 语句代码

运行结果如下,可尝试输入非数字的按键。

图 5-17 if 语句运行结

if --else 语句

表达式如下:

if(条件表达式)

{动作 1}

else

{动作 2}

语法:

如果条件表达式为真,则执行动作 1,跳过 else 部分的动作 2,接着往下执行。如果条件表达式为假,则跳过动作 1,执行动作 2,然后继续往下执行。

举例说明编写, if-else.c 文件如下:

/********************************************************
* 程序功能:
*使用 if-else 语句判断,按键输入的是否为数字或字符
*********************************************************/
#include <stdio.h>

void main() {
    int number;
    printf("n请按下键盘的一个按键,并按回车键:");
    scanf("%d", &number);

    // 先判断按的按键是否小于等于9,是的话,执行{}里的内容
    if (number <= 9) {
        printf("n输入了数字:%dn", number);
    } else {
        printf("n输入的不是数字,是一个字符!n");
    }

    printf("n程序结束!n");
    return;
}

图 5-18 if-else 语句代码

2 次运行程序,输入的分别是数字 1 和字符 e,程序执行结果如下:

图 5-19 if-else 试验结果

switch-case 语句

表达式如下:

switch(条件表达式)
{
    case 条件值 1:
        动作1
        break;
    case 条件值 2:
        动作2
        break;
    ...
    default:
        动作N;
        break;
}

语法:

先计算"条件表达式"的值,然后逐个和 case 后面的"条件值"比较,如果不相等,则顺序往下比较,如果一直不相等,则执行 default 后面的语句。如果等于执行这个"条件值"后面的语句,并且后续所有 case 后的语句都不执行。

举例说明编写, caseswitch.c 文件如下:

/********************************************************
* 程序功能:
*使用 switch-case 语句判断,根据输入的数字,显示星期几。
*1-7 分别对应星期一-星期日
*其他数字无效
*********************************************************/
#include <stdio.h>

void main() {
    int a;
    printf("请输入数字,回车结束: ");
    scanf("%d", &a);

    // 输入数字a,和下面 case 后面的数字对比
    switch (a) {
        case 1:
            printf("n星期一n");
            break;
        case 2:
            printf("n星期二n");
            break;
        case 3:
            printf("n星期三n");
            break;
        case 4:
            printf("n星期四n");
            break;
        case 5:
            printf("n星期五n");
            break;
        case 6:
            printf("n星期六n");
            break;
        case 7:
            printf("n星期日n");
            break;
        default:
            printf("n输入错误!n");
    }

    return;
}

图 5-20 case 语句代码

运行 3 次,分别输入不同数字,结果如下图所示:

图 5-21 case 语句运行结果

while 循环语句

表达式如下:

while(条件表达式)

{动作}

语法:

先执行 while 后面的"条件表达式",如果为真,则执行{}里面的"动作",执行完之后,再次回去执行"条件表达式"。如此,一直循环,直到"条件表达式"不为真,才结束 while 循环。

举例说明编写, while.c 文件如下:

/********************************************************
* 程序功能:
*使用 whie 语句
* 循环打印变量值
*********************************************************/
#include <stdio.h>

void main() {
    int a = 0;// 变量定义,并初始化为0

/**********************************
    1.先判断a是否小于 10,成立的话,执行{}
    里面的语句,{}里面语句执行完之后,在判断
    a是否小于 10,成立的话,继续执行{}内语句,
    如此循环,直到a不小于 10.
    2.下面程序中,{}内没执行一次a的值加1,因此,
    执行 10 次之后,a不小于 10 ,循环结束。
**********************************/
    while (a < 10) {
        a = a + 1;
        printf("a 的值:%dn", a);
    }

    printf("n程序结束!n", a);
    return;
}

图 5-22 while 语句代码

程序运行结果如下:

图 5-23 while 运行结果

for 循环语句

表达式如下:

for(初始化;条件 1;表达式 2)

{ 动作 }

语法:

"初始化"首先被执行,并且只会执行一次;

判断"条件 1",如果为真,执行后续 {} 中的"动作",如果不为真,则结束 for 循环;

执行完"动作"后,执行"表达式 2" ,这里的"表达式 2" 往往会更新"条件 1" 的状态;

回到 2 继续执行。

举例说明编写, for.c 文件如下:

/********************************************************
* 程序功能:
*使用 for 语句
* 循环打印变量值
*********************************************************/
#include <stdio.h>

void main() {
    // 变量定义
    int a;

/**********************************
    1.for 循环首先出初始化a=0
    2.执行第二条语句判断a<10 是否成立,不成立直接结束
    3.如果2成立
    4.执行{}内的所有内容
    5.执行a++
    6.跳转到2继续执行
    a每次循环都加1,因此,{}的内容将执行 10 次
**********************************/
    for (a = 0; a < 10; a++) {
        printf("a 的值:%dn", a);
    }

    printf("n程序结束!n", a);
    return;
}

图 5-24 for 语句代码

运行结果如下:

图 5-25 for 语句运行结果

5.6.6 函数

函数是一组一起执行一个任务的语句,通常我们会让函数来执行一个特定的任务。如果我们在程序的不同地方需要多次执行这个任务,我们只需要调用这个函数即可,而不需要每次都重复写这段代码。

我们前面用到过得 prinf(),就是标准的 C 语言库函数,它的功能就是打印显示指定的数据。定义函数:

返回值类型 函数名称(参数 1,参数 2,参数 3,...)

{

函数主体;

}

语法:

**返回值类型:一个函数可以返回一个值或者不返回。"返回值类型"**就指这个值的数据类型。如果函数没有返回值,那么,"返回值类型就是"关键字 void。

**函数名称:**这是函数标识符,也就是这个函数的名字。

**参数:**参数就像是占位符。当函数被调用时,您向参数传递一个值,这个值被称为实际参数。参数列表包括函数参数的类型、顺序、数量。参数是可选的,也就是说,函数可能不包含参数。

**函数主体:**函数主体包含一组定义函数执行任务的语句。

举例说明:

/********************************************************
* 程序功能:
*比较两个数的值,并显示较小的值
* 循环打印变量值
*********************************************************/
#include <stdio.h>

void main() {
    int a = 1, b = 2;
    int c;

    // a,b谁小,就把它赋值给c,然后显示c,就达到了显示较小值的目的
    if (a < b) {
        c = a;
    } else {
        c = b;
    }

    printf("较小值的值:%dn", c);
    return;
}

图 5-26 函数代码 1

如上第 14-21 行是比较 a 和 b 大小的功能代码,下面我们使用函数替代他们。编写代码 function.c,如下:

/********************************************************
* 程序功能:
*比较两个数的值,并显示较小的值
* 循环打印变量值
*********************************************************/
#include <stdio.h>

// 计算较小值得函数
int Min(int num1, int num2) {
    int result;

    if (num1 < num2) {
        result = num1;
    } else {
        result = num2;
    }

    return result;
}


// 主函数
void main() {
    int a = 1, b = 2;
    int c;
    // 调用函数 Min(),返回较小值
    c = Min(a, b);
    printf("n较小值的为:%dn", c);
    return;
}

图 5-27 函数代码 2

在第 28 行,通过调用函数 Min(),即一条语句替换了最开始的多条语句。上图的第 8-21 行是我们定义的函数 int Min( int num1, int num2 ) ,函数的返回值类型为 int,函数名称为 Min,函数参数为
num1, num2 ,函数主体的功能为比较 num1, num2 的大小,并将小的值返回。在第 28 行调用函数的时候,我们使用要比较的值 a,b 传递到函数里面,即替换了 num1, num2
。所以,函数的返回值就是 a,b 中小的那个值。程序运行结果如下图所示:

图 5-28 函数代码运行结果

5.7 本章小结

为了方便我们后续的单片机开发,本章介绍了 C 语言的基础知识,基本都是点到为止。更多的内容请参考专业的 C 语言书籍。本章中涉及的代码均放入了资料包中,如下图所示。

图 5-29 C 语言代码路径

后发布评论