【C语言】操作符大全万字详解

昨天已成为历史,明天是未知的,而今天是上天赐予我们的礼物,这就是为什么我们把它叫做现在!——《功夫熊猫》


目录

1、操作符的分类

2、算术操作符

2.1+、-、*(加减除)

2.2 /、%(除取余)

3、移位操作符

3.1原码反码补码

3.2<<(左移操作符)

3.3>>(右移操作符)

4、位操作符

4.1& (按位与)

4.2 |(按位或)

4.3 ^ (按位异或)

5、赋值操作符

6、单目操作符

6.1!(逻辑反操作)

6.2-(负值)、+(正值)

6.3&(取地址)

6.4sizeof(取字节操作符)

6.5~(二进制位取反)

6.6--、++(前后置--、++)

6.7*(间接访问操作符、解引用操作符)

6.8sizeof和数组

7、关系操作符

8、逻辑操作符

8.1&&、||(逻辑与逻辑或)

9、条件操作符

9.1?:三目操作符

10、逗号表达式

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

11.1[]下标引用操作符

11.2()函数调用操作符

11.3.、->结构体访问操作符

12、表达式求值

12.1一些有问题的表达式

12.2操作符优先级表格


前言:

大家好我是拳击哥,今天我给大家展现是C语言中各种各样的操作符。操作符是说明特定操作的符号,它是构造C语言表达式的工具,下面我就来介绍它们的详细用法,并且目录12.2中有从高到低的操作符优先级表格供大家参考。


1、操作符的分类

操作符分为:

  • 算术操作符
  • 移位操作符
  • 位操作符
  • 赋值操作符
  • 单目操作符
  • 关系操作符
  • 逻辑操作符
  • 条件操作符
  • 逗号表达式
  • 下标引用、函数调用和结构成员

2、算术操作符

算术操作符有:+(加)、-(减)、*(乘)、/(除)、%(取余、取模)

2.1+、-、*(加减除)

+、-、*(加减除)跟我们数学中的意思是一致的,我们来看一组代码:

#include<stdio.h>

int main()
{
	int a = 5;
	int b = 5;
	int c = 0;
	c = a + b;
	printf("%d\n", c);
	c = a - b;
	printf("%d\n", c);
	c = a * b;
	printf("%d\n", c);
	return 0;
}

输出结果:

10

0

25


2.2 /、%(除取余)

 /、%(除、取余)跟我们数学中的除法和取余有较大差别,我们先来看一组程序:

#include<stdio.h>

int main()
{
	int a = 10;
	int b = 3;
	printf("%d\n", a/b);//除法
	printf("%d\n", a%b);//取余
    printf("%f\n", a / 2.0);//除法可以有小数,%不允许有小数
	return 0;
}

输出结果:

3

1

5.000000


可以看到C语言中的除法返回值是除数,取余返回的是余数。并不像数学那般得到小数。并且C语言中只有除法/两边能有小数,取余%则不能。5.0000000因为浮点数编译器默认打印六位0,您可以在f前面加.n代表你要保留几位小数。如:%.3f保留三位小数。

  • 除了 % 操作符之外,其他的几个操作符(+、-、*、/)可以作用于整数和浮点数。
  • 对于 / 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。
  • % 操作符的两个操作数必须为整数。返回的是整除之后的余数。

3、移位操作符

<<(左移)、>>(右移)

3.1原码反码补码

在计算机中数据是按二进制存储的,二进制有三种形式分为原码、反码、补码。数字是用原码表示的,但在内存中的存储是以补码的形式存储的。

int main()
{
	int a = 10;
	int b = -10;
	return 0;
}

以上定义了整形a和b两个变量,整数分为正数负数。正数负数补码的形式也是不同的。正数的原码、反码、补码都是一样的,且符号位为0。负数的反码是原码的符号位不变其余位按位与,补码则是反码加1。因为是32位操作系统,a和b是整形,整形占4个字节,所以有32个bit位。

首先我们看a的原码、反码、补码:

10的原码:00000000 00000000 00000000 00001010

10的反码:00000000 00000000 00000000 00001010

10的补码:00000000 00000000 00000000 00001010

我们可以看到正数的原码、反码、补码都是一样的,且符号位为0。符号位就是第一位数


 我们再来看b的原码、反码、补码:

-10的原码:10000000 00000000 00000000 00001010

-10的反码:111111111 111111111 111111111 111110101

-10的补码:111111111 111111111 111111111 111110110

负数的原码、反码、补码。负数的原码符号位是1,反码是原码的符号位不变其余位按位与,补码则是反码+1。

