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;
}