1.10进制转二进制方法
所以125的二进制就是1111101
2.2进制转8进制:
从2进制序列中右边最低位开始向左每3个2进制位换算为一个8进制位,剩余不够3个2进制位的直接换算
例:01101011转为01 101 011
即1 5 3
即8进制的153
还原回去的话:
将3化为011放最右边,5化为101放前者的左边,1化为1放前者的前边
3.而二进制转16进制:
从2进制序列中右边最低位开始向左每4个2进制位换算成一个8进制位,剩余不够4个2进制位的直接换算
例:01101011
化为0110 1011
即6b
还原回去的话:
将b化为1011放最右边,6化为110放前者的左边
4.有符号 的整形的二进制位最高位是符号位,其余是数值位
5.1个整形32个bit
6.原码除了符号位不变,其他位按位取反得到的是反码
7.原码取反(符号位不变)加 1,得到补码,补码取反(符号位不变)加一,得到原码
8.整数转化为补码存储入计算机,计算机内部对整形的操作都是基于补码进行的
9.移位操作符只能对整数进行操作
10.左移操作符:左边丢弃,右边补零(对补码进行操作,已核实) <<
11.右移操作符:(大多编译器都用的算术右移) >>
逻辑右移:左边用零补充,右边丢弃
算术右移:左边用原有的符号填充,右边丢弃
12.真正打印出来的还是原码
13.不要用移位操作符移动负数位
14.
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int n = 10;
printf("%d\n", n << 62);
return 0;
}
这是标准未定义的,整形一共就32个bit
15.位操作符:&(按位与), |(按位或), ^(按位异或), ~(按位取反)
16.&&和 ||是逻辑操作符
17.位操作符的操作数必须是整数
18.& :
int c = a & b;
二者的补码化合,
有 0则 0,全 1才 1(符号位也遵从),
存入C中
19.| :
int c = a | b;
二者的补码化合,
有 1则 1,全 0才 0(符号位也遵从),
存入C中
20.^ :
int c = a | b;
二者的补码化合,
同 0异 1(符号位也遵从),
存入C中
21.~ :
int a = 10;
int b = ~a;
得到的b是a的补码(符号位也是)按位取反得到的值
22.一道 面试 题:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
//不创建临时变量来交换两个整形变量的值
int main()
{
int a = 10;
int b = 20;
//a ^ a == 0
//0 ^ a == a
//^ 服从交换律
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("%d\n", a);
printf("%d\n", b);
return 0;
}
方法2:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
//不创建临时变量来交换两个变量的值
int main()
{
int a = 10;
int b = 20;
a = a + b;
b = a - b;
a = a - b;
printf("%d\n", a);
printf("%d\n", b);
return 0;
}
异或的方法不会有溢出的风险,但是效率低点
23.题
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
//求一个整数存储在内存中的二进制位1的个数
//下列代码,负数也行
int ret = -1;
//scanf("%d", &ret);
int i = 0;
int n = 32;
int count = 0;
for (i = 0; i < n; i++)
{
int tem = 0;
tem = ret & 1;
if (tem == 1)
{
count++;
}
ret >>= 1;
}
printf("%d\n", count);
return 0;
}
另一种方法:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int my_count(unsigned int n)//此处传来的是-1的补码
{
//从问题:
//得到一个十进制的整数中的每一位用方法:/ 10和% 10
//处得到启发
//得到一个十进制的整数中的每一位用方法:/ 2和% 2
int count = 0;
int i = 0;
while (n != 0)
{
if (n % 2 == 1)
{
count++;
}
n = n / 2;
}
return count;
}
int main()
{
//求一个整数存储在内存中的二进制位1的个数
//下列代码,负数也行
int count = my_count(-1);
printf("%d", count);
return 0;
}
另一个方法:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int my_count(int n)
{
int count = 0;
while (n != 0)
{
n = n & (n - 1);
count++;
}
return count;
}
int main()
{
//求一个整数存储在内存中的二进制位1的个数
//下列代码,负数也行
int count = my_count(10);
printf("%d", count);
return 0;
}
上边的那个题做一个知识的延伸:
判断一个数是否是2的次方数DA搜:
24.做题时,一开始想不到的话就先写出前几个数据以看规律
25.
00000000000000000000000000000100
通过 ~ 得到
11111111111111111111111111111011
26.
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int func(int m, int n,int t)
{
int i = 0;
if (t == 1)
{
t = t << (n - 1);
m = m | t;
}
else
{
t = -1;
t = t & (t - 1);
t = t << (n - 1);
m = m & t;
int tem = 1;
//调回去
int i = 0;
for (i = 0; i < n - 1; i++)
{
m = m | (tem << i);
}
}
return m;
}
int main()
{
//把一个数的某个二进制位制 0或制 1
int m = 0;
scanf("%d", &m);//数字
int n = 0;
scanf("%d", &n);//第几位
int i = 0;
for (i = 31;i >= 0 ; i--)//打印一个整数存储在内存中的二进制位
{
printf("%d ", (m >> i) & 1);
}
printf("\n");
int e = func(m, n, 0);//第三个参数为要制为1还是0
for (i = 31; i >= 0; i--)//打印一个整数存储在内存中的二进制位
{
printf("%d ", (e >> i) & 1);
}
return 0;
}
上述函数还是少了两个功能:不能制正数的0,不能制负数的1,要加上去的话无非就是要多加上两个条件而已
27.逗号表达式从右往左执行,拿到的是最后一个值.注:前边的表达式要都执行一遍
28.5也可以是操作数
29.sixeof是一个单目操作符