【C语言】——详解操作符(上)

一、 操作符的分类

  • 算数操作符:+ 、 - 、* 、/ 、%
  • 位移操作符:<< 、 >>
  • 位操作符: & 、 | 、^ 、 ~
  • 赋值操作符:= 、 += 、 -= 、 *= 、 /= 、 %= 、 <<= 、 >>= 、 &= 、 |= 、 ^=
  • 单目操作符: ! 、 ++ 、 -- 、 & 、 * 、 + 、 - 、 ~ 、 sizeof 、(类型)
  • 关系操作符:> 、 >= 、 < 、 <= 、 == 、!=
  • 逻辑操作符:&& 、 ||、!
  • 条件操作符:? 、:
  • 逗号表达式:
  • 下标引用: [ ]
  • 函数调用: ( )
  • 结构成员访问: . 、->
      
      

二、 算数操作符

+ + + − - ∗ * 、/ 、%

  我们在写代码时,一定会涉及运算。

  C语言中,为了方便运算,提供了算术操作符,他们都是双目操作符

2.1、 + + + − - ∗ *

   + + + − - 以及 ∗ * 是用来完成加法、减法和乘法的.
   他们都有两个操作数,位于操作符两端的就是他们的操作数。因此,这种操作符也叫做双目操作符
  
代码示例:

#include<stdio.h>

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

运行结果:
在这里插入图片描述

2.2、 / / / 操作符

   说到C语言中的除法运算,我想先给大家看个例子:

#include<stdio.h>

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

  代码的运行结果是什么?会得到 2.5 2.5 2.5 吗?让我们一起来看看运行结果:

这里是引用
  为什么会这样呢?明明存放结果的变量类型已经是浮点型 ( f l o a t ) (float) (float) 了呀,为什么小数部分还是 0 0 0 呢?
  原因在于C语言中的整数除法是整除,只会返回整数部分,丢弃小数部分.
  
  如果希望得到浮点数的结果,两个运算符必须至少有一个浮点数,这时 C 语言就会进行浮点数除法.
  
参考代码:

#include<stdio.h>

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

运行结果:
在这里插入图片描述
  哈哈哈,没想到吧!只有除数或被除数是浮点型 ( f l o a t ) (float) (float) 也是不行的哦,结果也是要浮点型 ( f l o a t ) (float) (float)
  
参考代码:

#include<stdio.h>

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

运行结果:
在这里插入图片描述
  

2.3、 % 操作符

  操作符 % 表示求模运算,即返回两个整数相除的余值。这个操作符只能用于整数,不能用于浮点数
  
  同时,负数求模的规则是:结果的正负号由第一个运算数的正负号决定
  
参考代码:

#include<stdio.h>

int main()
{
	printf("%d\n", 11 % 5);
	printf("%d\n", 11 % -5);
	printf("%d\n", -11 % 5);
	printf("%d\n", -11 % -5);
	return 0;
}

运行结果:
在这里插入图片描述
  
  

三、 位移操作符

左移操作符 : < < << <<
右移操作符 : > > >> >>

注:位移操作符的操作数只能是整数。

3.1、 原码、 反码、 补码

  位移操作符实质上是对数据的二进制位进行操作,因此了解整数二进制表示方法至关重要。
  

  整数的二进制表示方法三种:

  • 原码
  • 反码
  • 补码

  对于 ( s i g n e d ) i n t (signed )int signedint (有符号整型),它的三种表示方法均分为符号位数值位两个部分。二进制序列中,最高位被当做符号位,剩余的都是数值位
  
  符号位都是用 0 0 0 表示,用 1 1 1 表示

  • 正整数的原、 反、 补码都相同
  • 负整数的三种表示方法各不相同

(1)原码

  直接将数值按照正负数的形式翻译成二进制得到的就是原码。

示例一:

#include<stdio.h>
int main()
{
	int a = -10;
	return 0;
}
  • -10是存放在 a a a 中, a a a 是整型变量,有4个字节,即32个bit位
  • 10的二进制为:1010
    在这里插入图片描述
  • -10为负数,负数用最高位 1 来表示
    在这里插入图片描述
  • 因为一共4个字节,中间位用 0 补为位在这里插入图片描述

(2)反码

  将原码的符号位不变,其他位依次按位去反,即反码

这里是引用

(3)补码

  反码 +1 就得到补码

在这里插入图片描述

  
示例二:

#include<stdio.h>
int main()
{
	int a = 10;
	return 0;
}

而对于正数来说,它的三种表示方法相同:
在这里插入图片描述

  

补码得到原码:

  • − 1 -1 1 ,取反
  • 取反, + 1 +1 +1

