【初阶C语言】操作符1--对二进制的操作

简介: 本节内容介绍的操作符,操作的对象是二进制位。所以前面先介绍整数的二进制位

一、二进制位介绍

1.二进制介绍

(1)整数的二进制表示形式有三种:原码、反码和补码。


(2)原码、反码和补码的长度有数据类型来决定,如整数,就是四个字节,转化后是三十二位比特位,所以一个整数写成二进制序列的时候,是32个bit位。


(3)数据是以补码的形式在内存中存储的。


(4)正负数原码、反码和补码不一样


2.正数三码的介绍

(1)正数的原码、反码和补码都一样,不需要计算,可以直接得出来。


(2)举例


7,我们先把7转化成二进制数:111;由于整数的二进制序列是32位,所以其他我需要补0,就写成这样


原码:00000000 00000000 00000000 00000111

反码:00000000 00000000 00000000 00000111

补码:00000000 00000000 00000000 00000111


3,二进制数为:11  二进制序列:


原码:00000000 00000000 00000000 00000011

反码:00000000 00000000 00000000 00000011

补码:00000000 00000000 00000000 00000011


3.负数三码的介绍

我们接下来重点介绍负数的原码、反码和补码


(1)原码


对于有符号的整数来说,最高位的一位是符号位;符号位是1表示负数,符号位是0表示正数。若是无符号数,没有符号位,所有位都是有效位。数字0则当成无符号数来看待。


正数:

image.png

负数:

image.png

对于有符号数来说,正负数原码的差异就是在最高位。


(2)反码

1.反码,顾名思义就是取反。

定义:反码是在原码的基础上,除了符号位,其他按位取反,1的话就写成0,0就写成1。

2.-7的反码


原码:10000000 00000000 00000000 00000111

反码:11111111  11111111   11111111  11111000


(3)补码


1.定义:补码则是在反码的基础上+1。


2.-7的补码


原码:10000000 00000000 00000000 00000111

反码:11111111  11111111   11111111  11111000

补码:11111111  11111111   11111111  11111001


而补码,就是数据在内存中的存储形式。所以整数在计算的时候使用的也是补码。


总结:三码的转换规则:原码----(取反)--->反码-----(+1)---->补码


补码----(-1)--->反码----(取反)--->原码


补码----(取反,+1)--->原码


二、移位操作符

前言:移位操作符包括左移操作符(<<)和右移操作符(>>)


1.左移操作符(<<)

(1)常用口诀:左边丢弃,右边补0


(2)代码演示

#include<stdio.h>
int main()
{
  int a = 7;
  int b = a << 1;//a向左移动一位
  printf("%d\n",a);//a的本质没有改变
  printf("%d\n",b);
  return 0;
}

代码结果:

image.png

由上面很清楚的就可以知道,其实a的值还是-7,没有改变。

代码演示2:

#include<stdio.h>
int main()
{
  int a = -7;//将a的值改成负数
  int b = a << 1;
    int c = a << 2;
  printf("%d\n",a);
  printf("%d\n",b);
    printf("%d\n",c);
  return 0;
}

运行结果:

image.png

两次代码演示初步总结:左移一位,结果在原数据基础上×2;左移两位,结果在原数据基础上×3;但原数据的值不会改变。


(3)左移符号解析


左移符号,移动的是补码,但是打印的时候打印的是原码。


正数左移:7


原码:00000000 00000000 00000000 00000111

反码:00000000 00000000 00000000 00000111

补码:00000000 00000000 00000000 00000111

image.png

正数的左移比较容易看出来,因为原码、反码和补码都相同


负数右移:-7


原码:10000000 00000000 00000000 00000111

反码:11111111  11111111   11111111  11111000

补码:11111111  11111111   11111111  11111001

image.png

总结:


   无论正数还是负数,左移的结果都会×2。


记忆口诀:左边丢弃,右边补0。


2.右移操作符(>>)

(1)右移操作符分类


右移操作符包括:算术右移和逻辑右移


逻辑右移:右边直接丢弃,左边补0


算术右移:右边直接丢弃,左边补原符号位(正数补0,负数补1)-----------常用选择


我们下面的例子也都用算术右移来演示


(2)代码演示

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

运行结果:

image.png

其实不难发现,算术右移其实也有一种÷2的效果。

(3)右移图示解析

image.png

总结:大多数编译器都是使用算术右移,效果相当于÷2


算术右移口诀:右边丢弃,左边补原符号位


3.左移、右移总结

(1)移动的对象只能是整数


(2)只能移动正整数位,比如左移一位、右移两位。


(3)移动后不会改变原数据的值


(4)移动的是二进制的补码,打印的结果是二进制的原码


三、位操作符

前言:位操作符的对象仍然是二进制的补码,他们必须有两个操作对象


1.按位与(&)

(1)定义


两个对象的补码比较,相同位有0则结果位0,相同位都是1结果才为1。


(2)代码演示

#include<stdio.h>
int main()
{
  int a = 5;
  int b = 7;
  int c = a & b;//将按位与的结果赋值给c
  printf("%d\n",c);
  return 0;
}

运行结果:

image.png

(3)代码分析

我们先列出5和7的补码:

5的补码:00000000 00000000 00000000 00000101

7的补码:00000000 00000000 00000000 00000111

图解:

image.png

(4)实列讲解

根据有0为0,两个1才为1的特点,可以按位与1来确定最低一位(最右一边)是1或者0。

代码演示:

#include<stdio.h>
int main()
{
  int a = 3;
  int b = a & 1;
  printf("%d\n",b);
  return 0;
}

运行结果:

image.png

结果分析:

3的补码:00000000 00000000 00000000 00000011

1的补码:00000000 00000000 00000000 00000001

