我们前面在学习分支语句时,会看到一些运算符,不知道具体含义是什么?
那么本文将正式讲解C语言的运算符
运算符的基本概念和分类
运算符的概念
C语言中的运算符是指用于执行各种数学或逻辑操作的符号,例如 1 + 1 中的“+”,就是一个运算符
运算符的分类
1.算数运算符
2.关系运算符
3.赋值运算符
4.位运算符
5.逻辑运算符
6.单目运算符
7.条件运算符
8.逗号运算符(逗号表达式)
运算符
1.算数运算符
运算符 | 作用 |
+ | 两个操作数做加法 |
- | 两个操作数做减法 |
* | 两个操作数做乘法 |
/ | 两个操作数做除法 |
% | 取模,两个整型操作数相除并取余数(一定是整型) |
演示如下
#include<stdio.h> int main() { int x = 15; int y = 10; int z; z = x + y;// 15 + 10 = 25 printf("z = x + y = %d\n", z); z = x - y;// 15 - 10 = 5 printf("z = x - y = %d\n", z); z = x * y;// 15 * 10 = 150 printf("z = x * y = %d\n", z); z = x / y;// 15 / 10 = 1 printf("z = x / y = %d\n", z); z = x % y;// 15 % 10 = 5 printf("z = x %% y = %d\n", z); }
%的操作数如果不是整型
所以C语言明确规定%的操作数必须是整型,如果不是就一定会报错,希望大家在后续的代码练习的时候可以注意这一点
2.关系运算符
运算符 | 作用 |
< | 判断A小于B |
> | 判断A大于B |
<= | 判断A小于等于B |
>= | 判断A大于等于B |
== | 判断A等于B |
!= | 判断A不等于B |
演示如下
#include<stdio.h> int main() { int x = 15; int y = 10; int z = 10; printf("操作符>\n"); if (x > y) printf("x > y\n"); else//条件是(x <= y) printf("x <= y\n"); printf("\n操作符<\n"); if (y < x) printf("y < x\n"); else//(y >= x) printf("y >= x\n"); printf("\n操作符<=\n"); if (y <= z) printf("y <= z\n"); else//(y > z) printf("y > z\n"); printf("\n操作符>=\n"); if (y >= z) printf("y >= z\n"); else//(y < z) printf("y < z\n"); printf("\n操作符==\n"); if (y == z) printf("y == z\n"); else//(y != z) printf("y != z\n"); printf("\n操作符!=\n"); if (x != y) printf("x != y\n"); else//(x == y) printf("x == y\n"); return 0; }
3.赋值运算符
运算符 | 作用 |
= | x = y; 将y值赋给x |
+= | x += y; x = x+y |
-= | x -= y; x = x - y |
*= | x *= y; x = x * y |
/= | x /= y; x = x / y |
%= | x %= y; x = x % y |
&= | x &= y; x = x & y |
|= | x |= y; x = x | y |
^= | x ^= y; x = x ^ y |
<<= | x <<= y; x = << y |
>>= | x >>= y; x = >> y |
" & ", " | ", " ^ ", " <<", " >> " 这是位运算符,我会在位运算符上讲解
演示如下
int main() { int x = 5;//这就是" = "的作用,将 5 赋给 x,使得 x 的值为 5 int y = 3; x += y;//x = x + y printf("x的值为%d\n", x);//8 x = 5; x -= y;//x = x - y printf("x的值为%d\n", x);//2 x = 5; x *= y;//x * y printf("x的值为%d\n", x);//15 x = 5; x /= y; printf("x的值为%d\n", x);//1 x = 5; x %= y; printf("x的值为%d\n", x);//2 x = 5; x &= y; printf("x的值为%d\n", x);//1 x = 5; x |= y; printf("x的值为%d\n", x);//7 x = 5; x ^= y; printf("x的值为%d\n", x);//6 x = 5; x <<= y;//x = x << y(3) x往左移3位 printf("x的值为%d\n", x);//40 x = 5; x >>= y;//x = x >> y(3) x往右移3位 printf("x的值为%d\n", x);//0 return 0; }
4.位运算符
运算符 | 作用 |
<< | 将一个操作数的二进制位往左移(左边的二进制位丢弃,右边补0) |
>> | 将一个操作数的二进制位往右移(右边的二进制位丢弃,如果为正数,左边补0,负数补1) |
& | 按位与,两个操作数对应的二进制位如果都是1,则取1 ,其余都为0 |
| | 按位或,两个操作数对应的二进制位如果有1个1,则取1 ,都是0才取0 |
^ | 按位异或,两个操作数对应的二进制位如果相同取0,不同取1 |
图画说明
<<和>>
二进制是从右往左算的,第一位代表2的0次方,第二位代表2的1次方,后面以此类推
代码演示
#include<stdio.h> int main() { int i = 5; printf("%d\n", i << 1); printf("%d\n", i >> 1); return 0; }
& 和 | 和 ^
代码演示
int main() { int x = 3; int y = 5; printf("%d\n", x & y); printf("%d\n", x | y); printf("%d\n", x ^ y); return 0; }
5. 逻辑运算符
运算符 | 作用 |
! | 逻辑非,当操作数为假时,表达真;当为真时,表达假 |
&& | 逻辑与,当两个操作数都为真时,表达真(全真则真,一假为假) |
|| | 逻辑或,当两个操作数都为假时,表达假(全假则假,一真为真) |
演示如下
int main() { int x = 5; int y = 3; // ! if (!x)//此时x原来是真,!x将x变为了假,if语句不执行 printf("111\n"); x = 0; if(!x)//此时x为假,!x将x变为了真,if语句执行 printf("222\n"); x = 5; // && if (x > 0 && y > 4)//x > 0为真,y > 4为假,if不执行 printf("333\n"); if(x > 0 && y > 0)//x > 0为真, y > 0为真,if执行 printf("444\n"); // || if (x < 0 || y > 0)//x < 0为假,y > 0为真,if语句执行 printf("555\n"); if(x < 0 || y < 0)//x < 0为假, y < 0为假,if语句不执行 printf("666\n"); return 0;
短路
C语言逻辑运算符有一个特点,它总是先对左边求值,再向右边求值,这个顺序是绝对的
如果左边求出来的值满足逻辑运算符的条件,那么逻辑运算符就不会再向右边求值。这种情况就是“短路”。
int main() { int x = 5; int y = 6; if (x > 6 && y > 5) printf("111"); return 0; }
就比如这段代码
表达式&&左边的操作数是 x > 6 , 右边的操作数是 y > 5,当左操作数x > 6的结果为0时,就算不判断右操作数y > 5,这整个表达式也为0(假)
所以
对于&&运算符来说,左边的操作数求出0(假)时,就不会执行右边的操作数了。
那么 || 运算符是怎样的呢,我们修改下前面的代码
int main() { int x = 5; int y = 6; if (x > 4 || y > 7) printf("111"); return 0; }
左边的 x > 4求出来为1,那么右边的 y > 7就不会执行,这个表达式的结果为1(真)
所以
对于 || 运算符来说,左边的操作数求出1(真)时,就不会执行右边的操作数了。
6.单目运算符
运算符 | 作用 |
- | 负号,表示负数 |
++ | 自加 |
-- | 自减 |
* | 取(指针)值 |
& | 取地址(操作数) |
! | 与逻辑运算符一样 |
(类型) | 强制类型转换 |
sizeof | 求长度(操作数) |
~ | 按位取反 |
演示如下
#include<stdio.h> #include<string.h> int main() { int i = 5; printf("%d\n", -i); printf("%d\n", i++);//后置++, --> 先用再加(先打印原来的,再加1) printf("%d\n", i); printf("%d\n", ++i);//前置++, -->先加再用(先加1,再打印) i = 5; printf("========\n"); printf("%d\n", i--);//后置--,--> 先用再减(先打印原来的,再减1) printf("%d\n", i); printf("%d\n", --i);//前置--, -->先减再用(先减1,再打印) i = 5; printf("========\n"); printf("%p\n", &i);//%p是地址占位符 printf("========\n"); printf("%f\n", (float)i);//强制将int i转换成float i printf("========\n"); printf("%d\n", sizeof(i));//求 int i的内存大小 printf("========\n"); printf("%d", ~i); return 0; }
7.条件运算符(三目运算符)
运算符 | 作用 |
? : | 表达式1?表达式2:表达式3 |
这是C语言唯一的三目运算符
表达式1?表达式2:表达式3这是什么意思呢?
表达式1为判断部分,如果判断为真,返回表达式2,如果为假。返回表达式3
演示如下
int main() { int i = 5; int j = 3; int max = i > j ? i: j;//如果i > j 为真,max = i,如果为假,max = j printf("%d", max); }
8.逗号运算符(逗号表达式)
运算符 | 作用 |
, | 分隔两个或多个表达式,从左向右依次计算每个表达式,并返回最后一个表达式的值。 |
如果不加()就不是逗号表达式里,返回的结果就不一样了
演示如下
int main() { int a = 0; int b = 2; int c = 3; int ret1 = (++a, ++b, ++c);//返回++c的值(4),但是++a和++b也是经过了运算的 int ret2 = ++a,++b,++c;//在vs中,这样写会直接报错 //所以这里只会返回++a的值(2) printf("%d\n", ret1);//4 printf("%d\n", ret2);//2 return 0; }
运算符的优先级
优先级 | 运算符 | 描述 |
1 | () [] . -> | 后缀 |
2 | ! ~ -(负号) ++ -- &(取地址) *(指针) sizeof | 单目 |
3 | (类型) | 类型转换 |
4 | * / % | 乘除 |
5 | + - | 加减 |
6 | >> << | 移位 |
7 | > >= < <= | 大小关系 |
8 | == != | 相等/不相等 |
9 | & | 按位与 |
10 | ^ | 按位异或 |
11 | | | 按位或 |
12 | && | 逻辑与 |
13 | || | 逻辑或 |
14 | ?: | 三目 |
15 | = += -= *= /= %= |= ^= &= >>= <<= | 赋值 |
16 | , | 逗号 |