对于整型来说:数据存放内存中都是用补码进行运算和存储
  
  原因在于,使用补码,可以将符号位和数值位统一处理;同时,加法和减法也可以统一处理(CPU只有加法器)此外,补码和原码相互转换,其运算过程是相同的(取反, + 1 +1 +1),不需要额外的硬件电路。
  

3.2、 左移操作符 <<

  
  移位规则:左边抛弃、右边补 0
  
在这里插入图片描述
注:调试时,在需要观测的整型变量后面加上 “ , b ,b ,b ”,即为其二进制表示。
  
运行结果:
在这里插入图片描述
图示:

在这里插入图片描述

  

3.3、 右移操作符 >>

  移位规则:首先右移运算分为两种:

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

注:大部分编译器都是算术右移
在这里插入图片描述
运行结果:
在这里插入图片描述
图示:

在这里插入图片描述

在这里插入图片描述


注:对于移位操作符,不要移动负数位,这个标准是未定义的!

int a = 10;
a >> -1//error

四、 位操作符

位操作符有:

&  按位与
|  按位或
^  按位异或
~  按位取反

注:他们的操作数必须是整数,且操作的都是二进制位

(1)&按位与
  
  逻辑:有 0 为 0,全 1 为 1

在这里插入图片描述
运行结果:
在这里插入图片描述

图示:

在这里插入图片描述

(2)|按位或
  
  逻辑:有 1 为 1,全 0 为 0
  
在这里插入图片描述
运行结果:
在这里插入图片描述

图示:

在这里插入图片描述

(3)^按位异或
  
  逻辑:相同为 0,相异为 1
  
在这里插入图片描述
运行结果:
在这里插入图片描述
图示:
在这里插入图片描述
(3)~按位取反
  
在这里插入图片描述
运算结果:
在这里插入图片描述

五、 赋值操作符

= 、 += 、 -= 、 *= 、 /= 、 %= 、 <<= 、 >>= 、 &= 、 |= 、 ^=

5.1、 = = = 操作符

  
  在创建变量的时候给一个值初始值叫初始化,在变量创建好后,再给一个值,这叫赋值。

int a = 0;//初始化
a = 200;//赋值,这里使用的就是赋值操作符

  赋值操作符 = = = 是一个随时可以给变量赋值的操作符。
  
  赋值操作符也可以连续赋值,如:

int a = 3;
int b = 5;
int c = 0;
c = b = a + 5;//连续赋值,从右向左依次赋值

  注:C语言虽然支持这种连续赋值,但是写出的代码不易理解,建议还是拆开来写,这样方便观测代码的执行细节。
  

5.2、 复合赋值操作符

  
  在写代码时,我们可能经常对一个数自增、自减的操作:

int a = 10;
a = a + 3;
a = a - 2;

  这样代码C语言提供了更加方便的方法:

int a = 10;
a += 3;
a -= 2;

  C语言中提供了复合赋值符,方便我们编写代码,这些附值符有:

+= 、 -= 、 *= 、 /= 、 %= 、 <<= 、 >>= 、 &= 、 |= 、 ^=

  

六、 单目操作符

! 、 ++ 、 -- 、 & 、 * 、 + 、 - 、 ~ 、 sizeof 、(类型)

  在C语言中,有些操作符只有一个操作数,他们被称为单目操作符

6.1、 ++ 与 – –

  ++是一种自增操作符,分为前置++和后置++,– –是一种自减操作符,也分为前置– –和后置 – –

(1)前置++
#include<stdio.h>

int main()
{
	int a = 10;
	int b = ++a;

	printf("%d %d\n", a, b);
	return 0;
}

运行结果:
在这里插入图片描述

  这段代码中, a a a 原来是 10 ,先 +1 , a a a 变为11使用就是赋值给 b b b b b b 得到的也是11,所以 a a a b b b 都是 11。

  计算口诀:先 +1,后使用

相当于以下代码:

#include<stdio.h>

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

  

(2)后置++
#include<stdio.h>

int main()
{
	int a = 10;
	int b = a++;

	printf("%d %d\n", a, b);
	return 0;
}

运行结果:
在这里插入图片描述

  上述代码中, a a a 原来是10,先使用,就是先赋值给 b b b b b b 得到了10,然后 a a a 自增成了11,所以运行结果 a a a 是11, b b b 是10.

  计算口诀:先使用,后 +1

相当于如下代码:

#include<stdio.h>

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

  

(3) – –

  – – 操作符和 ++ 原理一样,只是自增变成自减而已,这里就不再过多赘述了,下面给段代码大家一起来检验一下吧

#include<stdio.h>

int main()
{
	int a = 10;
	int b = a--;
	int c = --a;

	printf("%d %d %d\n", a, b, c);
	return 0;
}

运行结果:
在这里插入图片描述
  怎么样,你做对了吗?
  

