目录
一、操作符的分类
• 算术操作符: + 、- 、* 、/ 、%
• 移位操作符: >> 、<<
• 位操作符: &、 |、 ^
• 赋值操作符: = 、+= 、 -= 、 *= 、 /= 、%= 、、>>= 、&= 、|= 、^=
• 单目操作符: !、++、--、&、*、+、-、~ 、sizeof、(类型)
• 关系操作符: > 、>= 、< 、、 == 、 !=
• 逻辑操作符: && 、||、!
• 条件操作符: ? :
• 逗号表达式: ,
• 下标引用: []
• 函数调用:()
• 结构成员访问: . 、->
二、算术操作符: + 、- 、* 、/ 、%
1、除法运算符(/
)
对于除法来说,除法的两端如果都是整数,执行的是整数除法,得到的结果也是整数;
如果希望得到浮点数结果,两个运算数必须至少有一个浮点数。
2、取模(余)运算符(%)
用来整除后的余数,只能用于整数。
负数的求模规则是:结果的正负号由第一个运算数的正负号决定
例如:
int a = 11 % -5;//结果为1
int b = -11 % -5;//结果为-1
三、原码、补码、反码
整数的2进制表示方法有三种,即原码、反码和补码。
有符号整数的三种表示方法均有符号位和数值位两部分,2进制序列中,最高位的1位是被当做符号 位,剩余的都是数值位。
符号位都是用0表示 “正”,用1表示 “负”。
原码:直接将数值按照正负数的形式翻译成二进制的就是原码
反码:原码的符号位不变,数值位按位取反得到的就是反码
补码:在反码的基础上+1得到的就是补码
正整数的原、反、补码都相同。 负整数的三种表示方法各不相同。
对整型来说:数据存放在内存中的就是补码
四、移位操作符
<<左移操作符
>>右移操作符
注:移位操作符的操作数只能是整数
1、左移操作符
<<左移操作:左边抛弃,右边补0
比如:
int a=10;
对于32位机器来说,则a的二进制序列为:
int b=a<<1;
通过将a左移操作后,b == 20
2、右移操作符
- 逻辑右移:左边补0,右边丢弃
- 算术右移:左边用原改值的的符号位填充,右边丢弃(常用)
这里用算术右移举例:
int num=-1;
int num1=num>>1;
则 num1 == -1
五、位操作符
1、&按位与(有0出0,全1出1)
例:
int a=3;
int b=-5;
int c=a&b;
得 c == 3
2、| 按位或(有1出1,全0出0)
例:
int a=3;
int b=-5;
int c=a|b;
得c==-5
3、^按位异或(相同为0,相异为1)
- a^a=0;
- 0^a=a
- 异或支持交换律:a^b^a=a^a^b
例子就不举了,直接上个练习
练习:不能创建临时变量,实现两个整数的交换
#include<stdio.h>
int main()
{
int a = 10;
int b = 20;
int c = a ^ b;
a = c ^ a;
b = c ^ b;
printf("a=%d b=%d\n", a, b);
return 0;
}
六、单目操作符
1. 逻辑非操作符:!
逻辑非操作符对布尔值进行取反操作。
-
如果操作数为 非零值,结果为
0
(逻辑假)。 -
如果操作数为 零,结果为
1
(逻辑真)。
2. 自增操作符:++
自增操作符将操作数的值增加1。它有两种形式:
-
前置自增:
++a
,先将a
的值增加1,再使用新的值。 -
后置自增:
a++
,先使用a
的当前值,再将其增加1。
int a = 5;
int b = ++a; // a = 6, b = 6
int c = a++; // c = 6, a = 7
3. 自减操作符:--
自减操作符将操作数的值减少1。它也有前置和后置两种形式:
-
前置自减:
--a
,先将a
的值减少1,再使用新的值。 -
后置自减:
a--
,先使用a
的当前值,再将其减少1。
int a = 5;
int b = --a; // a = 4, b = 4
int c = a--; // c = 4, a = 3
4. 取地址操作符:&
取地址操作符用于获取变量的内存地址。
int a = 5;
int* ptr = &a; // ptr 存储 a 的地址
printf("%p\n", ptr); // 输出 a 的地址
5. 解引用操作符:*
解引用操作符用于通过指针访问其指向的值。
int a = 5;
int* ptr = &a;
int value = *ptr; // value = 5,通过指针访问 a 的值
6. 正号操作符:+
正号操作符表示操作数的正值。
7. 负号操作符:-
负号操作符用于取操作数的相反数。
8. 按位取反操作符:~
按位取反操作符对操作数的每一位进行取反(0变1,1变0)。它适用于整数类型。
int a = 5; // 二进制表示:0000 0101
int b = ~a; // 二进制表示:1111 1010,结果为 -6(补码表示)
9. sizeof操作符
sizeof 用于获取操作数的大小(以字节为单位)。操作数可以是变量或类型名。
int a = 5;
printf("Size of int: %zu\n", sizeof(a)); // 输出 int 的大小
printf("Size of char: %zu\n", sizeof(char)); // 输出 char 的大小
10. 类型转换操作符:(类型)
类型转换操作符用于将操作数强制转换为指定的类型。
double d = 3.14;
int a = (int)d; // 将 double 转换为 int,结果为 3
七、逻辑操作符: && 、||、!
1. 逻辑与:&&
功能:
逻辑与操作符用于判断两个操作数是否都为真。只有当两个操作数都为真时,结果才为真;否则为假
-
在C语言中,
0
表示逻辑假(false
),非零值表示逻辑真(true
)。 -
如果两个操作数都为非零值,则
a && b
的结果为1
(逻辑真)。 -
如果其中一个操作数为
0
,则结果为0
(逻辑假)
int a = 5; // 非零值,表示逻辑真
int b = 0; // 零值,表示逻辑假
int c = a && b; // c = 0,因为 b 为假
a = 10;
b = 20;
c = a && b; // c = 1,因为 a 和 b 都为真
2. 逻辑或:||
功能:
逻辑或操作符用于判断两个操作数中是否至少有一个为真。如果至少有一个操作数为真,则结果为真;否则为假。
int a = 0; // 零值,表示逻辑假
int b = 10; // 非零值,表示逻辑真
int c = a || b; // c = 1,因为 b 为真
a = 0;
b = 0;
c = a || b; // c = 0,因为 a 和 b 都为假
3、逻辑非:!
对布尔值取反。
4、&&、||的短路特性
如果左边的表达式满足逻辑运算符的条件,就不再对右边表达式求值,这种情况称为“短路”。
例:
int a = 0;
int b = 10;
int c = a && b; // c = 0,不会计算 b 的值
对于&&操作符来说,左操作数结果为0时,右操作数就不再执行。
int a = 10;
int b = 0;
int c = a || b; // c = 1,不会计算 b 的值
对||来说,||的左操作数不为0时,就无需执行右操作数。
八、条件操作符(三目运算符)
语法形式:
condition ? exprTrue : exprFalse;
-
condition
:这是一个布尔表达式,用于判断条件是否成立。-
如果条件为真(非零值),则表达式返回
exprTrue
的值。 -
如果条件为假(零值),则表达式返回
exprFalse
的值。
-
-
exprTrue
:当条件为真时,表达式的结果。表达式1, 表达式2, 表达式3, ...
-
exprFalse
:当条件为假时,表达式的结果。
比如:
int a = 10;
int b = 20;
int max = (a > b) ? a : b; // 如果 a > b,max = a;否则 max = b
printf("Max value is: %d\n", max); // 输出:Max value is: 20
-
条件操作符具有短路特性,类似于逻辑操作符。
-
如果条件为真,
exprFalse
不会被计算。 -
如果条件为假,
exprTrue
不会被计算。
九、逗号表达式
逗号表达式的基本形式是:
表达式1, 表达式2, 表达式3, ...
逗号表达式会依次计算每个表达式,但最终返回的是最后一个表达式的值。
int a = 10, b = 20;
if ((a += 5), (b -= 5), (a > b))
{
printf("a is greater than b\n");
}
else
{
printf("b is greater than or equal to a\n");
}
在这个例子中,if语句的条件部分使用了逗号表达式。它先计算a += 5
和b -= 5
,然后返回a > b
的结果作为if
的条件。
十、结构成员访问: . 、->
1. .
(点操作符)
点操作符用于访问非指针类型的结构体或联合体变量的成员。
语法:
struct_name.member_name
例如:
struct Stu
{
int age;
char name[20];
};
struct Stu p;
p.age = 25;// 使用点操作符访问成员
2. ->
(箭头操作符)
箭头操作符用于访问指针类型的结构体或联合体变量的成员。
形式:
pointer_to_struct->member_name
以上面定义的结构体为例:
struct Stu *ptr = &p;//创建类型为struct Stu*的指针变量ptr
//用来存放p的地址
ptr->age = 30;//通过->来访问结果提成员age并赋值30