1. 运算符概述
运算符是一种编译器执行特定的数学或逻辑操作的符号. C 语言提供了以下类型的运算符:
算术运算符
关系运算符
逻辑运算符
位运算符
赋值运算符
条件运算符
其他运算符
2. 算术运算符
算术运算符分为单目运算符和双目运算符, 单目运算符表示只需要一个操作数, 双目运算符需要两个操作数.
2.1 双目算术运算符
1)+ : 加法, 把两个操作数相加
2)- : 减法, 从第一个操作数中减去第二个操作数
3)* : 乘法, 把两个操作数相乘
4)/ : 除法, 第一个操作数除以第二个操作数
5)% : 求模(取余), 第一个操作数除以第二个操作数所得余数
双目运算符中, C 语言中的加号, 减号与数学中的一样. 乘号, 除号因为 ASCII 符号中没有与数学中相对应的符号, 所以使用星号表示乘号, 使用斜线表示除号. C 语言中增加了一个求模运算符, 是用来取余的. 需要注意的是, 求模运算符的两个操作数必须是整型.
[实例 6.1] 加减乘除以及取模运算
- #include <stdio.h>
- int main()
- {
- int a = 21;
- int b = 10;
- int c;
- float d = 2.5;
- double e;
- int f = -21;
- int g = -10;
- c = a + b;
- printf("a + b = %d\n", c);
- c = a - b;
- printf("a - b = %d\n", c);
- c = a * b;
- printf("a * b = %d\n", c);
- c = a / b;
- printf("a / b = %d\n", c);
- e = a / d;
- printf("a / d = %lf\n", e);
- c = a % b;
- printf("a %% b = %d\n", c);
- c = a % g;
- printf("a %% g = %d\n", c);
- c = f % b;
- printf("f %% b = %d\n", c);
- c = f % g;
- printf("f %% g = %d\n", c);
- return 0;
- }
执行以上程序, 输出结果为:
- a + b = 31
- a - b = 11
- a * b = 210
- a / b = 2
- a / d = 8.400000
- a % b = 1
- a % g = 1
- f % b = -1
- f % g = -1
实例解析:
加, 减与数学中的一样, 其中需要说明的是除法以及取模运算. C 语言中的除法运算, 不同类型的除数和被除数会导致不同类型的运算结果. 一种情况是, 当除数和被除数都是整数时, 运算结果也是整数. 当不能整除时, 就直接舍弃小数部分, 只保留整数部分. 另一种情况是, 一旦除数和被除数中有一个是小数, 那么运算结果也是小数, 并且是 double 类型的小数. C 语言中的取余运算, 就是求相除后的余数. 取余运算中 % 的两边都必须是整数, 不能出现小数, 否则会报错. 余数可以是正数也可以是负数, 由 % 左边的整数决定: 如果 % 左边是正数, 那么余数也是正数; 如果 % 左边是负数, 那么余数也是负数.
2.2 单目算术运算符
1)- : 取负, 把操作数乘以 - 1
2)++: 自增运算符, 把操作数增加 1
3)--: 自减运算符, 把操作数减少 1
单目运算符中, 只需要一个操作数. 取负操作符将正操作数设置为负数, 负操作数设置为正数. 自增运算符使得变量的值增加 1, 自减运算符使得变量的值减少 1. 比如:
i++;
j--;
变量 i 的值增加 1, 变量 j 的值减少 1, 相当于:
- i = i+1;
- j = j-1;
自增运算符和自减运算符的运算对象只能是变量, 不能是常量或者表达式, 否则将会报错. 比如:
- 1++;// 报错
- --(i+1);// 报错
自增运算符和自减运算符分为两种方式: 一种是在变量前面, 称为前缀模式; 一种是在变量后面, 称为后缀模式. 下面介绍一下两种方式的区别:
前缀模式, 先执行变量的自增或者自减操作, 再将得到的结果参与表达式运算.
后缀模式, 先将变量参与表达式运算, 再执行变量的自增或者自减操作.
前缀模式, 也被理解为先运算后赋值, 比如:
i = 1;
j = ++i;
执行上面语句, i 和 j 的值都是 2. 先是变量 i 自增, i 的值变为 2, 再将结果 2 赋值给 j.
后缀模式, 也被理解为先赋值后运算, 比如:
i = 1;
j = i++;
执行上面语句, i 的值是 2,j 的值是 1. 先是变量 i 赋值给 j, 这个时候 i 还没有自增操作, i 的值还是 1, 所以 j 的值是 1. 赋值后, i 再自增, i 的值变为 2.
[实例 6.2] 前缀模式和后缀模式
- #include <stdio.h>
- int main()
- {
- int a = 10;
- int c;
- c = a++;
- printf("先赋值后运算:\n");
- printf("c 的值是 %d\n", c);
- printf("a 的值是 %d\n", a);
- a = 10;// 重新赋值为 10
- c = a--;
- printf("c 的值是 %d\n", c);
- printf("a 的值是 %d\n", a);
- printf("先运算后赋值:\n");
- a = 10;
- c = ++a;
- printf("c 的值是 %d\n", c);
- printf("a 的值是 %d\n", a);
- a = 10;
- c = --a;
- printf("c 的值是 %d\n", c);
- printf("a 的值是 %d\n", a);
- }
执行以上程序, 输出结果为:
先赋值后运算:
c 的值是 10
a 的值是 11
c 的值是 10
a 的值是 9
先运算后赋值:
c 的值是 11
a 的值是 11
c 的值是 9
a 的值是 9
实例解析:
++ 在变量前面和后面是有区别的:++ 在前面叫做前自增. 前自增先进行自增运算, 再进行其他操作.++ 在后面叫做后自增. 后自增先进行其他操作, 再进行自增运算.
对于, c = a++; a 的值不会立马加 1, 而是先把 a 原来的值 (也就是 10) 交给 c, 然后再加 1.a 原来的值为 10, 所以 c 的值也就为 10. 而 a 经过自增, 最终值为 11.
对于, c = a--; a 的值不会立马减 1, 而是先把 a 原来的值 (也就是 10) 交给 c, 然后再减 1.a 原来的值为 10, 所以 c 的值也就为 10. 而 a 经过自减, 最终值为 9.
对于, c = ++a, 先执行 ++a, 结果为 11, 再将 11 赋值给 c, 所以 c 的最终值为 11. 而 a 经过自增, 最终的值也为 11.
对于, c = --a, 先执行 --a, 结果为 9, 再将 9 赋值给 c, 所以 c 的最终值为 9. 而 a 经过自减, 最终的值也为 9.
2.3 算术运算符的优先级
在数学运算中, 运算符是有优先级的, C 语言中的运算符也有优先级. 算术运算符的优先级: 单目算术运算符(-,++,--)> 乘号(*), 除号(/), 求模(%)> 加号(+), 减号(-). 比如:
int a = 1 + 2 * 3;
根据优先级, 将会先计算 2 * 3, 再将得到的结果 6 和 1 相加, 得到 7, 赋值给变量 a.
当表达式中有多个相同优先级的运算符时, 按照从左到右的顺序运算. 比如:
int a = 1 + 2 * 3 / 3;
乘号 (*), 除号(/) 优先级相同, 按照从左到右的顺序运算, 先计算 2 * 3, 将结果 6 / 3, 得到结果 2 和 1 相加, 得到 3, 赋值给变量 a.
如果需要改变表达式的运算顺序, 我们还可以使用圆括号. 比如:
int a = (1 + 2) * 3 / 3;
先计算圆括号内的 1 + 2, 得到的结果 3 再去运算, 最后得到 3, 赋值给变量 a.
3. 关系运算符
1)==: 检查两个操作数的值是否相等, 如果相等则条件为真.
2)!=: 检查两个操作数的值是否相等, 如果不相等则条件为真.
3)> : 检查左操作数的值是否大于右操作数的值, 如果是则条件为真.
4)<: 检查左操作数的值是否小于右操作数的值, 如果是则条件为真.
5)>=: 检查左操作数的值是否大于或等于右操作数的值, 如果是则条件为真.
6)<=: 检查左操作数的值是否小于或等于右操作数的值, 如果是则条件为真.
关系运算符只有两种结果: true 或者 false.true 代表条件为真, false 代表条件为假. C 语言中, 一般非 0 值代表 true,0 代表 false. 比如:
- 1 == 2;// 条件为假, 结果是 false.
- 1 != 2;// 条件为真, 结果是 true.
- 1 > 2;// 条件为假, 结果是 false.
- 1 < 2;// 条件为真, 结果是 true.
- 1 >= 2;// 条件为假, 结果是 false.
- 1 <= 2;// 条件为真, 结果是 true.
4. 逻辑运算符
1)! : 单目运算符, 称为逻辑非运算符. 用来逆转操作数的逻辑状态. 如果条件为真则逻辑非运算符将使其为假.
2)&&: 双目运算符, 称为逻辑与运算符. 如果两个操作数都非零, 则条件为真.
3)||: 双目运算符, 称为逻辑或运算符. 如果两个操作数中有任意一个非零, 则条件为真.
逻辑运算符与数学上有相同之处. 逻辑运算符和关系运算符一样, 也只有两种结果: true 或者 false. 逻辑运算符可以将多个关系表达式的结果合并起来. 我们要判断变量 i 是否在 0 和 100 之间, 不能直接表示成: 0 =<i =< 100. 需要使用逻辑运算符来表示, 比如:
i >= 0 && i =< 100
如果变量 i 在 0 和 100 之间, 则结果为 true, 否则为 false.
逻辑运算符也是有优先级的, 逻辑非运算符 (!)> 逻辑与运算符 (&&)> 逻辑或运算符(||).
[实例 6.3] 逻辑运算符
- #include <stdio.h>
- int main()
- {
- int a = 0, b = 1, c = 2, d = 3;
- printf("!a = %d\n", !a);
- printf("!b = %d\n", !b);
- printf("a&&b = %d\n", a && b);
- printf("a||b = %d\n", a || b);
- printf("a&&b||c&&d = %d\n", a&&b || c&&d);
- printf("a&&!b||c&&d = %d\n", a && !b || c&&d);
- return 0;
- }
执行以上程序, 输出结果为:
- !a = 1
- !b = 0
- a&&b = 0
- a||b = 1
- a&&b||c&&d = 1
- a&&!b||c&&d = 1
实例解析:
在使用 printf()函数以整数形式输出逻辑结果时, 1 代表 true,0 代表 false.!a 代表 a 取反, 0 取反结果为 true, 所以输出 1. 那么! b 取反则输出 0.a&&b 代表 a 和 b 做与运算, 0 和 1 做与运算, 结果为 false, 则输出 0.a||b 代表 a 和 b 做或运算, 0 和 1 做或运算, 结果为 true, 则输出 1.a&&b || c&&d, 根据优先级, 我们先运算 a&&b 和 c&&d, 得到的结果是 false 和 true,false 和 true 进行或运算, 结果还是 true, 所以输出 1.a && !b || c&&d, 根据优先级, 我们先运算! b, 得到的结果是 false, 然后运算 a 和 false 以及 c&&d, 得到的结果是, false 和 true 进行或运算, 结果是 true, 所以输出 1.
5. 位运算符
位运算符作用于位, 并逐位执行操作, 也就是二进制的运算.
1)~ : 单目运算符, 按二进制位进行取反运算.
2)& : 双目运算符, 按二进制位进行与运算.
3)| : 双目运算符, 按二进制位进行或运算.
4)^ : 双目运算符, 按二进制位进行异或运算.
5)<<: 双目运算符, 二进制左移运算符.
6)>>: 双目运算符, 二进制右移运算符.
位运算符不能用于 float,double 等类型, 只能用于整数类型.
[实例 6.4] 位运算符
- #include <stdio.h>
- int main()
- {
- int a = 50; /* 50 = 0011 0010 */
- int b = 19; /* 19 = 0001 0011 */
- int c = 0;
- c = a & b; /* 18 = 0001 0010 */
- printf("a & b 的值是 %d\n", c);
- c = a | b; /* 51 = 0011 0011 */
- printf("a | b 的值是 %d\n", c);
- c = a ^ b; /* 33 = 0010 0001 */
- printf("a ^ b 的值是 %d\n", c);
- c = ~a; /* -51 = 1100 1100 */
- printf("~a 的值是 %d\n", c);
- c = a << 2; /* 200 = 1100 1000 */
- printf("a << 2 的值是 %d\n", c);
- c = a >> 2; /* 12 = 0000 1100 */
- printf("a >> 2 的值是 %d\n", c);
- return 0;
- }
执行以上程序, 输出结果为:
a & b 的值是 18
a | b 的值是 51
a ^ b 的值是 33
~a 的值是 -51
a <<2 的值是 200
a>> 2 的值是 12
实例解析:
A = 50,B = 19, 现在以二进制格式表示, 它们如下所示:
- A = 0011 0010
- B = 0001 0011
然后按照二进制位进行相应运算得到结果值. 二进制左移运算符, 运算对象的各二进制位全部左移若干位, 左边的二进制位丢弃, 右边补 0; 二进制右移运算符, 运算对象的的各二进制位全部右移若干位, 正数左补 0, 负数左补 1, 右边丢弃.
6. 赋值运算符
C 语言中, 可以将赋值运算符分为两类: 简单赋值运算符和复合赋值运算符.
2.1 简单赋值运算符
简单赋值运算符就是 "=", 一般语法格式:
变量 = 表达式;
赋值运算符 "=" 和数学表达式中的等号 "=" 的意义是不同的. 前面我们就多次用到了赋值运算符 "="."=" 的作用是把结果赋值给变量, 所以赋值运算符的左边必须是变量, 赋值运算符从右向左的顺序计算. 比如:
a = b = 1;
以上语句, 先将 1 赋值给 b, 再将变量 b 赋值给变量 a.
赋值也是一种运算, 我们可以放在表达式中. 比如:
a = (b = 1) + (c = 2);
以上语句, 先将 1 赋值给 b 和将 2 赋值给 c, 再将变量 b 和 c 的值相加, 最后得到的结果 3 赋值给 a.
2.2 复合赋值运算符
1)+=: 加赋值, a += b 等价于 a = a + b.
2)-=: 减赋值, a -= b 等价于 a = a - b.
3)*=: 乘赋值, a *= b 等价于 a = a * b.
4)/=: 除赋值, a /= b 等价于 a = a / b.
5)%=: 取余赋值, a %= b 等价于 a = a % b.
6)&=: 位与赋值, a &= b 等价于 a = a & b.
7)|=: 位或赋值, a |= b 等价于 a = a | b.
8)^=: 位异或赋值, a ^= b 等价于 a = a ^ b.
9)<<=: 位左移赋值, a <<= b 等价于 a = a <<b.
10)>>=: 位右移赋值, a>>= b 等价于 a = a>> b.
赋值运算的规则是将左侧的变量和右侧的操作数进行运算, 然后再将得到的结果赋值给左侧的变量. 比如:
a += 1;
等价于:
a = a + 1;
7. 条件运算符
条件运算的一般语法格式如下:
表达式 1? 表达式 2: 表达式 3
从语法格式中, 我们可以看出, 这是一个三目运算. 通过问号和冒号将三个表达式连接起来. 整个表达式的运算过程: 先计算表达式 1 的值, 如果它的值为 true(非 0 值), 则将表达式 2 的值返回; 如果它的值为 false(0 值), 则将表达式 3 的值返回.
[实例 6.5] 条件运算符, 比较两个数的最大值
- #include <stdio.h>
- int main()
- {
- int a, b, max;
- printf("Please input a:");
- scanf("%d", &a);
- printf("Please input b:");
- scanf("%d", &b);
- max = a > b ? a : b;
- printf("max is:%d\n",max);
- return 0;
- }
执行以上程序, 输出结果为:
- Please input a:5
- Please input b:10
- max is:10
实例解析:
先计算 a> b, 值为 false, 将 b 的值返回, 结果为 10.
8. 其他运算符
1)sizeof: 长度运算符
2)& : 取地址运算符
3)[]: 下标运算符
4)* : 指针运算符
5). : 结构体成员运算符
6)->: 指向结构体成员运算符
这里介绍一下 sizeof 长度运算符, 其余的在后面会讲到. sizeof 运算符返回一个数据类型, 变量, 常量所占的字节长度, 可以使用 printf()函数来输出.
[实例 6.6] sizeof 长度运算符
- #include <stdio.h>
- int main()
- {
- int a = 100;
- printf("int 类型字节长度:%d\n", sizeof(int));
- printf("变量 a 字节长度:%d\n", sizeof(a));
- printf("常量 100 字节长度:%d\n", sizeof(100));
- return 0;
- }
执行以上程序, 输出结果为:
int 类型字节长度: 4
变量 a 字节长度: 4
常量 100 字节长度: 4
实例解析:
可以看到结果都是 4, 这是因为 int 类型的字节长度是 4, 变量 a 的字节长度也就是 4, 存储的常量 100 自然也就是 4.
9. 总结
总结一下, 本节内容主要介绍了 C 语言的算术运算符, 关系运算符, 逻辑运算符, 位运算符, 赋值运算符, 条件运算符和其他运算符.
10. 练习
6-1 下面程序的输出结果是什么?
- #include <stdio.h>
- int main()
- {
- int a = 12, b = 1;
- int c = a - (b--);
- int d = (++a) - (--b);
- printf("c=%d, d=%d\n", c, d);
- return 0;
- }
6-2 判断下面结果是 true 还是 flase:
- 1 > 1 && 3 < 4 || 4 > 5 && 2 > 1 && 9 > 8 || 7 < 6
- ! 2 > 1 and 3 < 4 or 4 > 5 and 2 > 1 and 9 > 8 or 7 < 6
6-3 编写一个程序, 比较三个数的最大值.
可以在评论中, 写下你们的练习答案.
之后的文章会给大家带来更精彩的内容
来源: https://www.cnblogs.com/cxyjczs/p/10234829.html