运算符
在C语言中我们可以进行一些数学运算,运算符是告诉编译器执行特定的数学或逻辑操作的符号。
C语言中运算符分为:
- 算数运算符:用于各类数值运算。包括加(+)、减(-)、乘(*)、除(/)、求余(或称模运算,%)、自增(++)、自减(–)共七种。
- 关系运算符:用于比较运算。包括大于(>)、小于(<)、等于(==)、 大于等于(>=)、小于等于(<=)和不等于(!=)六种。
- 逻辑运算符:用于逻辑运算。包括与(&&)、或(||)、非(!)三种。
- 赋值运算符:用于赋值运算,分为简单赋值(=)、复合算术赋值(+=,-=,*=,/=,%=)和复合位运算赋值(&=,|=,^=,>>=,<<=)三类共十一种。
- 条件运算符:这是一个三目运算符,用于条件求值(? : )。(唯一一个三目运算符)
- 位运算符:参与运算的量,按二进制位进行运算。包括位与(&)、位或(|)、位非(~)、位异或(^)、左移(<<)、右移(>>)六种。
- 逗号运算符:用于把若干表达式组合成一个表达式(,)。
- 指针运算符:用于取内容(*)和取地址(&)二种运算。
- 求字节数运算符:用于计算数据类型所占的字节数(sizeof)。
- 特殊运算符:有括号(),下标[],成员(→,.)等几种。
优先级
优先级是用来标识运算符在表达式中的运算顺序的,在求解表达式的值的时候,总是先按运算符的优先次序由高到低进行操作。
结合性
当一个运算对象两侧的运算符优先级别相同时,则按运算符的结合性来确定表达式的运算顺序。
运算符的优先级
1、优先级1级
结合方向 左结合(自左至右)
( ) 圆括号
[ ] 下标运算符
-> 指向结构体成员运算符
. 结构体成员运算符 (一个实心圆点)
2、优先级2级
结合方向 右结合(自右至左)单目运算符
! 逻辑非运算符
~ 按位取反运算符
++ 自增运算符
– 自减运算符
-负号运算符
(类型) 类型转换运算符
*指针运算符
& 地址与运算符
sizeof 长度运算符
3、优先级3级
结合方向 左结合 双目运算符
*乘法运算符
/ 除法运算符
% 取余运算符
4、优先级4级
结合方向 左结合 双目运算符
+ 加法运算符
- 减法运算符
5、优先级5级
结合方向 左结合 双目运算符
<< 移运算符
>> 右移运算符
6、优先级6级
结合方向 左结合 双目运算符
<、<=、>、>= 关系运算符
7、优先级7级
结合方向 左结合 双目运算符
== 等于运算符 (判断)
!= 不等于运算符(判断)
8、优先级8级
结合方向 左结合 双目运算符
& 按位与运算符
9、优先级9级
结合方向 左结合 双目运算符
^ 按位异或运算符
10、优先级10级
结合方向 左结合 双目运算符
| 按位或运算符
11、优先级11级
结合方向 左结合 双目运算符
&& 逻辑与运算符
12、优先级12级
结合方向 左结合 双目运算符
|| 逻辑或运算符
13、优先级13级
结合方向 右结合 三目运算符
? : 条件运算符
14、优先级14级
结合方向 右结合 双目运算符
= 赋值运算符
+= 加后赋值运算符 如s+=1表示s=s+1
-= 减后赋值运算符 如s-=1表示s=s-1
*= 乘后赋值运算符
/= 除后赋值运算符
% = 取模后赋值运算符
<<= 左移后赋值运算符
>>= 右移后赋值运算符
&= 按位与后赋值运算符
^= 按位异或后赋值运算符
|= 按位或后赋值运算符
15、优先级15级
结合方向 左结合
, 逗号运算符
表达式
运算符和运算对象(变量)的组合构成了不同的表达式:
算术表达式 = 算术运算符 + 运算对象
赋值表达式 = 赋值运算符 + 运算对象
复合赋值表达式 = 复合赋值运算符 + 运算对象
自增、自减表达式 = 自增、自减运算符 + 运算对象
逗号表达式 = 逗号运算符 + 运算对象
关系表达式 = 关系运算符 + 运算对象
逻辑表达式 = 逻辑运算符 + 运算对象
条件表达式 = 条件运算符 + 运算对象
算数表达式
加(+)、减(-)、乘(*)、除(/)、求余(%)
#include"stdio.h"
int main()
{
int a=5,b=3;
int c=a+b;//这是一条算数表达式语句
printf("a+b=%d\na-b=%d\na*b=%d\na/b=%d\n",a+b,a-b,a*b,a/b);
printf("a%%b=%d\n",a%b);
return 0;
}
要输出%在printf中需要两个%号
因为a和b都是int类型,所以结果取整数。(int类型和int类型运算的结果还是int类型)
#include"stdio.h"
int main()
{
double a=5,b=3;
printf("a+b=%lf\na-b=%lf\na*b=%lf\na/b=%lf\n",a+b,a-b,a*b,a/b);
return 0;
}
赋值运算
赋值运算符(=)复合算术赋值(+=,-=,*=,/=,%=)复合位运算赋值(&=,|=,^=,>>=,<<=)
#include"stdio.h"
int main()
{
int a=5,b=3;//普通赋值表达式
a-=b;//复合算术赋值表达式,等价与a=a-b;
b+=1;//b=b+1;
printf("%d\n%d\n",a,b);
return 0;
}
这种复合算数赋值就是简化了 算数运算并赋值的写法。
自增自减表达式
自增(++)自减(- -)
自增自减运算符在前表示当前变量使用前先进行自增自减运算。
自增自减运算符在后表示当前变量使用后在进行自增自减运算。
#include"stdio.h"
int main()
{
int a=5,b=3;
a++;//++在后,a的值不变(还是5),a++执行过后a+1(a=a+1)
++a;//++在前,a先加1(a=a+1)在执行a
printf("b++的当前b的值:%d\nb++执行后b的值:%d",b++,b);
return 0;
}
#include"stdio.h"
int main()
{
int a=5,b=3;
a++;//++在后,a的值不变(还是5),a++执行过后a+1(a=a+1)
++a;//++在前,a先加1(a=a+1)在执行a
printf("++b的当前b的值:%d\n++b执行后b的值:%d",++b,b);
return 0;
}
关系运算符
大于(>)、小于(<)、等于(==)、 大于等于(>=)、小于等于(<=)和不等于(!=)
关系用算符用于判断两边变量或表达式是否满足某种关系
#include"stdio.h"
int main()
{
int a=5,b=3,c=2;
if(a<=3)//是否满足a小于或等于3
{
printf("a小于等于3\n");
}
if(b+c==a)//b+c是否等于a
{
printf("b+c等于a\n");
}
return 0;
}
条件表达式
? : 这是C语言中唯一一个三目运算符
表达式1?表达式2:表达式3
表示如果(?)前的表达式满足表达式的结果为(:)前的表达式;不满足结果为(:)后面的表达式。
#include"stdio.h"
int main()
{
int a=5,b=3,c;
c=a>b?5:3;
printf("%d\n",c);
c=a<b?5:3;
printf("%d\n",c);
return 0;
}
逻辑表达式
与(&&)、或(||)、非(!)三种。
&&表示两边表达式同时为真,逻辑表达式才为真。
|| 表示两边表达式只要有一边的表达式为真,逻辑表达式就为真。
! 表示取反,一个表达式为真,取反后就为假。
与
#include"stdio.h"
int main()
{
int a=5,b=3,c=2;
if(a>b&&b>c)
{
printf("逻辑与表达式为真\n");
}
return 0;
}
或
#include"stdio.h"
int main()
{
int a=5,b=3,c=2;
if(a<b||b>c)
{
printf("逻辑或表达式为真\n");
}
return 0;
}
非(!)
非也是取反的意思,在C语言中不为0的数字默认为真,0为假,所以!运算符就是让真变成假,假变成真。
#include"stdio.h"
int main()
{
int a=5,c=0;//非0为真,0为假
printf("%d\n",!c); // 假取反就是真
printf("%d\n",!a); //真取反就是假
return 0;
}
逗号表达式
用逗号隔开的多个表达式。
#include"stdio.h"
int main()
{
int a,b;
int c=(a=5,b=3,a+b);
printf("%d\n",c);
//int a,b;和int a=3,b=5,c=a+b;这也是逗号表达式
return 0;
}
位运算
位与(&)、位或(|)、位非(~)、位异或(^)、左移(<<)、右移(>>)
作用是进行二进制的位运算。
#include"stdio.h"
int main()
{
int a=5,b=3;
printf("%d\n%d\n",a&b,a^b);
return 0;
}
程序中的所有数在计算机内存中都是以二进制的形式储存的。
位运算就是直接对整数在内存中的二进制位进行操作。
不同类型的运算
一个int 类型和double类型的数值进行运算,结果是一个double类型,
如果你把这个double类型的结果赋值给int类型,那么小数点后面的部分会被舍弃。
#include"stdio.h"
int main()
{
int a=5,b;
double c=4.3;
b=a+c;
printf("%d\n",b);
return 0;
}
int类型和long long 类型的数据进行运算时,如果结果要赋值给int类型要注意数据范围不要超过int类型的最大范围。
强制转换
int类型和int类型运算会得到一个int类型的结果,即使你将这个结果赋值给double类型,小数点后面依然是0。比如 double a=5/3 的结果是1.000000。
以为int类型和int类型运算只会得到int类型不会得到浮点类型,这时我们就需要使用强制转换。
用法是在你要转换类型的变量前添加(),在()中写你要转换的类型
#include"stdio.h"
int main()
{
int a=5,b=3;
double c,d;
c=a/b;
d=(double)a/b;//使用强制转换将a转换成double类型
printf("%lf\n",c);
printf("%lf\n",d);
return 0;
}