C语言操作符详解
我们日常所见到的任何事物都是有个种各样细小的零件所组成的,比如我们现在用的 CPU 它的内部是由许许多多的二极管、三极管等基本元器件再加上连接各种元器件的导线所组成的。不同的组合方式也就形成了不同的功能,比如ALU、控制器、寄存器、存储器等等。当然我们的C语言也不例外,它也是由最基本的运算所组成的,而我们今天讨论的操作符就是其中之一。
C语言的操作符由以下几种类型:算术操作符、移位操作符、位操作符、赋值操作符、单目操作符、关系操作符、逻辑操作符、条件操作符、逗号表达式、下标引用、函数调用和结构成员等,下面我们来详细讨论一下这些操作符。
1、算术操作符
我们常见的算术运算符有以下几个:
+ - * / %
除了%操作符以外,其他的操作符可以对整数和浮点数进 行运算
对于 / 和 * 操作符 如果两个操作数数整数,则为整数除法 / 乘法;若有一个是浮点数则为浮点数,则为浮点数除法 / 乘法
对于 % 操作符,两个操作数必须都为整数,结果是整除后的余数
2、移位操作符
移位操作符有两个左移和右移
<< 左移
>> 右移
左移就是把一个数的二进制位整体向左移,规则:左边抛弃,右边补零 比如:
5 << 1 就是把5的二进制形式向左移一位
相当于 0000 1001 << 1 这最左边为0被抛弃,然后在最右边补0
最后的结果是 0000 1001 << 1 ==> 0001 0010
右移就是把一个数的二进制位整体向右移,但是由两种情况:逻辑右移、算术右移
逻辑右移和左移是一样的,只不过是反了过来,右边抛弃,左边补零,比如
5 >> 1 //5右移一位 相当于
0000 1001 >> 1 //右边抛弃,左边补零
0000 1001 >> 1 ==> 0000 0100
算术右移要考虑到符号位, 左边补充符号位,右边丢弃,这里举两个例子:
1、正数
5 << 1 // 5右移1位
0000 1001 << 1 //二进制形式
0000 1001 << 1 ==> 0000 0100 //右边抛弃,左边补符号位
这个其实是与逻辑右移一样的,但是负数呢?
2、负数
-2 << 1 //-2 右移1位
1000 0010 //原码
1111 1101 //反码
1111 1110 //补码(内存中存储的形式)
1111 1110 >> 1 //对-2右移就是对他的补码右移
1111 1110 >> 1 ==> 1111 1111 //右边抛弃,左边补符号位
但是对于一个数,如何判断他是逻辑右移还是算术左移呢?
这个和操作数的类型有关,如果操作数是无符号的那就是逻辑右移,如果是有符号的那就是算术右移
3、位操作符
位操作符有三个分别是:
& //按位与 全1为1,否则为0
| //按位或 全0为0,否则为1
^ //按位异或 不同为1,相同为0
注:这三个操作符的两个操作数必须为整数
4、赋值操作符
赋值操作符为 = ,但是它可以与其他操作符简写,以下是常用的几种:
= //最基本的赋值操作符 例 a = b
+= //加等 例: a += b ==> a = a + b
-= //减等 例: a -= b ==> a = a - b
%= //模等 例: a %= b ==> a = a % b
*= //乘等 例: a *= b ==> a = a * b
/= //除等 例: a /= b ==> a = a / b
还有一些其他的,不一一举例,可与以上类比
<<= >>= &= ^= |=
5、单目操作符
! 逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
-- 前置、后置--
++ 前置、后置++
* 间接访问操作符(解引用操作符)
(类型) 强制类型转换
注:sizeof 不是一个函数,而是一个操作符
对于前置++/--和后置++/--的理解:
前置 ++/-- : 先对值 ++/-- 然后在使用这个值
后置 ++/-- :先使用值,使用完之后再对其进行 ++/--
int i = 1;
a = ++i ; //前置++,先加后用 所以现在 a = 2; i = 2
a = i++ ; //后置++,先用后加 用了之后 a = 2; 然后i再加1 , i = 3
a = --i ; //前置--,先减后用 减了后 i = 2 , 然后a = 2
a = i-- ; //后置++,先用再减 用了后 a = 2 , 然后i再减1 , i = 1
6、关系操作符
用于两个数的比较,常用的有:
> 大于
>= 大于等于
< 小于
<= 小于等于
!= 用于测试“不相等”
== 用于测试“相等”
注意:== 和 = 是两个不同的操作符,其表达的含义完全不一样,请初学者高度重视
7、逻辑操作符
常用于多个条件之间的关系判断:
&& 逻辑与 // 0为假 非零为真
|| 逻辑或
应该严格区分逻辑与/或和按位与/或的区别,举个例子:
1 & 2 ==> 0 按位与
1 && 2 ==> 1 逻辑与
按位与是把两个操作数的每一位相与
逻辑与是把两个操作数进行真假判断
注意:逻辑操作符有一个重要的特性
逻辑与:当现在的条件已经为假,则后续条件不需要判断
逻辑或:当现在的条件已经为真,则后续条件不需要判断
8、条件操作符
条件操作符也称为三目操作符
Exp1 ? Exp2 : Exp3
若条件Exp1成立,返回Exp2的值,否则返回Exp3的值
9、逗号表达式
逗号表达式,就是用逗号隔开的多个表达式
Exp1,Exp2,Exp3,...,Expn
表达式以此执行,但是结果是最后一个表达式的结果
10、下标引用、函数调用和结构
1、[ ] 下标引用操作数
操作数:一个数组名 + 一个索引值
Array[10]; //访问下标为10的元素,也就是数组中的第11个元素
2、( ) 函数调用操作符 接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数
void add(int x, int y){
printf("%d\n", x + y);
}
int main(){
int x = 10;
int y = 20;
add(10, 20);
}
3、访问一个结构体的成员
1、结构体 . 成员名
2、结构体指针 -> 成员名
typedef struct Stu{
int Id;
char Name[1024];
int Age;
}Stu_d;
void ChangeAge(struct Stu_t student){
student->Age = 25; //以结构体指针->成员名访问
}
int main(){
struct Stu_t zhangsan = {160245,"zhangsan",22};
ChangeAge(zhangsan);
printf("%d\n",zhangsan.Age); //以结构体.成员名访问
}
好了,以上就是C语言的一些常用的操作符,我们详细的讨论了每一种操作符的用法,希望对大家有所帮助。
笔者自身能力浅薄,若有疏漏,请联系我及时改正。
@YeLing0119