6.2、 + 和 –

  这里的 + 是正号, 是负号,他们都是单目操作符
  
  操作符 + 对正负值没有影响,是一个完全可以省略的操作符,但是写了也不会报错

#include<stdio.h>

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

在这里插入图片描述
  
  操作符 用来改变一个正值的正负号,在负数的前面加上 就会得到正数,在正数前面加上就会得到负数。

#include<stdio.h>

int main()
{
	int a = 10;
	int b = -a;
	int c = -10;
	printf("b = %d c = %d\n", b, c);

	int aa = -10;
	int bb = -aa;
	printf("bb = %d\n", bb);
	return 0;
}

在这里插入图片描述
  

6.3、 强制类型转换

  在操作符中还有一种特殊的操作符是强制类型转换,语法形式很简单,如下:

(类型)

  
请看代码:

#include<stdio.h>

int main()
{
	int a = 3.14;
	printf("%d/n", a);
	return 0;
}

在这里插入图片描述
  为了消除这个警告,我们可以使用强制类型转换:

#include<stdio.h>

int main()
{
	int a = (int)3.14;
	printf("%d\n", a);
	return 0;
}

  但,俗话说:强扭的瓜不甜,我们使用强制类型转换都是万不得已的时候使用,如果不需要强制类型转换就能实现代码,这样自然最好。
  

6.4、sizeof

  看到这,是不是很惊讶呢,没错! s i z e o f sizeof sizeof 并不是函数,而是一个操作符
   s i z e o f sizeof sizeof 是一个关键字,也是一个操作符是专门用来计算类型长度的,单位是字节
  
   s i z e o f sizeof sizeof单目操作符,操作数可以是类型,也可以是变量或者表达式

sizeof(类型)
sizeof 表达式
  • s i z e o f sizeof sizeof 的操作数如果不是类型,是表达式的时候,可以省略后边的括号的。
  • s i z e o f sizeof sizeof 后边的表达式是不真实参与运算的,根据表达式的类型雷得出大小。
  • s i z e o f sizeof sizeof 的计算结果是 s i z e size size_ t t t 类型的。

   s i z e o f sizeof sizeof 操作符的返回值,C语言只规定是无符号整数,并没有规定具体类型,而是留给系统自己决定。 s i z e o f sizeof sizeof 到底返回什么类型,在不同的系统中,返回值的类型有可能是 u n s i g n e d unsigned unsigned i n t int int ,也有可能是 u n s i g n e d unsigned unsigned l o n g long long,甚至是 u n s i g n e d unsigned unsigned l o n g long long l o n g long long。他们对应的 p r i n t f () printf() printf() 占位符分别是 % u u u、% l u lu lu和 % l l u llu llu。这样不利于程序的可移植性。
  C语言提供了一个解决方法,创造了一个类型别名 s i z e size size_ t t t,用来统一表示 s i z e o f sizeof sizeof 的返回值类型。对应当前系统的 s i z e o f sizeof sizeof 的返回值类型,可能是 u n s i g n e d unsigned unsigned i n t int int ,也可能是 u n s i g n e d unsigned unsigned l o n g long long l o n g long long

比如:

#include<stdio.h>

int main()
{
	int a = 10;
	printf("%zd\n", sizeof(a));
	printf("%zd\n", sizeof a);//a是变量的名字,可以省略sizeof后面的()
	printf("%zd\n", sizeof(int));
	printf("%zd\n", sizeof(3 + 3.5));
	return 0;
}

在这里插入图片描述
   s i z e o f sizeof sizeof中表达式不计算 !

#include<stdio.h>

int main()
{
	short s = 2;
	int b = 10;
	printf("%d\n", sizeof(s = b + 1));
	printf("s = %d\n", s);
	return 0;
}

   s i z e o f sizeof sizeof 在进行编译的时候,就根据表达式的类型确定了,而表达式的执行却要在程序运行期间才能执行,在编译期间已经将 s i z e o f sizeof sizeof 处理掉了,所以在运行期间就不会再执行表达式了。
  

6.5、!

  在C语言中:0 为假,非 0 为真(负数也为真)
   操作符作用是:逻辑取反
  
图示:

在这里插入图片描述

  
  比如,我们有一个变量 f l a g flag flag,如果 f l a g flag flag 为假,要做一个什么事情,就可以这样写代码:

#include<stdio.h>

int main()
{
	int flag = 0;
	if (!flag)
	{
		printf("do something\n");
	}
	return 0;
}

  如果 f l a g flag flag 为真, ! f l a g !flag flag 就是假,如果 f l a g flag flag 为假, ! f l a g !flag flag 就是真
  所以上面的代码意思是 f l a g flag flag 为假,执行 i f if if 语句中的代码.
  
  
  剩下的两个单目操作符 & ∗ * ,将在之后指针内容一起介绍,敬请期待!

  • 51
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值