1.操作符的分类
算术操作符
移位操作符
位操作符
赋值操作符
逻辑操作符
条件操作符
逗号表达式
2.算数操作符
算数操作符有:
+——加法操作符;
-——减法操作符;
*——乘法操作符;
/——除法操作符;
%——取模操作符。
2.1 除法运算
其中,加、减、乘运算与我们日常数学中的运算没有特别大的区别,但是除法运算却与我们日常数学中的认识大相径庭。所以在C语言我们要有以下敏感的认识:
①整数除法——当除号两端都是整数的时候,商为结果的整数部分;代码验证如下:
#include <stdio.h> int main() { int a = 0; //这时你可能要说,用int类型定义, //得到的结果无论如何也都会是整数啊, //所以我们再增加一个float类型来验证整数除法的运算规则 float b = 0; a = 9 / 2; b = 9 / 2; printf("a=%d,b=%f\n", a,b); return 0; }
运算结果如图:
②浮点数(小数)除法——除号两端至少有一个小数就执行小数除法,代码验证如下:
#include <stdio.h> int main() { float a = 0; float b = 0; float c = 0; a = 9.0 / 2; b = 9 / 2.0; c = 9.0 / 2.0; printf("a=%f\nb=%f\nc=%f\n", a,b,c); return 0; }
运算结果如图:
2.2取模运算
%取模运算与除法运算类似,结果得到的是整除之后的余数,需要注意的是,执行取模运算时%两端的操作数必须是整数。
验证如下:
*2.3算数操作符的应用
我们知道了算数操作符的用法,那么这些运算有哪些应用呢?下面为大家介绍这些运算符的一种应用。
例:给定一个数1234,求该数的各位数分别是几?
这时就用到取模运算和除法运算——1234%10得到个位数4,1234/10%10得到十位数3,1234/100%10得到百位数2,1234/1000%10得到千位数1。代码实现如下:
#include <stdio.h> int main() { int a = 1234; int b = 0; int c = 0; int d = 0; int e = 0; b = a % 10; c = a / 10 % 10; d = a / 100 % 10; e = a / 1000 % 10; printf("个位数为%d\n十位数为%d\n百位数为%d\n千位数为%d\n",b, c, d, e); return 0; }
运算结果如图:
3.移位操作符
移位操作符分为<<(左移操作符)和>>(右移操作符)
需要注意的是,左移操作符和右移操作符的操作数都只能是整数。
3.1原码、反码、补码
我们知道,计算机处理的是二进制信息,整数的二进制在计算机中有原码,反码,补码三种表示形式,而整数又是以补码的形式存储在计算机的内存中,所以计算机中的运算都是以补码来进行计算的,因此移位操作符移动的也是补码的二进制序列。
其中,正数的原码、反码、补码都是相同的,负数的原码、反码、补码是要通过计算得到的。
一个整型是4个字节=32个比特位,最高位为符号位,0表示正数,1表示负数
所以15的二进制表示为00000000 00000000 00000000 00001111,
-15表示为10000000 00000000 00000000 00001111。
因为15是正数,所以15的原码、反码、补码都是
00000000 00000000 00000000 00001111,
而负数的原码、反码、补码遵循这样的计算规则:原码的符号位不变,其他位按位取反得到的就是反码,反码+1就是补码。
因此-15的原码、反码、补码为:
3.2 左移操作符
我们已经说过,移位操作符移动的是二进制的补码
因此左移操作符<<的移位规则为左边抛弃,右边补0(移动几位就抛弃几位);
例如:int a = 15; int b = a<<1;求b的值?
计算图解如下:
按原、反、补的计算规则可以得到15<<1的原码为00000000000000000000000000011110
即b=30,代码验证如下:
#include <stdio.h> int main() { int a = 15; int b = a << 1; printf("%d\n", b); return 0; }
3.3右移操作符
右移操作符与左移操作符不完全相同,右移操作符分为算数右移和逻辑右移,他们的计算规则为:
算数右移:右边丢弃,左边补原来的符号位;
逻辑右移:右边丢弃,左边直接补0;
需要注意的是,一般编译器采用的是算数右移。
与左移计算规则类似,右移代码验证如下:
#include <stdio.h> int main() { int a = -15; int b = a >> 1; int c = a >> 2; printf("%d\n%d\n", b, c); return 0; }
4.位操作符
位操作符有
&——按位与;
|——按位或;
^——按位异或;
位操作符的运算对象也是二进制的补码。
4.1 & 操作符
例如:int a = 3; int b = -5;int c = a & b;求c?
我们得到3和-5的补码分别为
00000000000000000000000000000011
11111111111111111111111111111011
&的运算规则为:对应的二进制位有0则为0,两数同时为1,才为1;计算如图:
得到c的符号位为0,c为正数,原、反、补相同,c=3
#include <stdio.h> int main() { int a = 3; //00000000 00000000 00000000 00000011--原、反、补码 int b = -5; //10000000 00000000 00000000 00000101--原码 //11111111 11111111 11111111 11111010--反码 //11111111 11111111 11111111 11111011--补码 int c = a & b; //对应的二进制位有0则为0,两数同时为1,才为1; //00000000 00000000 00000000 00000011 //11111111 11111111 11111111 11111011 //00000000 00000000 00000000 00000011--补、反、原码 c=3; printf("%d\n", c); return 0; }
4.2 | 操作符
与 & 操作符类似, | 操作符的计算规则为对应的二进制位有1则为1,两数同时为0,才为0;
代码验证如下:
#include <stdio.h> int main() { int a = 3; //00000000 00000000 00000000 00000011--原、反、补码 int b = -5; //10000000 00000000 00000000 00000101--原码 //11111111 11111111 11111111 11111010--反码 //11111111 11111111 11111111 11111011--补码 int c = a | b; //对应的二进制位有1则为1,两数同时为0,才为0; //00000000 00000000 00000000 00000011 //11111111 11111111 11111111 11111011 //11111111 11111111 11111111 11111011--补码 //11111111 11111111 11111111 11111010--反码 //10000000 00000000 00000000 00000101--原码 c = -5 printf("%d\n", c); return 0; }
巧计:&同真为真余为假,|同假为假余为真。
4.3 ^操作符
^操作符的计算规则为:对应的二进制位相同为0,相异为1;
代码验证如下:
#include <stdio.h> int main() { int a = 3; //00000000 00000000 00000000 00000011--原、反、补码 int b = -5; //10000000 00000000 00000000 00000101--原码 //11111111 11111111 11111111 11111010--反码 //11111111 11111111 11111111 11111011--补码 int c = a ^ b; //对应的二进制位相同为0,相异为1; //00000000 00000000 00000000 00000011 //11111111 11111111 11111111 11111011 //11111111 11111111 11111111 11111000--补码 //11111111 11111111 11111111 11110111--反码 //10000000 00000000 00000000 00001000--原码 c = -8 printf("%d\n", c); return 0; }
*4.4 位操作符的应用
假如有a=3,b=5,c=6;可以得到:a ^ b = c ; a ^ c = b ; b ^ c = a;
不难发现:在a,b,c中,任意两个数按位异或都会得到第三个数。
根据这个,我们就可以轻松得到以下这个题目的解决方法:
不创建临时变量(第三个变量),实现两个数的交换?解决方法如下:
#include <stdio.h> int main() { int a = 15; int b = 8; printf("交换前a=%d,b=%d\n", a, b); a = a ^ b; b = a ^ b; a = a ^ b; printf("交换后a=%d,b=%d\n", a, b); return 0; }
5.赋值操作符
我们最熟悉的 = 赋值操作符,这里不再详细说明,只介绍一些复合赋值符:
+=
-=
*=
/=
%=
>>=
<<=
&=
|=
^=
关于这些复合操作符的用法,举个例子,一目了然:
例如:
a+=1与a=a+1;
a-=1与a=a-1;
a*=与a=a*1;
……
这些都是不同的写法,相同的意思。
6.单目操作符
所谓单目操作符,即操作符的操作数只有一个,单目操作符有:
! 逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
-- 前置、后置--(前置--,先减后用;后置--,先用后减)
++ 前置、后置++(前置++,先加后用;后置++,先用后加)
* 间接访问操作符(解引用操作符)
(类型) 强制类型转换
7.关系操作符
关系操作符有:
>
>=
<
<=
!= 用于测试“不相等”
== 用于测试“相等”
关系操作符与我们数学中的相似,不再详细介绍,不过需要注意的是,‘=’与‘==’是两个完全不同的操作符,千万不可用错。
8.逻辑操作符
逻辑操作符有:
&& 逻辑与(有and的意思)
|| 逻辑或(有or的意思)
逻辑操作符也没有什么可说的,但是需要区分‘&&’与‘&’;‘||’与‘|’;
比如:
1&2 结果为0
1&&2 结果为1
1|2 结果为3
1||2 结果为1
所以,我们可以这样总结:‘&&’与‘&’——同真为真余为假;‘||’与‘|’——同假为假余为真;
‘&&’和‘||’运算的是数字本身,运算结果为 真(1)或假(0);而‘&’和‘|’运算的是数字的二进制位补码,运算结果为数值。
9.条件操作符
条件操作符的格式为:
语句1?语句2:语句3
意思为:语句1为真,则执行语句2;语句1为假,则执行语句2。
它与if语句有相似的表达效果:
#include <stdio.h> int main() { int a = 0; int b = 0; if (a > 0) b = 1; else b = 0; printf(" %d\n ", b); return 0; }
#include <stdio.h> int main() { int a = 0; int b = 0; b = (a > 0) ? 1 : 0; printf(" %d\n ", b); return 0; }
*条件操作符的应用
使用条件表达式实现找两个数中较大值?
//使用条件表达式实现找两个数中较大值? #include <stdio.h> int main() { int a = 3; int b = 5; int c = 0; c = (a > b) ? a : b; printf("较大值为%d\n ", c); return 0; }
10.逗号表达式
逗号表达式的表现形式为:
表达式1,表达式2,表达式3,表达式4……
意思为:
逗号表达式,就是用逗号隔开的多个表达式,逗号表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果。
上一段代码加深理解:
#include <stdio.h> int main() { int a = 1; int b = 2; int c = (a > b, a = b + 10, a, b = a + 1); //逗号表达式从左往右依次执行,最后一个表达式的结果即为最终结果。 //a>b为假,a、b的值未改变; //a=b+10=12,所以a=12,b=2; //a=12; //b=a+1=13; //故整个表达式的值为13,即c=13。 printf("%d\n", c); return 0; }