进制和操作符

1. 进制

我们常常会听到二进制、八进制、十进制、十六进制,而使用最多的就是十进制。这次我们就来详细介绍一下。

1.1 二进制

  二进制是由 0 和 1 组合而成的,逢二进一。

个人理解为 几进制就没有几

由于二进制是逢二进一的,所以二进制没有2。
例如,0 的二进制是 00000000,1 的二进制是 00000001,2 的二进制是00000010,3 的二进制是00000011,以此类推······

1.2 八进制

  八进制是由 0 ~ 7 组成的,逢八进一,八进制也就没有八。
八进制的表示方法在开头加上 0 即可,;例如 9(十进制)的八进制为 011。

1.3 十进制

  十进制是我们生活中用得最多的,比如平常计数用的都是十进制。
在前面说过 几进制就没有几,那在这里十进制为什么会出现 10 呢 ,其实从本质上来说不算是“十”,因为十进制是由 0 ~ 9 组成的,逢十进一,在 9 之后遇到了 “十” ,就需要进一位,个位上是0,十位上是 1 ,组成之后就变成了 10 。

1.4 十六进制

  十六进制也是一样没有“十六”,十六进制是由数字和字母组成的。
十六进制
  十六进制在 9 之后就由 a ~ f 补上 ,十六进制表示的时候需在前面加上 0x 。例如,12 的十六进制是0xC ,25 的十六进制是0x19,

2. 进制转换

  在使用的进制的时候,多少会碰到进制转换,现在我们就来看看进制是如何转换的。

2.1 二进制和十进制

  在介绍之前,先要了解位权(权重),比如 1234 ,从右向左的权重依次是100 (个位) 、101(十位)、102(十位)、103(十位)。
权重
  
二进制-------->十进制
接下来就用图片解释一下:
二进制-------->十进制
二进制 1011 的十进制就是 11 。
  
十进制-------->二进制:

十进制------->二进制

十进制转换为二进制,核心是除2取余数

2.2 二进制和八进制

  八进制中最大的单位数 7 二进制只有 3 位(111),所以进制转换时取二进制三位转换为八进制的一位。具体操作如下图:
  
二进制-------->八进制:
  

二进制----->八进制
  
90 的二进制是 0101 1010 ,从右往左每次取 3 位转换,最后不满三位也要转换,最终得到八进制:0132 。(前面的 0 不可省)

八进制-------->二进制:
  八进制转换二进制,可以先将 0 后面的数拆分开来,再对拆分单位逐个进行转换,最后将转换到的二进制数字合起来就变成完整的二进制。例如,

八进制-------->二进制
  
八进制:062   八进制转换为二进制   二进制:0011 0010 。

2.3 二进制和十六进制

  十六进制中最大的单位数 15 二进制只有 4 位(1111),所以进制转换时取二进制四位转换为十六进制的一位。具体操作如下图:
  
二进制-------->十六进制:

二进制-------->十六进制
二进制:0001 0110 1011   二进制转换为十六进制   十六进制:0x16b

十六进制-------->二进制:
十六进制-------->二进制
十六进制:0x12d   十六进制转换为二进制    二进制:0001 0010 1101

2.4 八进制和十进制

  前面提到了位权,八进制的位权就是以 8 为底数,进行计算。
  
八进制-------->十进制:
八进制-------->十进制
八进制:066   八进制转换为十进制    十进制:54
  
十进制-------->八进制:
在这里插入图片描述
十进制:66   十进制转换为八进制    八进制:0102

2.4 八进制和十六进制

  八进制和十六进制间的相互转换,可以借助二进制或者十进制作为中间值进行转换。
这里不做过多展示。

2.5 十进制和十六进制

  
十进制-------->十六进制:
十进制-------十六进制>

十六进制住转换为十进制,可以借助二进制或者十进制作为中间值进行转换。
这里不做过多展示。

3. 原码、反码、补码

  原码、反码、补码都是 整数 二进制位的展示方法。
这三种方法都有符号位和数值位,最高位是符号位, 0 代表正,1 代表负,除了最高位,其余位都是数值位。

注意:
   原码:将数值翻译成二进制就是原码。
   反码:符号位不变,数值为全部取反得到的就是反码。
   补码:反码 + 1 。

 正整数的原码、反码、补码都相同
 负数的原码、反码、补码照常计算

4. 位操作符

位操作符含义
&按位与
|按位或
^按位异或
~按位取反
<<左移
>>右移

注意:
   1.位运算符运算队对象,只能是整型数据或字符型数据,不能是浮点型数据。
   2.只有 ~ 为单目操作符,其他均为双目操作符。
   3.运算对象一律按二进制补码形式参与运算。
   4.位运算结果是整型数据。

4.1 按位与(&)

  
这里二进制位有 32 位,因为一个整型是 4 个字节,一个字节是八个比特位(bit)
  
  双目运算符,只有对应的两个二进位都为 1 时,结果位才为 1 。

可以把 & 操作符理解为乘法运算。(对应二进制位相乘)

#include<stdio.h>
int main()
{
	int m = 6; // 0000 0000 0000 0000 0000 0000 0000 0110
	int n = 12;// 0000 0000 0000 0000 0000 0000 0000 1100
	int x = 0;
	x = m & n; // 0000 0000 0000 0000 0000 0000 0000 0100 
	printf("%d",x);
	return 0;
}

运行结果:

4

  

4.2 按位或( | )

  双目运算符,只要对应的二个二进位有一个为1时,结果位就为1。

