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("----- 算术运算符实例---- \n\n");
printf("初始值:a=10,b=5\n\n");
c = a + b; //a 加b,并将结果赋值个变量c
printf("a+b = %d\n", c);
c = a - b; //a 减b,并将结果赋值个变量c
printf("a-b = %d\n", c);
c = a * b; //a 乘b,并将结果赋值个变量c
printf("a*b = %d\n", c);
c = a / b; //a 除以b,并将结果赋值个变量c
printf("a/b = %d\n\n", c);
a=10;
a++;
printf("a=10,a++之后,a= %d\n", a);
a=10;
a--;
printf("a=10,a-- 之后,a= %d\n\n", a);
/*********************************************
* 关系运算符实例
**********************************************/
printf("----- 关系运算符实例---- \n\n");
a = 10;// 改变a,b的值下面语句会输出不同结果
b = 5;
printf(" == 运算符实例\n\n");
printf("初始值:a=%d,b=%d\n", a, b);
if (a==b) // 如果a等于b,执行下面{}里面的语句,否则执行 else 的{}里面的语句
{
printf("a 等于b\n");
}
else
{
printf("a 不等于b\n");
}
printf("\n < 运算符实例\n\n");
printf("初始值:a=%d,b=%d\n", a, b);
if (a<b) // 如果a小于b,执行下面{}里面的语句,否则执行 else 的{}里面的语句
{
printf("a 小于b\n");
}
else
{
printf("a 不小于b\n");
}
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 0111B = 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输入了数字:%d\n", 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输入了数字:%d\n", 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 的值:%d\n", 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 的值:%d\n", 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("较小值的值:%d\n", 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较小值的为:%d\n", 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语言代码路径