文章目录
- 1、表达式组成
- 1、运算符
- 2、表达式的分类
- 1、算数运算符
- 1、自增运算符和自减运算
- 2、取余运算(%)
- 3、除法运算(/)
- 4、案例
- 2、关系运算符
- 3、逻辑运算符
- 4、条件运算符(三目运算符)
- 1、案例
- 5、赋值运算(=)
- 1、赋值类型转换
- 2、复合赋值运算
- 6、逗号运算
- 7、取地址运算(&)
- 8、计算变量占用几个字节(sizeof)
- 9、位运算(二进制运算)
- 1、按位取反
- 2、按位与运算(&)
- 3、按位或运算(|)
- 4、按位异或运算(^)
- 5、左移位运算(<<)
- 6、右移位运算(>>)
- 3、运算的优先级与结合性
1、表达式组成
1、运算符
-
根据运算符的操作个数分为单目,双目,三目
-
a++ 单目运算
-
a+b 双目运算
-
?表1;表2 三目运算
2、表达式的分类
1、算数运算符
1、自增运算符和自减运算
-
a++ ++a,自增1
-
++i 先增加1,然后再使用
-
i++ 先使用i的值,然后增加+1,先用,后使用
-
跟的是一个变量,不能是表达式,常量
-
–i,++i都用完之后才能加,也就是语句
#include<stdio.h>
void main()
{int a = 1 ,b=2,c;c = ++a*b;printf("%d,%d",c,a);
}# tc版本
# 扫描整个表达式 ,i=1
(++i)+(++i)+(++i)# 所以i=4 ,结果为3*4 = 12# vc版本# 只能先算后面2个表达式# i = 3 3+3+(++i) = 6+4=10# 编译器的不同
#include<stdio.h>
void main()
{int i,j;i=j=5;printf("i++=%d,j--=%d\n",i++,j--);printf("++i=%d,++j=%d\n",++i,--j);printf("i++=%d,j--=%d\n",i++,j--);printf("++i=%d,++j=%d\n",++i,--j);printf("i=%d,j=%d\n",i,j);
}
2、取余运算(%)
-
%要求参与运算的2个量必须是整型,不能有实型(小数),实型数据不能做%运算
-
可以判断是不是偶数
-
正负号取决于被除数
-
5%(-2) = 1 ,(-5)%2 = -1
-
0取余任何数据结果都为0
int a = 10,b;
b = a%3; # %的优先级高于= ,先算右边的,= 的结合性自右向左的,赋值给b
printf("%d",b);
3、除法运算(/)
-
如果有小数参与,得到的就是小数
-
如果均为整数参与运算,得到的就是整数
4、案例
3.5+1/2+56%10345取出个位,十位,百分位
2、关系运算符
-
也就是条件运算
-
关系运算符,低于算数运算符,高于逻辑运算
-
1代表的真,0代表的为假
5 > 3 的结果为真,值为13<7<5# 先算从往右算,1<5成立,为真,1
3、逻辑运算符
-
非0代表真,0代表假
-
&& 逻辑与,2边都为真,就为真
-
|| 逻辑或,有一个为真,则为真
-
!逻辑非 为真结果就为假,运算的优先级高于上面的&&,|| ,因为是单目运算符
-
!>&&>|| 低于关系运算符,高于赋值运算符
-
&& 只要表达式的值能够确定,就不在计算下去了
-
|| 可以确定整个表达式的值为假时,剩下的表达式部分边不在计算
#include<stdio.h>
void main()
{int a=3,b=5,c=7,d;d = a >5&&b--||c++;printf("a=%d,b=%d,c=%d,d=%d",a,b,c,d);}# 3581
# 如果能确定值的话,剩下的表达式就不用算了
- 逻辑表达式描述条件
# x是3的倍数x%3==0# x是偶数x%2==0# x是3的倍数并且是偶数(x%3==0)&&(x%2==0)# 三位数x是回文数,121,首尾相等x/100 == x%10# abc为三边,构成等边三角形(a==b)&&(b==c)# 某年是闰年
# 能够被4整除,并且不能被100整除或者可以被400整除((year%4==0)&&(year%100!=0))||(year%400==0)#include<stdio.h>
void main()
{int x,y,z,t;x=y=z=1;t = ++x||++y&&++z;printf("x=%d,y=%d,z=%d,t=%d",x,y,z,t);
}# 先算++x 为真 ,||后面的就不用算了,短路的特性# 因为·单目运算符的优先级高于|| ,所以的话,先算出++x > 0 ,因此后面就不用算了
4、条件运算符(三目运算符)
-
?和;组成
-
三目运算符
-
表达式1?表达式2:表达式3
-
表达式1为真执行表达式2,否则执行表达式3
-
表达式1必须是判断的,有一个真假的值
-
条件运算,优先级高于赋值运算和逗号运算
-
从右往左算
a>b?a:c>d?c:d# 先算右边的再算左边的
a>b?a:(c>d?c:d)
1、案例
- 比较2个数的谁打谁小
a?a:b# 如果a>b输出a# 如果a<b输出b 这个就是求出了最大值
- 求a的绝对值
a>0?a:-a# 如果a>0,就输出a# 如果a<=0,就输出-a,也就是绝对值
- 输入一个字母,以小写的形式输出
# 'A'和'Z'之间的范围,就是大写字母
#include<stdio.h>
void main()
{char ch;scanf("%c",&ch);ch = (65<=ch<97)?ch+32:ch;printf("%c",ch);
}
5、赋值运算(=)
-
右结合性,算右边的
-
= 左边的操作数只能是变量
1、赋值类型转换
-
实型数据赋给整型,舍弃小数部分,不是四舍五入
-
将整型数据赋给单双精度时,数值大小不变,以浮点形式存储
-
字符型数据赋值给整型变量时,由于字符只占一个字节,整形占2个字节,因此字符型数据放在整型变量的低8位中,这样数据就不会发生改变了,高八位补0即可
-
基本整形数据赋给长整型变量时,基本整形数据放在长整型变量低16位中,反之长整型赋给基本整形变量时,只将长整型数据的低16位送给基本整形变量,正数用0补全,负数用1来补全
2、复合赋值运算
-
+=,-=,*=,/= %=
-
变量❤ = 表达式 = 等价于 变量=变量❤表达式
#include<stdio.h>
void main()
{int a = 3;a+=a*=a+1;printf("%d",a);
}# 右结合性
6、逗号运算
-
优先级是最低的
-
从左往右算
-
表达式1,表达式2,表达式3,表达式n 表达式n就是最终的结果
-
自增和自减遇到逗号立刻完成
-
赋值运算高于逗号运算
x=a=3,6*x,6*a,a+x# 最后的结果为6,a与x的结果没有变x=3,x++,x+2;# x++,这个时候x=4,表达式最后的结果为6
# x的值为4
7、取地址运算(&)
- 变量存储在内存中,这个&就能求出这个地址
8、计算变量占用几个字节(sizeof)
#include<stdio.h>
void main()
{printf("%d\n",sizeof(char)); # 占一个字节printf("%d\n",sizeof("qwer")); # 输出5个字节,\0
}
9、位运算(二进制运算)
1、按位取反
-
运算符 ~
-
右结合性
-
将一个二进制按位取反,0变1,1变0
~25
0000000000011001 # 25的二进制1111111111100110 # ~25 先按位取反1000000000011001 # 取反码1000000000011010 # ~25的补码 按位取反后为-26
2、按位与运算(&)
-
都是1就是1,有0就是假
-
1&任何数 都是那个数
0x29&0x37
00101001
0011011100100001 # 得到的结果为0x21
3、按位或运算(|)
- 有一个1就是真
4、按位异或运算(^)
- 相同为0,不同为1
5、左移位运算(<<)
-
对左边的操作进行移位,右边操作数是移动的位数
-
左移的话相当于乘以2^n
-
空出的为补0
15<<2
1111
111100 # 移动之后的为60
6、右移位运算(>>)
- 除以2^n取整
15>>2
1111
11.11 # 后面的11被舍弃了为3
3、运算的优先级与结合性
-
* 是指针运算符,就是单目的
-
如果是乘号,就是双目运算符
-
单目运算符和赋值运算符,从右到左
-
大多数都是从左往右进行计算
-
从左往右看2个运算符,比较几个运算符的优先级
-
当前面的高于后面的,直接算前面一个
-
当后面高于前面的,继续向后比较
-
真就是1,假就是0,看的是结果