目录
一、运算符
一、自增自减运算符
二、位运算符
三、关系运算符
注意事项
四、条件运算符
注意事项
五、逻辑运算符
注意事项:
六、逗号运算符
概述
注意事项:
七、小结
运算符优先级和结合性一览表
运算符 | 描述 | 实例 |
---|---|---|
++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
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
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
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);
return 0;
}
1 注意赋值"="与关于等于"=="的区别
a=1;//将1赋值给a变量 a==1;//判断a是否等于1
2 结合性自左向右
1<3<2;//值为1,计算过程:(1<3)<2 <==> 1<2 <==> 1
#include
int main()
{
int a=1,b=2,c=3,d=0;
printf("a
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
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
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
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
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
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
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
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。