符号位不变就是这一串二进制的第一位1不变,其余位按位与的意思是其余的所有位的1变为0,0变为1。


3.2<<(左移操作符)

有了原码、反码、补码的理解后,我们来了解左移操作符(<<)。移位规则:左边抛弃、右边补0

#include<stdio.h>

int main()
{
	int a = 10;
	int b = -10;
	int c = a << 1;
	int d = b << 1;
	printf("%d ", c);
	printf("%d\n", d);
	return 0;
}

 输出结果:20 -20

左移操作符具体怎么移呢,左移时。这个数的补码往左移动一位,移动后的补码最左边的那一位丢弃最右边空着的位补0。我们来看一个图理解:

从侧面说明了左移一位也就代表着这个数乘以2,这个数可以是正数或负数。 


3.3>>(右移操作符)

(>>)右移操作符与左移操作符有些许不同分为两种;

  • 算术移位,左边用原该值的符号位填充,右边丢弃。
  • 逻辑移位,左边用0填充,右边丢弃。

#include<stdio.h>

int main()
{
	int a = 10;
	int b = -10;
	int c = a >> 1;
	int d = b >> 1;
	printf("%d ", a);
	printf("%d ", b);
	printf("%d ", c);
	printf("%d\n", d);
	return 0;
}

输出结果:10 -10 5 -5 


右移分为算术移位和逻辑移位,我们首先来看算术移位,算术右移就是整个补码往右边移动一位,移动完后,最左边的空着的位数补符号位,最右边的多出的一位丢弃。我们来看一个图理解:

从侧面说明了,这个数右移一位就是这个数除以2。以上程序就是算术右移。 


我们再来看逻辑移位,逻辑右移就是整个补码往右边移动一位,移动完后,最左边的空位补0,最右边多的一位丢弃。我们也来看一个图理解:


注意:一个数值在内存中存放的是补码,但是补码的二进制转换成的十进制数并不是我们实际的数值。当我们知道一个数值的补码时,正数的原反补码都是一样的我们直接化成十进制就好了。而负数的补码我们可以通过原码变成补码这个过程逆序求出原码。也就是补码-1然后符号位不变其余位取反得到的就是原码。

警告 :对于移位运算符,不要移动负数位。


4、位操作符

位操作符有:& (按位与)、| (按位或)、^ (按位异或)。他们的操作数必须是整数,我们来看一组代码:

#include<stdio.h>

int main()
{
	int a = 10;
	int b = -10;
	printf("%d ", a & b);
	printf("%d ", a | b);
	printf("%d\n", a ^ b);
}

输出: 2 -2 -4


 位操作符也是按照补码来进行运算的,首先我们得到a的补码

原码、反码、补码:00000000 00000000 00000000 00001010

我们再来求b的补码

原码:10000000 00000000 00000000 00001010

反码:11111111 11111111 11111111 11110101

补码:11111111 11111111 11111111 11110110

知道了a和b的补码,我们来讲解& (按位与)、| (按位或)、^ (按位异或)。


4.1& (按位与)

& (按位与)就是两个数的补码相与时只要有一个数为0则整个表达式的结果为0,我们来看一个图理解:


4.2 |(按位或)

 |(按位或)就是两数补码相或时只要有一个数为1,则整个表达式结果为1,我们也来看一个图理解:


4.3 ^ (按位异或)

^ (按位异或)就是两数补码异或时,两数不同时为1相同时为0,我们来看图理解:


🤼‍♀️ 练习:不创建临时变量,实现两个数的交换。

//方法1
#include<stdio.h>

int main()
{
	int a = 5;
	int b = 2;
	a = a + b;
	b = a - b;
	a = a - b;
	printf("a=%d b=%d\n", a, b);
	return 0;
}
//方法2
#include<stdio.h>

int main()
{
	int a = 5;
	int b = 2;
	a = a ^ b;
	b = a ^ b;
	a = a ^ b;
	printf("a=%d b=%d\n", a, b);
	return 0;
}

输出的都是:a=2 b=5 

方法2中用到了异或,异或在二进制是相同为0不相同为1,那么此题中是什么样呢:

第一步,a=a^b;把a,b化为二进制,a:101,b:010。异或后111,此时a=7

第二步,b=a^b;把此时的a,b化为二进制,a:111,b:010。异或后101,此时b=5

第三步,a=a^b;把此时的a,b化为二进制,a:111,b:101。异或后010&

评论 41
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一只爱打拳的程序猿

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

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

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

打赏作者

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

抵扣说明:

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

余额充值