第一讲小结(位运算)
第一讲的作业是位运算。
位运算主要有几个妙用:
- 按位与“&”
可以将某些位清零的同时保留其他位不变。
也可以获取某变量中的某一位
思考:0&1还是0,1&1还是1,可以保证不变。不管是1还是0&0都是0,所以可以清零.
e.g. n的低8为都置为0,其他位不变:n&=0xffffff00;
判断n的第7位是否为1:n&0x80
note:int变量是32位2进制也就是8位16进制。 - 按位或“|”
可以将某些位置变成1,其他位不变。
思考:1|0还是1,0|0还是0,保证不变。不管是1还是0,|1都为1,所以可以变为1。 - 按位抑或“^”
将某些位取反,保留其他位不变。
思考:1^0还是1,0^0还是0,保证不变。1^1为0,0^1为1,所以可以取反。
特点:a^b=c, c^b=a, c^a=b (穷举法证明)
应用:交换两个变量的值
int a = 5, b = 7; a = a^b; b = b^a; a = a^b;
- 思考题:使表达式的值和a的第n位相同. (a>>n)&1
作业:
1.写出函数中缺失的部分,使得函数返回值为一个整数,该整数的第i位和m的第i位相同,其他位和n相同
return (m&(1<<i))|(n&(~(1<<i)));
//m&(1<<i)把m的第i位取出来
//然后把n的第i位置0;(这样保证第三步时第i位与m相同 )
//然后两者或
2.写出函数中缺失的部分,使得函数返回值为一个整数,该整数的左边i位是n的左边i位取反,其余位和n相同
return n^(-1<<(32-i));
//注意整型是32位
//第一位是符号位
//-1的补码是1111 1111,负数的补码是绝对值部分取反+1
//想要搞出一个111000000 ,所以左移32-i位,那么右边多出32-i个0,左边就剩i个1