目录
1、操作符的分类
算数操作符 | +、-、*、/、% |
移位操作符 | <<、>> |
位操作符 | &、|、^ |
赋值操作符 | =、+=、 -= 、*=、 /=、 %= 、>>= 、<<= 、&=、 |=、 ^= |
单目操作符 | ! 、- 、+ 、&、sizeof 、~、-- 、++ 、* 、(类型) |
关系操作符 | >、 >=、 < 、<=、 != 、== |
逻辑操作符 | &&、|| |
条件操作符 | exp1 ? exp2 : exp3 |
逗号表达式 | , |
下标引用、函数调用和结构成员 | [ ]、( )、. 、-> |
1.1操作符的优先级
优先级 | 运算符 | 名称或含义 | 使用形式 | 结合方向 | 说明 |
1 | [] | 数组下标 | 数组名[常量表达式] | 左到右 | -- |
() | 圆括号 | (表达式)/函数名(形参表) | -- | ||
. | 成员选择(对象) | 对象.成员名 | -- | ||
-> | 成员选择(指针) | 对象指针->成员名 | -- | ||
| |||||
2 | - | 负号运算符 | -表达式 | 右到左 | 单目运算符 |
~ | 按位取反运算符 | ~表达式 | |||
++ | 自增运算符 | ++变量名/变量名++ | |||
-- | 自减运算符 | --变量名/变量名-- | |||
* | 取值运算符 | *指针变量 | |||
& | 取地址运算符 | &变量名 | |||
! | 逻辑非运算符 | !表达式 | |||
(类型) | 强制类型转换 | (数据类型)表达式 | -- | ||
sizeof | 长度运算符 | sizeof(表达式) | -- | ||
| |||||
3 | / | 除 | 表达式/表达式 | 左到右 | 双目运算符 |
* | 乘 | 表达式*表达式 | |||
% | 余数(取模) | 整型表达式%整型表达式 | |||
4 | + | 加 | 表达式+表达式 | 左到右 | 双目运算符 |
- | 减 | 表达式-表达式 | |||
5 | << | 左移 | 变量<<表达式 | 左到右 | 双目运算符 |
>> | 右移 | 变量>>表达式 | |||
| |||||
6 | > | 大于 | 表达式>表达式 | 左到右 | 双目运算符 |
>= | 大于等于 | 表达式>=表达式 | |||
< | 小于 | 表达式<表达式 | |||
<= | 小于等于 | 表达式<=表达式 | |||
7 | == | 等于 | 表达式==表达式 | 左到右 | 双目运算符 |
!= | 不等于 | 表达式!= 表达式 | |||
| |||||
8 | & | 按位与 | 表达式&表达式 | 左到右 | 双目运算符 |
9 | ^ | 按位异或 | 表达式^表达式 | 左到右 | 双目运算符 |
10 | | | 按位或 | 表达式|表达式 | 左到右 | 双目运算符 |
11 | && | 逻辑与 | 表达式&&表达式 | 左到右 | 双目运算符 |
12 | || | 逻辑或 | 表达式||表达式 | 左到右 | 双目运算符 |
| |||||
13 | ?: | 条件运算符 | 表达式1? 表达式2: 表达式3 | 右到左 | 三目运算符 |
| |||||
14 | = | 赋值运算符 | 变量=表达式 | 右到左 | -- |
/= | 除后赋值 | 变量/=表达式 | -- | ||
*= | 乘后赋值 | 变量*=表达式 | -- | ||
%= | 取模后赋值 | 变量%=表达式 | -- | ||
+= | 加后赋值 | 变量+=表达式 | -- | ||
-= | 减后赋值 | 变量-=表达式 | -- | ||
<<= | 左移后赋值 | 变量<<=表达式 | -- | ||
>>= | 右移后赋值 | 变量>>=表达式 | -- | ||
&= | 按位与后赋值 | 变量&=表达式 | -- | ||
^= | 按位异或后赋值 | 变量^=表达式 | -- | ||
|= | 按位或后赋值 | 变量|=表达式 | -- | ||
| |||||
15 | , | 逗号运算符 | 表达式,表达式,… | 左到右 | -- |
2、算数操作符
+、-、*、/、%
+ 操作符将两个数相加
- 操作符将两个数相减
* 操作符将两个数相乘
/ 除法可分为:1、整数除法(除法两端都是整数) 2、浮点数除法(除号两端只要有一个是小数就执行小数除法)
int a = 5/2;
整数除法的结果也为整数,会自动舍弃小数点后的数字,上述代码运行的结果为:a=2;
double a = 5 / 2.0;
浮点数除法的结果可保留小数,上述代码运行结果为:a=2.500000
& 操作符两个操作数必须是整数,当c=a%b时,意思为,c为a除以b的余数
取模操作符的引用:可用除10与模10取出10进制数的每一位
3、移位操作符
这里我们需要明确的是位移操作符移动的是二进制,而我们生活中的一般用的是10进制
我们先来看一下什么是10进制,如下123,1代表的是1*10^2,2代表的是2*10^1;3代表的是3*10^0
二进制同理,比如我们看一下int a =15的二进制为:1111,分别代表的是:1*2^3+1*2^2+1*2^1+1*2^0
整数的二进制的表示形式有三种:原码;反码;补码
这里值得注意的是:正整数的原码、反码、补码是相同的;负整数的原码、反码、补码是需要计算的
我们这里用的是整型,而一个整形有4个字节=32bit位,所以二进制表示应为32位,第一位为符号位,1表示负数,0表示正数,中间用0补齐就好,正整数的原码、反码、补码表示如下
int a = 15;
//00000000000000000000000000001111 - 原码
//00000000000000000000000000001111 - 反码
//00000000000000000000000000001111 - 补码
负整数的原码、反码、补码是需要计算的,计算方法和原码、反码、补码表示如下
int b = -15;
//10000000000000000000000000001111 - 原码
//11111111111111111111111111110000 - 反码(原码的符号位不变,其他位按位取反得到的就是反码)
//11111111111111111111111111110001 - 补码(反码+1就是补码)
我们还需要明确的是整数在内存中存储的是补码,计算的时候也是使用补码计算的
3.1、左移操作符
移位移动的二进制序列,左移操作符 - 左边丢弃,右边补0,这里我们以int a =15;为例
3.2、右移操作符
右移我们这儿分为:
算数右移(右边丢弃,左边补齐原来符号位);逻辑右移(右边丢弃,左边直接补0)
4、位操作符
& 按位与
| 按位或
^ 按位异或
注意:他们的操作数必须是整数
不懂?没关系,请看下面带码
int a = 3;
//00000000000000000000000000000011 - 补码
int b = -5;
//10000000000000000000000000000101 -原码
//11111111111111111111111111111010 -反码
//11111111111111111111111111111011 - 补码
这是我们给出的初始代码后面都会用到,这里不得不在强调一遍:整数在内存中存储的是补码,计算的时候也是使用补码计算的
& 操作符使用与计算如下
int c = a & b;
// //& -- 对应二进制位有0则为0,两个同时为1,才是1
// //00000000000000000000000000000011
// //11111111111111111111111111111011
// //00000000000000000000000000000011 - 补码
// //
// printf("%d\n", c);//结果为3
| 操作符使用与计算如下
// int c = a | b;
// //| - 按(2进制)位或 - 对应的二进制位有1则为1,两个同时为0才是0
// //00000000000000000000000000000011
// //11111111111111111111111111111011
// //11111111111111111111111111111011 - 补码
// //11111111111111111111111111111010
// //10000000000000000000000000000101 - -5
// printf("%d\n", c);//结果为-5
^ 操作符使用与计算如下
int c = a ^ b;
// //^ - 按二进制位异或 -对应的二进制位相同为0,相异为1
// //00000000000000000000000000000011
// //11111111111111111111111111111011
// //11111111111111111111111111111000 - 补码
// //11111111111111111111111111110111
// //10000000000000000000000000001000 - -8
// printf("%d\n", c);//结果为-3
5、赋值操作符
+= -= *= /= %=
>>= <<= &= |= ^=
=
赋值操作符就比较简单,就给大家举一个例子,其他的赋值操作符都是同样的道理
a+=b
意思为a=a+b;
6、单目操作符
! 逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
-- 前置、后置--
++ 前置、后置++
* 间接访问操作符(解引用操作符)
(类型) 强制类型转换
6.1、单目操作符介绍
! 逻辑反操作
int main()
{
int flag = 5;
if (flag == 0)
{
printf("hehe\n");
}
if (!flag)//flag 为假 打印hehe
{
printf("hehe\n");
}
if (flag)
{
printf("haha\n");
}
return 0;
}
简单的应用
//int main()
//{
// int a = 0;
// //scanf 读取失败返回的是EOF
// while (scanf("%d", &a) != EOF)
// {
// printf("%d\n", a);
// }
// return 0;
//}
+ 与 -这里博主就不介绍了
//& * 应用于指针
//int main()
//{
// int a = 10;
// //pa是指针变量
// int* pa = &a;//&-取地址操作符-取出a的地址
// *pa = 20;//解引用操作符(间接访问操作符)-单目操作符-通用pa中存放的地址,找到指向的空间(内容)
// int c = *pa;
// return 0;
//}
~ 操作符讲解和使用如下
//~ 按补码二进制位取反
//
//int main()
//{
// int a = 0;
// printf("%d\n", ~a);//这里的值为-1
// //00000000000000000000000000000000
// //11111111111111111111111111111111 - 补码
// //11111111111111111111111111111110
// //10000000000000000000000000000001 -1
// return 0;
//}
++、--操作符详解如下
//--前置、后置--
//++前置、后置++
//int main()
//{
// int a = 1;
// int b = a++;//后置++,先使用,后++
// //b=a,a=a+1
// printf("a=%d b=%d\n", a, b);//2 1
// return 0;
//}
//
//int main()
//{
// int a = 1;
// int b = a--;//后置--,先使用,后--
// //b=a,a=a-1
// printf("a=%d b=%d\n", a, b);//0 1
// return 0;
//}
//
//int main()
//{
// int a = 1;
// int b = ++a;//前置++,先++,后使用
// //a=a+1,b=a
// printf("a=%d b=%d\n", a, b);//2 2
// return 0;
//}
//int main()
//{
// int a = 1;
// int b = --a;//前置--,先--,后使用
// //a=a-1,b=a
// printf("a=%d b=%d\n", a, b);//0 0
// return 0;
//}
//int main()
//{
// int a = 10;
// printf("%d\n", a++);//10
// printf("%d\n", a);//11
//
// return 0;
//}
(类型) 强制类型转换使用如下
//int main()
//{
// int a = (int)3.14;//强制转换,将浮点型转为整形
// printf("%d\n", a);//结果为3
// return 0;
//}
6.2、sizeof和数组
这里我们需要强调的是
我们看一下实例应用就懂了
//#include <stdio.h>
//void test1(int arr[])//int*
//{
// printf("%d\n", sizeof(arr));//(2)
//}
//void test2(char ch[])//char*
//{
// printf("%d\n", sizeof(ch));//(4)
//}
//int main()
//{
// int arr[10] = { 0 };
// char ch[10] = { 0 };
// printf("%d\n", sizeof(arr));//打印的是40,因为每个数4个字节,总共有10个数,所以数组大小为40
// printf("%d\n", sizeof(ch));//对char操作时计算的时数组内可存放多少个字符,所以是10
// test1(arr);//打印的是&arr[0],&arr[0]是指针变量,字节大小为4/8个字节
//具体为多少,这得取决你所使用的平台环境,x86为4,x64为8
//播主用的是x86,所以此处打印为4
// test2(ch);// 打印的是&ch[0],同理,所以长度为4字节
// return 0;
//}
7、关系操作符
>
>=
<
<=
!=
==
这里博主也不做多余解释,但值得注意的是:在编程的过程中== 和=不小心写错,易导致错误;只能运用到合适的位置上 ,注意>=、<=、!=别写反了
8、逻辑操作符
&& 逻辑与
|| 逻辑或
这里了博主借助于一位大牛的图来带大家了解一下这两个操作符
首先看一下逻辑与&&,也就是并且的意思,看下图
我们再来看看逻辑或||,也就是或者的意思,看下图
了解这些之后,我们先浅看一个代码看一下他们的应用
//int main()
//{
// int y = 0;
// scanf("%d", &y);
// //1. 能被4整除,并且不能被100整除
// //2. 能被400整除是闰年
// if (((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0))
// {
// printf("闰年\n");
// }
// else
// {
// printf("不是闰年\n");
// }
// return 0;
//}
了解呢这些之后呢,它们还有几个点也必须值得我们注意
&& 操作符,左边为假,右边就不会计算了
| | 操作符,左边为真,右边就不会计算了
至于具体什么意思呢,请看代码
//#include <stdio.h>
//int main()
//{
// int i = 0, a = 0, b = 2, c = 3, d = 4;
// i = a++||++b||d++;
// printf("a = %d\nb = %d\nc = %d\nd = %d\n", a, b, c, d);//
// return 0;
由于a++,是先使用后++,所以判断时此处还为0,为假继续判断;++b=3为真,后面便不用计算了,所d++不执行,便得出以下结果
刚刚时| |操作符,接下来我们看看&&操作符,代码如下
//#include <stdio.h>
//int main()
//{
// int i = 0, a = 0, b = 2, c = 3, d = 4;
// i = a++ && ++b && d++;
// printf("a = %d\nb = %d\nc = %d\nd = %d\n", a, b, c, d);//
// return 0;
由于a++,是先使用后++,所以判断时此处还为0,为假结束后面计算,所一结果如下
关于其他操作符的详解请关注博主后续文章