操作符详解
// 进制转换 2进制换10进制 对应权重相乘 最后相加 得到对应的 10进制数字
// 2进制转到8进制 2进制的每三位 对应一个 8进制位,同理 8进制转2进制,8进制的每一位 换算成对应的 3位2进制数(0不可省略)
// 2进制转到16进制 2机制的每四位 对应一个 16进制位,同理 16进制转2进制,16进制的每一位 换算成对应的 4位2进制数(0不可省略)
// 进制转换 仅限整数 浮点数不可以
// 2进制的表示形式有 3种 :原码-反码-补码,在计算机最底层中 存的是2进制的 补码,
// 正数3码相同
// 负数 先将原码按位取反->得到反码 然后反码+1 ->得到补码,同理 补码先-1 然后反码按位取反 最后得到原码
// 注意 在计算机中 2进制位的最高位 为符号位,0表示 正数 1表示负数,在计算负数的 原反补时 符号位不可以动
//
//void print(int n)
//{
// int i = 0;
// int cont = 0;
// for (; i < 32 ; i++)
// {
// printf("%d ", (n >> i) & 1);
// cont++;
// }
//
// printf("\n");
// printf("%d", cont);
//}
//int main()
//{
// int a = -2;
// print(a);
//
// return 0;
//}
//移位操作
// << 左移 ,左边抛弃 右边补0,负数同理
// >> 右移 ,分为 逻辑与运算 ,
// 逻辑右移 右边抛弃 ,左边补 0
// 算术右移 右边抛弃 ,左边补 1
//
//int main()
//{
// //
// int a = -2;
// printf("%d\n", a << 1);// -4
// printf("%d\n", a >> 1);// -1 ,VS2022 采用的是 算术右移
//
// // 移位操作符,左移1位相当于 乘2 ,右移1位相当于 除2
//
// return 0;
//}
//! 位操作符 (位比较的都是 补码,并且只能是整数,不可以是浮点数)
//! ( 包括符号位 )
//! & 按位与 同为 1 才为 1
//! | 按位或 有一个 1 则为 1,两个都是0,才是 0
//! ^ 按位异或 相同为 0,相异为 1
//! ~ 按位取反 0变1 1变0,包括符号位
!
//int main()
//{
// int a = 2;
// int b = -1;
// printf("%d\n", a & b);// 2
// printf("%d\n", a | b);// -1
// printf("%d\n", a ^ b);// -3
// printf("%d\n", ~a);// -3
// printf("%d\n", ~b);// 0
//
// // 不使用 额外变量 交换值
// int x = 3;
// int y = 7;
// x = x ^ y;// 异或
// y = x ^ y;// 然后 y 异或 x 就得到 3
// x = x ^ y;// 然后 x 异或 y 就得到 7,,完成交换
// // ^ 操作符 支持 加法结合律与交换律
// printf("%d %d\n", x, y); // 7 3
//
// // 但是 通常交换值 选择 空瓶交换法
//
// return 0;
//}
// 求一个数的 二进制中 1的个数
// 1:遍历 二进制
// 2:取模,,思路:由10进制转 2进制,但是这个需要考虑到负数
void idea_1(int n)
{
int i = 0;
int cont = 0;
for (; i < 32; i++)
{
if (((n >> i) & 1) == 1)
cont++;
}
printf("%d\n", cont);
}
void idea_2(unsigned int n)
{
int cont = 0;
// 10 进制转 2进制位补码办法 巧妙 ,但是需要注意负数,所以 要将参数改为 unsigned 无符号类型的 正数
while (n)
{
if (n % 2 == 1)// 因为 如果是负数的话,余数的符号取决于 被除数的符号,如果被除数是负数的话 余数就不会大于 0
cont++;
n /= 2;//
}
printf("%d\n", cont);
}
// 注意 ! 如果函数不添加返回值的话 默认返回值是 int类型的整数,需要注意
// 牛逼代码公式 n&(n-1),每次减掉一个 直接算出 二进制中 1的个数,同样是在补码中进行 不需要考虑负数
void idea_3(int n)
{
int cont = 0;
while (n)// n 不为0 就进入
{
n = n & (n - 1);// 将 & 后的结果赋值给 n,依次循环
cont++;
}
printf("%d\n", cont);
}/*
int main()
{
int n = -1;
idea_1(n);
idea_2(n);
idea_3(n);
return 0;
}*/
// 引出一个题目
// 判断一个数 是否是2的次方数,
// 规律 2的次方数中 二进制中1的个数只有1个
//int main()
//{
// int n = -2;
// if ((n & (n - 1)) == 0)
// {
// printf("YES\n");
// }
// else
// printf("NO\n");
//
// // 需要考虑负数情况
// // 先 将负数的补码按位取反 然后在用公式
// n = ~n;
// if ((n & (n - 1)) == 0)
// {
// printf("YES\n");
// }
// else
// printf("NO\n");
//
// return 0;
//}
改变 二进制中任意位置的 0 1
//int main()
//{
// int n = 13;
// //
// n = n | (1 << 4);
// printf("%d\n", n);// 29
// n = n & ~(1 << 4);
// printf("%d\n", n);// 13
//
// return 0;
//}
//单目操作符
//sizeof 是操作符 不是函数
//int main()
//{
// int a = 0;
// printf("%d\n", sizeof (a));// 证明 函数必须带括号,而sizeof 可以不带括号 直接跟变量名即可
// printf("%d\n", sizeof a);
// //printf("%d\n", sizeof int); // 但是不可以跟关键字
//
// // 逗号表达式 ( , , , , , , , ,) 表达式从左向右依次计算 但是最后一个的结果代表整个表达式的结果,因为有可能左边的计算会影响到最后的结果
//
// return 0;
//}
// 函数 至少有一个操作数 就是函数名,(无参数时)