可以把 | 操作符理解为加法运算。(对应二进制位相加(不要将两位对应的 1 相加成 2 了哦))

#include<stdio.h>
int main()
{
	int m = -6; //原码: 1000 0000 0000 0000 0000 0000 0000 0110
				//反码: 1111 1111 1111 1111 1111 1111 1111 1001
				//补码: 1111 1111 1111 1111 1111 1111 1111 1010

	int n = 12; //      0000 0000 0000 0000 0000 0000 0000 1100
	int x = 0;
	x = m | n;  //      1111 1111 1111 1111 1111 1111 1111 1110  
	printf("%d",x);
	return 0;
}

运行结果:

-2

4.3 按位异或( ^ )

  双目操作符,相同为 0 ,相异为 1 .

可以看做为 “消消乐” ,相同就消除了(为 0) ,相异就还存在(为 1 )。
或者说对应二进制位相减之后的绝对值。

#include<stdio.h>
int main()
{
	int m = -6; //原码: 1000 0000 0000 0000 0000 0000 0000 0110
				//反码: 1111 1111 1111 1111 1111 1111 1111 1001
				//补码: 1111 1111 1111 1111 1111 1111 1111 1010

	int n = 12; //       0000 0000 0000 0000 0000 0000 0000 1100
	int x = 0;
	x = m ^ n;  //       1111 1111 1111 1111 1111 1111 1111 0110 
	printf("%d",x);
	return 0;
}

运行结果:

-10

4.4 按位取反( ~ )

  单目操作符,将每一位二进制位取反,0 变成 1 ,1 变成 0 。

注意是每一位取反哦,不要忘了符号位。


#include<stdio.h>
int main()
{
	int m = -6; //原码: 1000 0000 0000 0000 0000 0000 0000 0110
				//反码: 1111 1111 1111 1111 1111 1111 1111 1001
				//补码: 1111 1111 1111 1111 1111 1111 1111 1010
	int x = 0;
	x = ~m;     //      0000 0000 0000 0000 0000 0000 0000 0101
	printf("%d",x);
	return 0;
}

运行结果:

5

4.5 左移操作符( << )

移位操作符也要先转换到补码再操作哦

  二进制位整体向左移动,左端超过范围丢弃,右端空位补 0
图解:
<<

#include<stdio.h>
int main()
{
	int m = -6; //原码: 1000 0000 0000 0000 0000 0000 0000 0110
				//反码: 1111 1111 1111 1111 1111 1111 1111 1001
				//补码: 1111 1111 1111 1111 1111 1111 1111 1010
	int x = 0;
	x = m<<1;   //      1111 1111 1111 1111 1111 1111 1111 0100
	printf("%d",x);
	return 0;
}

运行结果:

-12

4.5 右移操作符( >> )

右移操作符有两种规则,

  1. 逻辑右移:右端超过范围丢弃,左端空位补 0 。
  2. 算术右移:右端超过范围丢弃,左端符号位不变,其余空位补 0 。

图解:(这里只演示了逻辑右移)
>>

#include<stdio.h>
int main()
{
	int m = -6; //原码: 1000 0000 0000 0000 0000 0000 0000 0110
				//反码: 1111 1111 1111 1111 1111 1111 1111 1001
				//补码: 1111 1111 1111 1111 1111 1111 1111 1010
	int x = 0;
	x = m>>1;   //      1111 1111 1111 1111 1111 1111 1111 1101
	printf("%d",x);
	return 0;
}

运行结果:

-3

注意:
  1. 编译器大多数都是算术右移。
  2. 移位操作符不可移动负数位(x >> -2)。

5.优先级 、结合性

  表达式运算时通常会有各种运算符参与计算,而这些操作符就决定了表达式的结果。这就涉及到优先级和结合性了。

5.1 优先级

  优先级很好说明,就如以下式子:

  x = 7 - 6 * 1 ;

在表达式中,既有乘号( * )又有减号( - ),根据运算符的优先级,此表达式就要先进行乘法运算,后进行减法运算。

5.2 结合性

  如果出现运算符优先级相同的情况,就要看运算符的结合性,是从左往右,还是从右往左。

  x = 4 * 3 / 6 ;

由于乘号( * )和除号( / )的优先级相同,根据结合性就是从左往右计算。
接下来就介绍一下最常见的运算符。

优先级常见的运算符
1圆括号 ( )
2自增(++)、自减(- -)
3正号(+)、负号( - )
4乘法( * )、除法( / )
5加法( + )、减法( - )
6大于( > )、小于( < )
7赋值运算符 ( = )

其他操作符请参考:运算符优先级

6.逗号表达式

基本格式:

(表达式 1 ,表达式 2,表达式 3,……)

计算方式是从左往右,最后一个表达式的结果就是整个表达式的结果。
既然这样,那还要前面那么多表达式干嘛呢,如果有人这样想就说明还没有完全理解。
要记住:逐个表达式从左往右依次计算!!!
例如:

#include<stdio.h>
int main()
{
	int a = 5;
	int b = 8;
	int c = 0;
	c = (a = b++, a--, b = a - 6);   //逗号表达式中的值从左往右依次计算
	printf("a = %d\n", a);
	printf("b = %d\n", b);
	printf("c = %d\n", c);
	return 0;
}

运行结果:

a = 7
b = 1
c = 1

逗号操作符的优先级是最低的

  
最后:进制转换和位操作符可能会有些难理解,多尝试,耐心练习,会有很多收获哦 !

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值