image.png

所以,任何数按位与1,得出的结果为1,则该数的二进制最低为是1,如果是0,则最低为是0。当然,要知道该数的二进制序列的所以1,则需要配合右移符号使用(后续补充)

2.按位或(|)

(1)定义

二进制序列对应位上,有1则为1,两个相同才为0。

(2)代码演示

#include<stdio.h>
int main()
{
  int a = 5;
  int b = -3;
  int c = a | b;//按位或
  printf("%d\n",c);
  return 0;
}

运行结果:

image.png

3)代码解读

5的补码:00000000 00000000 00000000 00000101

-3的补码11111111 11111111 11111111 11111101

image.png

3.按位异或(^)

(1)定义

对应的二进制位相同为0,相异为1

由此而来的知识点:a^a=0          a^0=a

(2)代码演示

#include<stdio.h>
int main()
{
  int a = 5;
  int b = -3;
  int c = a ^ b;//按位异或
  printf("%d\n", c);
  return 0;
}

运行结果:

image.png

3)代码解读

5的补码:00000000 00000000 00000000 00000101

-3的补码:11111111 11111111 11111111 11111101

image.png

(4)实例讲解

题目:在不借助第三方变量的情况下,交换两个变量的值

代码演示:

#include<stdio.h>
int main()
{
  int a = 520;
  int b = 1314;
  a = a ^ b;
  b = a ^ b;//此时的a=a^b
  a = a ^ b;
  printf("a=%d b=%d\n",a,b);
  return 0;
}

运行结果:

image.png

代码解读:


第一步:a=a^b;这个结果先不要算出来


第二步:b=a^b;这个时候左边的a=a^b,所以整个等式变成b=a^b^b,因为b^b=0,且a^0=a,所以此时就将a的值赋给了b,


第三步:a=a^b,此时左边的a=a^b,b=a,所以左边=a^b^a=b,所以就将b赋值给了a,完成两个数的交换



四、某些复合赋值操作符和一个单目操作符

前言:操作对象都是二进制的补码


1.复合赋值操作符

(1)赋值操作符的介绍


>>=    右移等

<<=    左移等

&=      按位与等

|=       按位与等

^=      按位异或等

(2)使用方法


上面的这些符号就多了一个等号,就如同+=一样


代码举例:

#include<stdio.h>
int main()
{
  int a = 5;
  a = a >> 1;//普通写法
  a >>= 1;//复合写法
  a = a << 1;
  a <<= 1;
  a = a & 2;
  a &= 2;//复合写法
  a = a | 4;
  a |= 4;
  a = a ^ 1;
  a ^= 1;
  return 0;
}

2.一个单目操作符

(1)定义:~(一个波浪号)

作用:对一个数的二进制按位取反

(2)代码演示

#include<stdio.h>
int main()
{
  int a = 0;
  printf("%d\n",~a);//单目操作符
  return 0;
}

运行结果:

image.png

(3)例子

#include<stdio.h>
int main()
{
  int a = 10;
  a |= (1 << 4);//控制二进制将10变成26
  printf("%d\n",a);
  //再将26变回10
  a &= (~(1 << 4));
  printf("%d\n",a);
  return 0;
}

10的补码:00000000 00000000 00000000 00001010

26的补码:00000000 00000000 00000000 00011010

10变成26:

image.png

26变回10:只需将该位置按位与上0即可

相关文章
|
3月前
|
存储 C语言 索引
【C语言篇】操作符详解(下篇)
如果某个操作数的类型在上⾯这个列表中排名靠后,那么⾸先要转换为另外⼀个操作数的类型后执⾏运算。
75 0
|
3月前
|
程序员 编译器 C语言
【C语言篇】操作符详解(上篇)
这是合法表达式,不会报错,但是通常达不到想要的结果, 即不是保证变量 j 的值在 i 和 k 之间。因为关系运算符是从左到右计算,所以实际执⾏的是下⾯的表达式。
261 0
|
1月前
|
存储 缓存 C语言
【c语言】简单的算术操作符、输入输出函数
本文介绍了C语言中的算术操作符、赋值操作符、单目操作符以及输入输出函数 `printf` 和 `scanf` 的基本用法。算术操作符包括加、减、乘、除和求余,其中除法和求余运算有特殊规则。赋值操作符用于给变量赋值,并支持复合赋值。单目操作符包括自增自减、正负号和强制类型转换。输入输出函数 `printf` 和 `scanf` 用于格式化输入和输出,支持多种占位符和格式控制。通过示例代码详细解释了这些操作符和函数的使用方法。
37 10
|
1月前
|
存储 编译器 C语言
【C语言】简单介绍进制和操作符
【C语言】简单介绍进制和操作符
163 1
|
1月前
|
存储 编译器 C语言
初识C语言5——操作符详解
初识C语言5——操作符详解
180 0
|
3月前
|
C语言
C语言操作符(补充+面试)
C语言操作符(补充+面试)
45 6
|
3月前
|
存储 编译器 C语言
十一:《初学C语言》— 操作符详解(上)
【8月更文挑战第12天】本篇文章讲解了二进制与非二进制的转换;原码反码和补码;移位操作符及位操作符,并附上多个教学代码及代码练习示例
59 0
十一:《初学C语言》—  操作符详解(上)
|
4月前
|
C语言
五:《初学C语言》— 操作符
本篇文章主要讲解了关系操作符和逻辑操作符并附上了多个代码示例
44 1
五:《初学C语言》—  操作符
|
4月前
|
编译器 C语言
【C语言初阶】指针篇—下
【C语言初阶】指针篇—下
|
4月前
|
存储 C语言
【C语言初阶】指针篇—上
【C语言初阶】指针篇—上