【C语言 4】 操作符

本文详细介绍了C语言中的各种操作符,包括算术操作符如加减乘除和求余,移位操作符如左移和右移,位操作符如与、异或和或,以及赋值、单目、关系、逻辑、条件和逗号操作符。文章还讨论了整型提升和操作符的属性,提供了示例代码来帮助理解其用法和优先级。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

操作符

1. 算术操作符

+ - * / %
加减乘除我们就不多说了,会涉及到数据转换,详细请看数据类型篇。

//1.%求余数的妙用
//s=i%5;这说明s的取值只能是0 1 2 3 4,但是数据有可能会溢出,所以这时候我们需要用 unsigned,才让他重新回到0。
//0%5 ——》》0除5等于0余0
//1%5 ——》》0除5等于0余1
for (unsigned char a = 125; a < 256; a++)//永远到达不了256,无线循环
{
printf("%d\n",a%4);
}

2. 移位操作符

>>右移操作符
<<左移操作符
我们知道,计算机里面存储数据的方式是以反码的形式进行存储,那么移位操作符就是移位计算机中反码的二进制位。
对于移位运算符,不要移动负数位,num<<-1是错误的。

2.1 左移操作符

左边抛弃、右边补0

//2.操作符
int num = 10;
num=num<<1;
//   		00000000 00000000 00000000 00001010
//去(0)	  00000000 00000000 00000000 0001010(0)补
printf("%d",num);//

2.2 右移操作符

  • 逻辑移位:左边用0填充,右边丢弃
  • 算术移位:左边用原该值的符号位填充,右边丢弃
    计算机采用的是算术移位,符号填充,右边丢弃
//2.操作符
int main()
{
	int num = -2;
	num = num >> 1;
	//   	  11111111 11111111 11111111 11111110		(补码形式)
	//	  补(1)1111111 11111111 11111111 11111111 去(0)
	printf("%d", num);//-1
	return 0;
}

3. 位操作符

& ^ |(与、异或、或)
位操作符对补码形式行进位操作。

3.1 &与操作符用于对某一位进行清0,在单片机中对寄存器操作

0110 0011 & 1101 1111=0100 0011(单片机用法)
常用来清零某位,其他位可以不变,0很重要

3.2 |或操作用于对某一位置1

0011 0011 | 1000 0000=1011 0011
常用来置1某位,然后其他位不变
不能创建临时变量(第三个变量),实现两个数的交换。
方法1:
a=5,b=3;
a=a+b;(容易溢出)
b=a-b;
a=a-b;

方法2;0101 ^  0011(没有进位)
a=a^b;0110
b=a^b;0101 5b=a^b^b=a^0=a;
a=a^b;00113

//3.位操作符
int main()
{
	int a = 3, b = 5;     //	   0011  0101
	a = a ^ b;			  //0110 = 0011 0101
	b = a ^ b;			  //0011 = 0110 0101
	a = a ^ b;
	printf("%d\n",a);
	printf("%d\n",b);
}


4. 赋值操作符

= += -= *= /= &= ^= |= >>= <<=
这个就不多说了。

5. 单目操作符

  • ! 逻辑反操作a=5;!a=0;

  • ~ 对一个数的二进制按位取反a=5;~a=-6

  • & 取地址

  • sizeof 操作数的类型长度(以字节为单位)sizeof()括号可以省略,所以他是一个操作符,不是函数。计算数组元素大小=sizeof(arr)/sizeof(arr[0])

  • – 前置、后置

  • ++ 前置、后置
    b=++a;先加加后使用
    b=a++;先使用后加加

  • *间接访问操作符(解引用操作符)
    int p=&a;*p=5解引用指针p;a=5

  • (类型) 强制类型转换

6. 关系操作符

>=
<
<=
!=      用于测试“不相等”
==      用于测试“相等”

7. 逻辑操作符

&&     逻辑与
||     逻辑或
//4.逻辑操作符&& ||

int main()
{
	int i = 0, a = 0, b = 2, c = 3, d = 4;
	i = a++ && ++b && d++;
	// a++ 后置++__a=a+1,因为a先使用了,所以与后面&&等于0,编译器会直接忽略后面的不计算
	printf(" a = %d\n b = %d\n c = %d\n d = %d\n i = %d\n", a, b, c, d,i); //1 2 3 4  i=0;
	return 0;
}

8. 条件操作符(三目运算符)

exp1 ? exp2 : exp3
a=exp1 ? exp2 : exp3;如果是真,那么a=exp2
在return 中的使用
return exp1 ? exp2 : exp3;正确用法
exp1 ? return exp2 : return exp3;//错误用法

9. 逗号表达式

exp1, exp2, exp3, …expN
以最后一个表达式的结果为结果

10. 下标引用、函数调用和结构成员

[]
() 函数调用操作符
.
->结构体引用

11. 整形提升

C的整型算术运算总是至少以缺省整型类型的精度来进行的。为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升。

//5.整型提升
int main()
{
	char c = 1;
	printf("%u\n", sizeof(c));
	printf("%u\n", sizeof(+c));  //提升,这里C++和++C都不行,因为C=C+1,已经运算完然后回归char型了,这里是数据类型运算
	printf("%u\n", sizeof(-c));	//提升
	printf("%u\n", c);
	//1 4 4 1
	return 0;
}

int a;
int b;
a+b;//每个变量都有两个属性,值属性和类型属性
我们上面说sizeof不参与运算,的确是的,他printf(“%u\n”, sizeof(1+c));这里只要类型属性就够了,它不需要值属性,所以C从头到尾都是1

12. 操作符的属性

虽然我们知道了操作符的优先级,但是有些代码还是错误的

//6.操作符的属性
#include<stdio.h>
int fun()
{
	static int count = 1;
	return ++count;
}
int main()
{
	int answer;
	answer = fun() - (fun() * fun());//这里涉及到,如果按照优先级应该是 4-2*3=1;但是编译器先准备的是前面的 2-3*4=-10
	printf("%d\n", answer);//输出-10
	return 0;
}
int main()
{
int a = 2;
int* p = &a;
*p++;//后置++,故意让你先解引用。*p没做什么操作,然后p+1,所以p=&a+1,a=2
printf("%p,%p,%d",&a,p, a);
return 0;
}

总结:
对于操作符,我们有些时候很难记清他们的操作符,比如+= *=的这种优先级很低,前置和后置++的优先级很高,只不过他的意图是先让你运用还是先让你++又或者a=1,(++a)+(++a)+(++a)的结果是不确定的,因为我们不知道到底先准备a还是先++,如果先准备a,那么所有a都相同,如果先++,a不同
所以,面对大量的运算符,我们最好多用一些括号。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

太阳予野花

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值