1.操作符分类:
算数操作符:+ - * / %
移位操作符: << >>
位操作符 & | ^
赋值操作符: = += -= *= /= 等等
单目操作符:! sizeof + - ~ & *
关系操作符:> < <= == !=
逻辑操作符: && ||
条件操作符: ? :
逗号操作符: ,
下标引用,函数调用和结构成员: [] () . ->
2.算术操作符:
+ - * / %
前三种大家都了解,在此特别说明后两种
一。 /(除法)
根据计算结果的类型分为两种:
1.整数除法(除号两端都是整数) 结果只要整数部分,不要小数部分。
演示代码如下:
#include<stdio.h>
int main()
{
int r = 7 / 3;
double d = 7 / 3;
printf("%d\n", r);
printf("%lf", d);
return 0;
}
运行结果:
同时从上面的演示中我们还可以发现除法的结果不会因为所赋值变量的类型,而使结果形式发生改变(除法结果主要整数部分,不要小数部分)。
2.浮点数除法(除号的两端只要有一个小数就执行小数除法)
代码演示:
#include<stdio.h>
int main()
{
double d = 7 / 2.0;
printf("%lf", d);
}
运行结果:
在上面的演示中你还可以将7改成7.0或者将7改成7.0 ,2.0该为2。此时运行代码得到的结果和上述结果仍然一样。
同时在进行除法运算中我们应当还要注意除数(分母)不能为0。若不小心使分母为0,则编译器会报错。
错误实例:
二。%(取模操作符:得到的结果时整数被除后的余数)
注意事项:
1.进行取模运算得到的结果范围为:0~除数-1
2.使用取模操作符是两边的数据必须是整形不能为其他类型;
正确事例:
错误示例:
3.移位操作符:
<< (左移操作符)
>> (右移操作符)
注意事项:
1.移位操作符的操作数只能是整数
2.移位操作符移动的是操作数在计算机中存储的二进制。
表示一个整数的二进制:
由于在C语言中一个整形(int)是四个字节(32位bit)所以整数的二进制一共有32位,最高位是0时表示正整数,1时表示负整数。
整数的二进制有三种表示形式:1.原码,2反码,3.补码
正整数的原码反码补码都一样。
1.将10进制的整数转化成2进制数,并在前面加0直到32位。
2.将最高位置为0。
例子:10(10进制) 。
将10(10进制)转化二进制数为1010
加0到32位为:00000000000000000000000000001010
将最高位置为0后:00000000000000000000000000001010
正整数10的原码,反码,补码为:00000000000000000000000000001010
负整数的原码反码补码需要计算
原码:将10进制的整数转化成2进制数,并在前面加0直到32位。将最高位置为1。
反码:最高位保持不变,将其他位取反(0变1,1变0)
补码:将得到的反码加1就是补码。
例子:-10(10进制)
将 -10(10进制)转化成二进制数为1010
加0到32位为:00000000000000000000000000001010
将最高位置为1后:10000000000000000000000000001010
所以-10的原码为:10000000000000000000000000001010
所以-10的反码为:111111111111111111111111111111110101
所以-10的补码为:111111111111111111111111111111110110
而因为整数在计算机中储存二进制数位补码,所以移位操作符操作的就是操作数的补码。
右移分为:
1.算术右移。(右边丢弃,左边补原来的符号位)
2.逻辑右移。(右边丢弃,左边补0)
左移:左边丢弃,右边补0
C语言没有明确规定移动是算术移动还是逻辑移动。一般编译器采用的是算数移动。
移位操作符代码例子:
运行结果:
(注:1.在vs2022中采用的是算数移动。2.移位操作符右边的数(为正整数【推荐】,若为负整数【强烈不推荐】就是标准未定义行为,具体要看编译器)表示移动的位数。3.在电脑上打印的是10进制数。)
4.位操作符
& 按位与
| 按位或
^ 按位异或
注:他们的操作数必须是整数。也是按二进制数进行的操作
#include<stdio.h>
int main()
{
int a = 3;
//00000000000000000000000000000011 --补码
int b = -5;
//10000000000000000000000000000101
//11111111111111111111111111111010
//11111111111111111111111111111011 --补码
int c = a & b; //按位与
// & --对应二进制有0则为0,两个同时为1,才是1
// 00000000000000000000000000000011
// 11111111111111111111111111111011
// 00000000000000000000000000000011--补码
//
int d = a | b; //按位或
// | --对应二进制有1则为1,两个同时为0,才是0
// 00000000000000000000000000000011
// 11111111111111111111111111111011
// 11111111111111111111111111111011 --补码
// 11111111111111111111111111111010
// 10000000000000000000000000000101 --原码
int e = a^b; //按位异或
// ^ --对应二进制相同为0,不同为1
// 00000000000000000000000000000011
// 11111111111111111111111111111011
// 11111111111111111111111111111000 --补码
// 11111111111111111111111111110111
// 10000000000000000000000000001000 --原码
//
printf("%d %d %d", c,d,e);
return 0;
}
运行结果:
5.赋值操作符
=
可以给变量赋值,同时可以连续使用
如:
int a=10;
int x=20;
a=x=y+1//连续赋值
注:连续赋值时从右向左赋值
复合赋值符
+= -= *= /= %= >>= <<=
&= |= ^=
如:
int x=10;
x=x+10;
x+=10;//复合赋值
//其他运算符一样的道理
6.单目操作符 (只有一个操作数)
! 逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制取反
-- 前置,后置--
++ 前置,后置++
* 间接访问操作符(解引用操作符)
(类型) 强制转换
! 将真变为假,假变为真,常用于条件判段中
如:
+ 正值
在正数前面,一般省略不写
- 负值
可以将正数变为负数,复数变为整数。在负数前面
如:
& * 应用于指针
sizeof 不是函数,是操作符
sizeof 计算的是类型,变量和数组的大小,单位是字符;
~ 按补码二进制位取反(包括符号位)
++前置 后置++ --前置 后置--
--前置 后置-- 同上。
(类型)强制转换
7.关系操作符
>
>=
<=
!= 用于测试”不相等“
== 用于测试”相等“
注:只能应用于适合的类型上(如整形,浮点型)
8.逻辑操作符
&& --逻辑与 并且(同时成立)
|| --逻辑或 或者 (有一个成立就可以)
逻辑操作符 :&&和|| 计算为真时,使用1表示。为假时,使用0表示
注意区分逻辑与,逻辑或 和 按位与 ,按位或
1&2------>0
1&&2------>1
1|2 -------->3
1||2------->1
注:使用&&时,如果&&左边条件为假,则就不执行右边,直接判断为假。
使用||时,如果||左边条件为真,则就不执行右边,直接判断为真。
9.条件操作符(三目操作符[有三个操作数])
exp1?exp2:exp3
使用方法:
(1)如果表达式1(exp1)为真,表达式2(exp2)计算,表达式3(exp3)不计算;
(2)如果表达式1(exp1)为假,表达式2(exp2)不计算,表达式3(exp3)计算;
例子:
#include<stdio.h>
int main()
{
int a = 0, b = 0;
a > 5 ? b = 3 : b = 4;
//当a>5时,执行b=3,当a>5不成立时执行b=4.
printf("b=%d", b);
return 0;
}
运行结构:
10.逗号表达式
exp1,exp2,exp3, ...expN
逗号表达式,就是用逗号隔开的多个表达式。
逗号表达式从左向右依次执行。整个表达式的结果是最后一个表达式的结果。
注:由于逗号表达式由多个表达式组成,在前面的表达式的执行结果可能会影响到最后一个表达式,因此出现逗号表达式是我们一定要从左到右去看,不要直接看最后一个表达式。
例子:
#include<stdio.h>
int main()
{
int a = -1, b = 1,c = 1;
if (a++, b++, c = a + b)
//前两个的运行结果影响到了最后一个表达式,若我们此时只看最后一个,我们所得到的结果就是错误的
//a++, b++, c = a + b的执行结果为c=a+b的结果3,为真。
{
printf("haha\n");
}
printf("a=%d b=%d c=%d", a, b, c);
return 0;
}
运行结果:
下标引用操作符([]) 操作数一般是数组名加下标。
函数调用操作符 () 操作数一般是函数名加上()里面的参数, 最少有一个操作数(调用无参函数时)。
例子:
#include<stdio.h>
#include<string.h>
int main()
{
int a[4] = { 1,2,3,4 };
printf("%d\n", a[0]);//利用下标引用操作符([])得到数组a的第一个元素
//在这里下标引用操作符([])有两个操作数:数组名a 和 []里面的0
int len = strlen("aaaa");// ()函数调用操作符。这里函数调用操作符 ()的操作符是:函数名strlen 和参数"aaaa"字符串
printf("%d", len);
return 0;
}
运行结果:
结构成员操作符( . -> )
. 结构体.成员
-> 结构体指针->成员名
例子:
#include<stdio.h>
struct book
{
char name[30];
char auther[20];
float price;
};
void print(struct book* p)
{
printf("%s %s %.1f", p->name, p->auther, p->price);//结构体指针->成员名
}
int main()
{
struct book b1 = { "C程序设计","谭浩强",66.6f };
struct book b2 = { "C语言第一课","鹏哥",66.6f };
printf("%s %s %.1f\n", b1.name, b1.auther, b1.price);//结构体变量.成员名
print(&b2);
return 0;
}
运行结果: