目录
一、运算符
一、自增自减运算符
二、位运算符
三、关系运算符
注意事项
四、条件运算符
注意事项
五、逻辑运算符
注意事项:
六、逗号运算符
概述
注意事项:
七、小结
运算符优先级和结合性一览表
一、运算符
一、自增自减运算符
运算符 | 描述 | 实例 |
---|---|---|
++a | 前自增运算符 | b=++a;等价于a=a+1,b=a; |
a++ | 后自增运算符 | b=a++;等价于b=a,a=a+1; |
--a | 前自减运算符 | b=--a;等价于a=a-1,b=a; |
a-- | 后自减运算符 | b=a--;等价于b=a,a=a-1; |
#include<stdio.h>
int main()
{
int n=10,m=10;
printf("%d\n",(m++)+(m--)+(++m)); // 10+10+11
printf("%d\n",(++n)+(n++)+(n--)); //系统从左向右执行,执行完n=++n=11了,所以是11+11+11
}
二、位运算符
运算符 | 描述 | 规则 |
---|---|---|
& | 按位与操作,按二进制位进行"与"运算。 | 0&0=0; 0&1=0; 1&0=0; 1&1=1; |
| | 按位或运算符,按二进制位进行"或"运算。 | 0|0=0; 0|1=1; 1|0=1; 1|1=1; |
^ | 异或运算符,按二进制位进行"异或"运算。 | 0^0=0; 0^1=1; 1^0=1; 1^1=0; |
~ | 取反运算符,按二进制位进行"取反"运算。 | ~1=0; ~0=1; |
<< | 二进制左移运算符。将一个运算对象的各二进制位全部左移若干位(左边的二进制位丢弃,右边补0)。 | 11<< 2 得到1100 |
>> | 二进制右移运算符。将一个数的各二进制位全部右移若干位,正数左补0,负数左补1,右边丢弃。 | 1011>>2得到10 |
#include<stdio.h>
int main()
{
int a=60,b=13,c=0;
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;
printf("a&b的值是:%d\n",c);
c=a<<2;
printf("a&b的值是:%d\n",c);
c=a>>2;
printf("a&b的值是:%d\n",c);
}
三、关系运算符
1. C语言的逻辑值
关系表达式和逻辑表达式的运算结果是一个逻辑值。
C语言没有专门的“逻辑值",用非0表示“真”,用0表示“假”
算符 | 描述 | 优先级 | 结合性 | 操作数 |
---|---|---|---|---|
> | 大于 | 6 | 自左向右 | 双目运算符 |
< | 小于 | 6 | 自左向右 | 双目运算符 |
>= | 大于等于 | 6 | 自左向右 | 双目运算符 |
<= | 小于等于 | 6 | 自左向右 | 双目运算符 |
== | 相等 | 7 | 自左向右 | 双目运算符 |
!= | 不相等 | 7 | 自左向右 | 双目运算符 |
#include<stdio.h>
int main()
{
int a=1,b=2;
printf("a==b结果为%d\n",a==b);
printf("a!=b结果为%d\n",a!=b);
printf("a>b结果为%d\n",a>b);
printf("a<b结果为%d\n",a<b);
printf("a>=b结果为%d\n",a>=b);
printf("a<=b结果为%d\n",a<=b);
return 0;
}
注意事项
1 注意赋值"="与关于等于"=="的区别
a=1;//将1赋值给a变量 a==1;//判断a是否等于1
2 结合性自左向右
1<3<2;//值为1,计算过程:(1<3)<2 <==> 1<2 <==> 1
#include<stdio.h>
int main()
{
int a=1,b=2,c=3,d=0;
printf("a<c<b结果为%d\n",a<c<b); //相当于(a<c)<b;(a<c)为真1相当于1<b,1<2为真
printf("a<c<d结果为%d\n",a<c<d);
}
3 优先级
3==2>=0;//值为0,由于>=的优先级高于==,因此等价于3==(2>=0) 1+2>5-4;//值为1,由于算数运算符优先级高于关系运算符,因此等价于(1+2)>(5-4) a=1==3<=2;//a值为0,赋值运算符优先级低于关系运算符,等价于a=(1==(3<=2));
四、条件运算符
条件表达式的一般形式为:
表达式1 ? 表达式2 : 表达式3;
条件运算符的执行:表达式1结果为非零(真),则采用表达式2的值,否则采用表达式3的值。
优先级:13级,高于赋值运算符、逗号运算符。
结合性:自右向左
比较两个数之间的大小
#include<stdio.h>
int main()
{
int a,b;
printf("请输入两个数:\n");
scanf("%d%d",&a,&b);
printf("两数的较大者为:%d\n",a>b?a:b);
}
注意事项
结合性自右向左
a>b ? a : c>d ? c : d; 等价于 a>b ? a : (c>d ? c : d);
优先级仅高于赋值及逗号运算符
a>b?a+1:b-1; 等价于 a>b?(a+1):(b-1);
比较数字大小
#include<stdio.h>
int main()
{
int a,b,c,d;
printf("请输入四个数:\n");
scanf("%d%d%d%d",&a,&b,&c,&d);
printf("两数的较大者为:%d\n",a>b?a:b); //比较a、b
printf("三数的较大者为:%d\n",a>b?a:(c>d?c:d)); //比较a、c、d
printf("三数的较大者为:%d\n",a>b?a:(b>c?b:c)); //比较a、b、c
}
五、逻辑运算符
运算符 | 描述 | 规则 |
---|---|---|
&& | 逻辑与运算符。 | 如果两个操作数都非零(真),则结果为真。 |
|| | 逻辑或运算符。 | 如果两个操作数中有任意一个非零(真),则结果为真。 |
! | 逻辑非运算符。 | 一个操作数为非零(真),则结果为假。若操作数为零(假),结果为真。 |
1.运算符&&和I为双目运算符
运算符!为单目运算符,出现在运算对象的左边。,
2.结合性
自左向右
3.优先级
优先级次序是:!级别最高,&&次之,|最低。
逻辑运算符与赋值运算符、算术运算符、关系运算符之
间从高到低的运算优先次序是:
! >算术运算符>关系运算符>&&>I>赋值运算符
a>b&&x>y
等价于(a>b) && (x>y)
与运算、或运算的短路现象
(1) a&&b运算:当a为假时,a&&b确定为假,此时b不再计算。
(2) al|lb运算:当a为真时,al |b确定为真,此时b不再计算。
题目一:
从键盘输入一个整数,如果该数既能被3整除又能被5整除,输出“yes”;否则输出“no”
#include<stdio.h>
int main()
{
int a;
printf("请输入一个整数a:");
scanf("%d",&a);
if(a%3==0&&a%5==0)
printf("yes");
if(a%3!=0|a%5!=0)
printf("no");
}
题目二:
判断年份是否为闰年
闰年计算:能被4整除,不能被100整除,或者能被400整除
方法一:
#include<stdio.h>
int main()
{
int a;
printf("请输入一个年份:");
scanf("%d",&a);
if((a%4==0&&a%100!=0)||a%400==0)
printf("今年是闰年!");
if(a%400!=0)
printf("今年不是闰年!");
}
方法二:
#include<stdio.h>
int main()
{
int a,b; //a输入的年份,b真假
printf("请输入一个年份:");
scanf("%d",&a);
b=a%4==0&&a%100!=0||a%400==0;
printf("%d是否为闰年:%c\n",a,b?'Y':'N');
return 0;
}
注意事项:
注意逻辑运算符与位运算符的区别
逻辑运算符 与&& 或|| 非! 位运算符 与& 或| 非~
注意运算符的优先级 !>算数>关系>&&>||
1&&0||!1&&1 等价于 (1&&0)||((!1)&&1) a+b>c&&d 等价于 ((a+b)>c)&&d
注意运算规则(短路)
#include<stdio.h>
int main()
{
int a=1;
int b=0;
printf("%d\n",a||(b=1));
printf("%d%d\n",a,b);
}
结果为
1 1 0
b的值没有发生变化,因为a||(b=1)运算中,a为真,则不再进行计算
六、逗号运算符
概述
逗号运算符是以逗号为分隔符的列表中最后一个表达式的值。
逗号表达式的一般形式为:
表达式1,表达式2,表达式3,......表达式n
执行:顺序执行表达式1,表达式2,.....表达式n.最右边的那个表达式的值将作为整个逗号表达式的值。
运算符 | 描述 | 操作数 | 优先级 | 结合性 |
---|---|---|---|---|
, | 逗号运算符 | 双目运算符 | 15级(最低) | 自左向右 |
题目一:
#include<stdio.h>
int main()
{
int i=1, j;
j = (i++, i + 100, 999 +i);
printf("%d %d\n",i,j);
return 0;
}
注意事项:
优先级最低,低于赋值运算符
如下逗号表达式
a = 3 * 5, a * 4
对该表达式,可能会有两种解读。
一种为 a=(3*5,a*4); 一种为(a=3*5),(a*4);
由于赋值运算符的优先级高于逗号运算符的优先级,因此应该首先求解a = 3 * 5,然后再求解a*4,得60.
七、小结
运算符优先级和结合性一览表
优先级 | 运算符 | 名称或含义 | 使用形式 | 结合方向 | 说明 |
---|---|---|---|---|---|
1 | [] | 数组下标 | 数组名[常量表达式] | 左到右 | |
() | 圆括号 | (表达式) | |||
. | 成员选择(对象) | 对象.成员名 | |||
-> | 成员选择(指针) | 对象指针->成员名 | |||
2 | - | 负号运算符 | -表达式 | 右到左 | 单目运算符 |
(类型) | 强制类型转换 | (数据类型)表达式 | |||
++ | 自增运算符 | ++变量名 | 单目运算符 | ||
-- | 自减运算符 | --变量名 | 单目运算符 | ||
* | 取值运算符 | *指针变量 | 单目运算符 | ||
& | 取地址运算符 | &变量名 | 单目运算符 | ||
! | 逻辑非运算符 | !表达式 | 单目运算符 | ||
~ | 按位取反运算符 | ~表达式 | 单目运算符 | ||
sizeof | 长度运算符 | sizeof(表达式) | |||
3 | / | 除 | 表达式 / 表达式 | 左到右 | 双目运算符 |
* | 乘 | 表达式*表达式 | 双目运算符 | ||
% | 余数(取模) | 整型表达式%整型表达式 | 双目运算符 | ||
4 | + | 加 | 表达式+表达式 | 左到右 | 双目运算符 |
- | 减 | 表达式-表达式 | 双目运算符 | ||
5 | << | 左移 | 变量<<表达式 | 左到右 | 双目运算符 |
>> | 右移 | 变量>>表达式 | 双目运算符 | ||
6 | > | 大于 | 表达式>表达式 | 左到右 | 双目运算符 |
>= | 大于等于 | 表达式>=表达式 | 双目运算符 | ||
< | 小于 | 表达式<表达式 | 双目运算符 | ||
<= | 小于等于 | 表达式<=表达式 | 双目运算符 | ||
7 | == | 等于 | 表达式==表达式 | 左到右 | 双目运算符 |
!= | 不等于 | 表达式!= 表达式 | 双目运算符 | ||
8 | & | 按位与 | 表达式&表达式 | 左到右 | 双目运算符 |
9 | ^ | 按位异或 | 表达式^表达式 | 左到右 | 双目运算符 |
10 | | | 按位或 | 表达式|表达式 | 左到右 | 双目运算符 |
11 | && | 逻辑与 | 表达式&&表达式 | 左到右 | 双目运算符 |
12 | || | 逻辑或 | 表达式||表达式 | 左到右 | 双目运算符 |
13 | ?: | 条件运算符 | 表达式1? 表达式2: 表达式3 | 右到左 | 三目运算符 |
14 | = | 赋值运算符 | 变量=表达式 | 右到左 | |
/= | 除后赋值 | 变量/=表达式 | |||
*= | 乘后赋值 | 变量*=表达式 | |||
%= | 取模后赋值 | 变量%=表达式 | |||
+= | 加后赋值 | 变量+=表达式 | |||
-= | 减后赋值 | 变量-=表达式 | |||
<<= | 左移后赋值 | 变量<<=表达式 | |||
>>= | 右移后赋值 | 变量>>=表达式 | |||
&= | 按位与后赋值 | 变量&=表达式 | |||
^= | 按位异或后赋值 | 变量^=表达式 | |||
|= | 按位或后赋值 | 变量|=表达式 | |||
15 | , | 逗号运算符 | 表达式,表达式,… | 左到右 |
注意事项:
关系运算的注意事项
(1) 注意赋值"="与关于等于"=="的区别
a=1; //将1赋值给a变量
a== 1://判断a是否等于1
(2) 结合性自左向右
1<3<2:;//值为1,计算过程: (1<3)<2<==> 1<2 <==> 1
(3) 优先级
3==2>=0;//值为0,由于>=的优先级高于==,因此等价于3== (2>=0)
1+2>5-4://值为1,由于算数运算符优先级高于关系运算符,因此等价于
(1+2)>(5-4)
a=1==3< =2://a值为0,赋值运算符优先级低于关系运算符
等价于a=(1==(3<=2));
(4)当关系运算符两边值的类型不一致时
系统将自动按类型转换规则转换然后进行比较。
(5)避免判断浮点数之间是否相等
若x和y都是浮点数,应当避免使用x==y这样的关系表达式,因为浮点数在内存
中是有误差的,不可能精确相等,这将导致关系表达式x==y的值总是为0。