一、操作符的分类
在c语言中,有各种各样的操作符,我先将这些操作符给大家列出来:
- 关系操作符:>、>=、< 、<=、 ==、 !=
- 逻辑操作符:&&、||
- 条件操作符:? :
- 逗号表达式:,
- 下标引用:[]
- 函数调用:()
- 结构体访问:. 、->
操作符中的一些操作和二进制有关系,我们先铺垫一下二进制的和进制转换的知识。
二、二进制和进制的转换
我们经常听到2进制、8进制、10进制、16进制这样的讲法,那是什么意思呢?
介绍一部分,操作符中有一些操作符和二进制的关系,我们先铺垫一下二进制和进制转换的知识。
1 15的二进制数:1111
2 15的八进制数:17
3 15的十进制数: 15
4 15的十六进制数:F
5
6 //十六进制的数值之前写:0x
7//8进制数值之前写: 0
我们首先重点介绍一下二进制:
首先还是忒从10进制讲起,其实10进制是我们生活中经常使用的,我们已经形成了很多尝试
- 十进制中满10进1
- 10进制数字每一位都是0~9的数字形成的
其实二进制也是一样的
- 二进制中满2进1
- 2进制的数字每一位都是0~1的数字组成
那么1101就是二进制的数字了
2.1 2进制转10进制
1101=1*2的零次幂+0*2的一次幂+1*2的二次幂+1*2的三次幂
注:从最低位开始计算(最右边计算最低位),依次往左边的高位计算再累加。
#include<stdio.h>
void main()
{ int n,sum=0,p=1 //n为二进制数,sum为每一位计算所加的和,p为位权
scanf("%d",&n); //输入该二进制数
while(n) //循环条件为n,即二进制数n在不为0的时候程序一直成立
{ sum+=(n%10)*p; //数字中所有位乘以本位的位权再加和
p*=2; //位权随着位的变化依次增加
n/=10; } //进行下一位的输出
printf("%d\n",sum);
}
2.2 10进制转2进制数字
十进制转二进制其实就是让这个10进制数一直除于2,然后取他的余数,倒着连在一起就是这个十进制数的二进制数
#include <stdio.h>
int main()
{
int num;int temp;int i=0;
int arr[20];
printf("请输入一个十进制数:\n");
scanf("%d", &num);
do
{
temp=num%2;
num=num/2;
arr[i++]=temp;
}
while (num!=0);
for (int j = i-1; j>=0; j--)
printf("%d",arr[j]);
}
2.3 2进制转8进制
举一个例子:
如:111000110101001转换成八进制
按照八四二一法则
将二进制3个一等分变成:
111 000 110 101 001
按照八四二一法则
111为4+2+1=7;000为0
110为4+2=6;101为4+1=5;001为1
所以,二进制转换为8进制的数为:70651
2.4 2进制转16进制
十六进制:
十六进制逢十六进一,所有的数组是0到9和A到F组成,其中A代表10,B代表11,以此类推,字母不区分大小写
2进制转换16进制的方法
利用8421法则:
如二进制数0010110101110001110011010101,将其分割
0010 1101 0111 0001 1100 1101 0101(16进制的一位数对应2进制的4位数)
0010利用8421为:2
1101利用8421为:8+4+1=13为D
同理:0111为7,0001为1,1100为C,1101为D,0101为5
所以二进制数0010 1101 0111 0001 1100 1101 0101转换为16进制数为:
2D71CD5
三、原码补码反码
整数的2二进制数表示方法有三种,即原码、反码和补码
有符号整数的三种表示方法均有符号位和数值位两部分,2进制序列中,最高位的1位是被当作符号位,其余都是数值为。
符号位都是0表示正,1表示负。
正整数的原反补码都是相同的,但是负数的有三种的表示方法:
原码:直接将数值按照正负数的形式翻译成二进制数就是原码
反码:将原码的符号位不变,其他位按位取反
补码:反码+1得到补码。
补码得到原码也是可以使用:取反,+1的操作。
对于整形来说:数据存放在内存中其实就是存放的补码
为什么呢?因为在计算机系统中,数值一律用补码来表示和存储,原因在于,使用补码,可以将符号位和数值域统一处理(CPU只有加速器),此外,补码和原码相互转换,其运算过程是相同的,不需要额外的硬件电路。
四、移位操作符
4.1左移操作符
对二进制数进行移位,并且只能对整数进行移位。
如图便可知道为何代码中的b变成了12,左移位操作符的规则就是左边抛弃,右边补0.
4.2右移操作符
与左移操作符分起来,右移操作符稍微要麻烦一些。
首先右移操作符分为两种:
1. 逻辑右移:左边补0,右边丢弃
2. 算术右移:左边用原该值的符号位填充,右边丢弃
#include<stdio.h>
int main()
{
int num=10;
int n=num>>1;
printf("%d\n",n);
printf("num=%d\n",num);
return 0;
}
五、位操作符
1. & //按位与2. | //按位或3. ^ //按位异或4. ~ //按位取反
这些数的操作数必须是整数。
直接上代码:
#include <stdio.h>
int main()
{
int num1 = -3;
int num2 = 5;
printf("%d\n", num1 & num2);
printf("%d\n", num1 | num2);
printf("%d\n", num1 ^ num2);
printf("%d\n", ~0);
return 0;
}
输出结果是这样的,看一下懂不懂为啥。
下面我们再来看一个面试题,题目要求是给你一个a,b,然后交换a与b的值,但是不能再次创建一个临时变量。
先考虑一下,再来看代码。
#include <stdio.h>
int main()
{
int a = 10;
int b = 20;
a = a^b;
b = a^b;
a = a^b;
printf("a = %d b = %d\n", a, b);
return 0;
}