【C语言初阶】8 操作符详解

1. 算数操作符

  1. 算数操作符包括+、-、*、/
  2. 对于 / 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。
  3. % 操作符的两个操作数必须为整数。返回的是整除之后的余数。

2. 移位操作符

<< 左移 >> 右移
移位操作符针对的是整数的二进制位

移位规则:

右移运算分两种:

  1. 逻辑移位
    左边用0填充,右边丢弃
  2. 算术移位
    左边用原该值的符号位填充,右边丢弃
    在这里插入图片描述
    一般编译器采用的都是算数右移,算数右移也更符合规则

3. 位操作符

& //按位与
| //按位或
^ //按位异或

不能创建临时变量(第三个变量),实现两个数的交换。

// 采用异或的方法
//3^3 = 0 -> a^a=0
//011
//011
//000
//0^5=5 -> 0^a = a
//000
//101
//101
//
//3^3^5 = 5
//3^5^3 = 5
//异或操作符支持交换律
//011
//101
//110
//011
//101
int main()
{
	int a = 3;
	int b = 5;

	printf("交换前:a=%d b=%d\n", a, b);
	a = a ^ b;//a=3^5
	b = a ^ b;//3^5^5 --> b=3
	a = a ^ b;//3^5^3 --> a=5
	printf("交换后:a=%d b=%d\n", a, b);
	return 0;
}

通常交换两个变量的值采用创建临时变量的方法,更加高效(但这种方法可能有溢出的风险)

4. 赋值操作符 =

==关系操作符和=赋值操作符不能混淆

5. 单目操作符

5.1 !逻辑反操作

int main()
{
	int flag = 3;
	//flag为真,进入if
	if (flag)
	{}
	//flag为假,进入if
	if(!flag)
	{}
	return 0;
}

在C语言未引入bool类型时,用!(逻辑反)来表示真假

5.2 sizeof 操作符

#include <stdio.h>
int main()
{
	int a = -10;
	printf("%d\n", sizeof(a));
	printf("%d\n", sizeof(int));
	printf("%d\n", sizeof a);//这样写行不行?
	printf("%d\n", sizeof int);//这样写行不行?
	return 0;
}

sizeof a 可以,但sizeof int 不行 进而说明sizeof并不是函数,函数是一定要带括号的
而strlen是库函数,是用来求字符串长度

5.3 ~ 按位取反操作符

	int a = 0;
	//~ 是按二进制位取反
	//00000000000000000000000000000000 - 补码
	//11111111111111111111111111111111 -> ~a
	//11111111111111111111111111111110
	//10000000000000000000000000000001
	//-1
	printf("%d\n", ~a);//-1

	int a = 3;
	//00000000000000000000000000000011
	//11111111111111111111111111111100 - 补码
	//11111111111111111111111111111011
	//10000000000000000000000000000100
	//-4

按二进制取反后,因为计算机存储的形式是补码,而在控制台显示的都是原码形式

5.4 前置++,后置++

	int a = 3;
	//int b = ++a;//前置++,先++,后使用
	//a=a+1,b=a;
	int b = a++;//后置++,先使用,再++
	//b=a, a=a+1
	printf("%d\n", a);//
	printf("%d\n", b);//
	int a = 3;
	int b = a--;
	//b=a,a=a-1
	//int b = --a;//前置--,先--,后使用
	//a=a-1,b=a
	printf("%d\n", a);//2
	printf("%d\n", b);//3

这里的使用指的是给表达式赋值,在函数传参时若是前置先++,再传过去;若是后置++,先传过去再++;

6.关系操作符

>= <= ==...
不是所有类型判断相等都是采用==,两个字符串判断相等应该用strcmp

7.逻辑操作符

逻辑操作符包括 逻辑或|| 逻辑与&& 存在控制求值顺序
&& 左边为假,右边就不计算了 || 左边为真,右边就不计算了
在这里插入图片描述

8. 条件操作符

在这里插入图片描述
若表达式1为真,返回表达式2的值,表达式3不计算

9.逗号表达式

逗号表达式,就是用逗号隔开的多个表达式。
逗号表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果。

10. [ ] 下标引用操作符

操作数:一个数组名 + 一个索引值

int arr[10];//创建数组
 arr[9] = 10;//实用下标引用操作符。
 [ ]的两个操作数是arr和9

arr[9]的形式还可以写成9[arr] arr[9] 其实就是*( arr + 9 ) => *(9+arr) => 9[arr]

11. 表达式求值

11.1 隐式类型转换

为了获得缺省整型(int)精度,表达式中的字符(char)和短整型(short)操作数在使用之前被转换为普通(int)整型,这种转换称为整型提升。
在这里插入图片描述

int main()
{
	char a = 5;
	//00000000000000000000000000000101
	//00000101 - a
	char b = 126;
	//00000000000000000000000001111110
	//01111110 - b
	char c = a + b;
	//00000000000000000000000000000101 - a
	//00000000000000000000000001111110 - b
	//00000000000000000000000010000011
	//10000011 - c
	//11111111111111111111111110000011 - 补码
	//11111111111111111111111110000010
	//10000000000000000000000001111101
	//
	printf("%d\n", c);//-125
	return 0;
}

char、short类型只要出现在表达式当中就会出现整型提升的现象

int main()
{
	char a = 0xb6;
	short b = 0xb600;
	int c = 0xb6000000;

	if (a == 0xb6)
		printf("a");

	if (b == 0xb600)
		printf("b");

	if (c == 0xb6000000)
		printf("c");

	return 0;
}

上述代码只有c打印成功,a,b都发生整型提升,最高位为1 整型提升补1(也就是负数)肯定不相等
在这里插入图片描述

11.2 算术转换(强制类型转换)

在这里插入图片描述
如果在表达式当中出现不同类型的变量,首先要转换为更高的操作数类型后执行运算。

12. 操作符的属性

在这里插入图片描述
后缀++的优先级高于+,+的优先级高于前缀++
复杂表达式的求值有三个影响的因素。

  1. 操作符的优先级
  2. 操作符的结合性
  3. 是否控制求值顺序。
    两个相邻的操作符先执行哪个?取决于他们的优先级。如果两者的优先级相同,取决于他们的结合性。
    尽管知道了两个操作符的优先性与结合性,有时候还是无法得到唯一结果
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    代码中的变量是static静态的,无法确定那个fun()是先执行的,这就产生了歧义

总结:我们写出的表达式如果不能通过操作符的属性确定唯一的计算路径,那这个表达式就是存在问题
的。
(尽量避免)

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值