1.类型转换
- int main()
- {
- char a = 129;
- char b = 255;
- char c = -1;
- int d = a;
- printf("%d\n",d);//-127
- d = b;
- printf("%d\n",d);//-1
- d = c;
- printf("%d\n",d);//-1
- unsigned char e = 300;
- unsigned char f = -1;
- unsigned char g = 255;
- d = e;
- printf("%d\n",d);//44
- d = f;
- printf("%d\n",d);//255
- d = g;
- printf("%d\n",d);//255
- return 0;
- }
2.统计一个字节数据中二进制1的个数:
- //统计一个字节数据中二进制1的个数,法三法四不如法一法二好
- //8->1,5->2,127->7,-1->8
- //法三
- int Bits(unsigned char n)//unsigned 防止出现负数情况,
- {
- int count = 0;
- while(n != 0)
- {
- if(n%2 == 1)//和十进制类似,得个位
- {
- count++;
- }
- n /= 2;// 丢个位,如果是-1,结果为0,直接退出,此时打印-1含有的1为1个,而真实-1的值(1111 1111)有八个,明显错误。
- }
- return count;
- }
- //法四
- int Bits(unsigned char n)
- {
- int count = 0;
- while(n != 0)
- {
- if((n&1) != 0)
- {
- count++;
- }
- n >>= 1;
- }
- return count;
- }
法一//x & (x - 1),即求二进制1的个数,实用
- int Bits(unsigned c,char n)
- {
- int count = 0;
- while(n != 0)
- {
- n &= (n-1);
- count++;
- }
- return count;
- }
法二//利用空间换时间,手动写好数的值,保存数组里面,直接查找,简称查表法
- int Bits(unsigned char n)
- {
- char bit[256] = {0,1,2,2,1,2,2,3,1,2,2,3};//即保存的是0,1,2,3,4,5,6,7,8,9,10,11里面的二进制中1的个数,保存了才能查到,否则为零
- return bit[n];//返回位数
- }
- int main()
- {
- printf("%d\n",Bits(5));//2法一的值//2法二的值
- printf("%d\n",Bits(9));//2//2
- printf("%d\n",Bits(7));//3//3
- printf("%d\n",Bits(3));//2//2
- printf("%d\n",Bits(64));//1//0
- printf("%d\n",Bits(-1));//8//0
- }
3.易错点
- int main()
- {
- printf("%d\n",-1 >> 1);//-1,右移一位,末尾去1,然后在头加符号位1,所以还是 1111 1111,即-1
- printf("%d\n",255 >>1);//127
- char b = 200;
- //b的二进制为1100 1000 符号位为1,即负数,真正的值要取反加1, 变为-0011 1000,即-56(char 类型的范围是-128~127)
- printf("%d\n",b);//-56
- float c = 3.4;
- printf("%f\n",c);//3.4
- printf("%d\n",c);//特别大的数
- float a = 5/2;//2.000000
- float d = 5.0/2;//2.500000
- float e = (float)5/2;//2.500000,强转的优先级高,先算强转
- float m = (float)(5/2);//2.0
- printf("%f,%f,%f,%f\n",a,d,e,m);
- //求不同类型字节数
- printf("%d\n",sizeof(char));//1
- printf("%d\n",sizeof(short));//2
- printf("%d\n",sizeof(int));//4
- printf("%d\n",sizeof(long));//4
- printf("%d\n",sizeof(long long));//8
- printf("%d\n",sizeof(float));//4
- printf("%d\n",sizeof(double));//8
- printf("%d\n",sizeof(1));// 整数默认为整形
- printf("%d\n",10%3);
- //求余
- printf("%d\n",-5%3);//-2
- printf("%d\n",5%(-3));//2
- printf("%d\n",(-5)%(-3));//-2
- // <, >容易出错,不能连等
- if(10 > 5 > 8)//假,不能连续比较,10 > 5的值为1,小于8
- {
- printf("真\n");
- }
- else
- {
- printf("假\n");
- }
- //!= ,赋值的利用率远远大于等号的利用率,所以把=看成赋值,把==看成等于
- if(a == b)
- {
- printf("==\n");
- }
- else
- {
- printf("!= \n");
- }
- return 0;
- }
1.表达式1 && 表达式2 //表达式1为假,2不做运算
表达式1 || 表达式2 /表达式1为真,表达式2不做运算
2.按位异或
10 0000 1010
11 0000 1011
10 ^ 11 0000 0001
3.按位左移,按位右移
11 << 1 0001 0110 变为:22 = 11*2 (按位左移,右边补零)
11 << 2 0010 1100 变为: 44 = 11*2*2
11 >> 1 0000 0101 变为:5 = 11/2 (按位右移,左边补符号位)
-1 >> 1 1111 1111 -1为1111 1111 (右移补符号位,右移一个,右边去掉一个1,符号位为1,所以左边再加1)
4.表达式1 ? 表达式2 : 表达式3 //表达式为真,执行表达式2,表达式为假,执行表达式3
a > b ? a : b;(a > b,执行a,否则,执行b);
5.位总结:定符号,定数字,构造数字
&与 |或 ^异或
定符号:取零&1,取1 | 0,^(1和1还是0,0和0还是0,0和1变为1)
1.去掉x最后一位
eg:(101101->10110) 右移 x >> 1
2.在x最后加0
eg:(101101->1011010) 左移 x << 1
3.在x最后加1
eg:(101101->1011011) 左移再或1 (x << 1) | 1
4.把x最后一位变1
eg:(101100->101101) 或1 |1
5.把x最后一位变0
eg:(101101->101100) 右移再左移 或者 1取反再与x ((x >> 1) <<1) (~1)& x
6.把x最后一位取反
eg:(101101->101100) x^1
7.把x第倒数k位变1
eg:(101001->101101 ,k = 3) 1左移k-1位再或x x | (1 <<(k-1))
8.把右数第k位变0
eg:(101101->101001,k = 3) 1左移k-1位再取反再与x x &(~(1<<(k-1)))
9.把x右数第k位取反
eg:(101001->101101,k = 3) 左移k-1位再异或x x ^ (1 << (k-1))
10.取x末尾三位
eg:(1101101->)101 x & 7
11.取末尾K位 1左移k位减1再与1
eg:(1101101 ->1101,k=4) x & ((1 << k)-1)
12.取右手第k位
eg:(1101101->1,k = 4) (x >> k) & 1
13.右手连续的1 变连续的0
eg:(100101111->100100000) x & (x + 1)
14.右起第一个0变1
eg:(100101111->100111111) x | (x + 1)
15.右边连续的0变1
eg:(11011000->110111111) x | (x-1)