今天主要学习一下位操作符。
今天也要心情愉悦的学习呀!
<>1.都有哪些操作符?怎么用呢?
& 按位与:逐比特位运算 同1为1,其他为0
| 按位或 : 逐比特位运算 同0为0,其他为1
^ 按位异或 :逐比特位运算 相异为1,相同为0
~ 取反 :逐比特位运算 按位取反(单目操作符)
<< 左移 :逐比特位左移最低位补0
>>右移:逐比特位右移有符号补最高位补符号位,无符号数补0。
除了~取反,其他都是双目操作符。
<>2.位操作符适用于哪些数据类型呢?
答案是只适用于整形家族,不适合浮点型家族。
本质原因是因为两者的数据存储类型不同。
整形家族的存储在上篇说过了,不在赘述。
* 整形家族存储方式
浮点型家族的存储方式,要符合IE754的规定。
<>3.按位与 按位或 按位异或 的实例
<>例 1: 求二进制中1的个数。 采用&(按位与)
int a = 0; scanf("%d", &a); int count = 0; while (a) { a = a&(a - 1);
//每次把最低位丢弃,直到a为0. count++; } printf("%d\n", count);
<>例 2:求二进制中0的个数 采用 | (按位或),(很有趣,可以看看)
int a = 0; int count = 0; scanf("%d", &a); while (a+1) { a = a | (a + 1); count
++; } printf("%d\n", count);
这个代码很有趣,是采用数据溢出后截断来使判断条件成立的。
首先,判断处采用a+1是因为要使0也要进去,更巧的是,当a+1等于0的时候,刚好a是 -1,我们知道-1的二进制补码中是没有0的
,所以刚好符合,这是采用的每次使一个比特位的变成1,到最后使数据变为负数(-1),再加1变为0,终止循环。
<>例 3: 采用 ^ (按位异或)交换两个变量的值。
首先要知道一些最基本的结论:
1 .一个数异或0,还是它本身。
2.一个数异或它本身为0
这是根据异或概念得出的。
下面再看这题,是不是有点思路了。
先a异或b,然后再进行一次异或,相当于b = b^ b^a.
同理可得出a。
int a = 10; int b = 20; printf("before:%d %d\n", a, b); a = a^b; b = a^b; a = a
^b; printf("after:%d %d\n", a, b);
下面是数学法。
int a = 10; int b = 20; printf("before:%d %d\n", a, b); a = a + b; b = a - b; a
= a - b; printf("after:%d %d\n", a, b);
异或法比数学法最大的好处就是不用考虑溢出的问题,如果两个非常大的数进行数学法运算可能会溢出。
<>4.左移 右移操作符
左移比较简单,丢弃高位,低位补0。
右移分情况讨论了 :
算数右移 :有符号的数来说,最高位补符号位。
逻辑右移:无符号的数来说,最高位补0。
看个例子 :
int a = -1; unsigned int b = -1; printf("%d\n", a >> 1); printf("%u\n", b >> 1)
;
运行后发现,先打印的是-1,然后是打印的是230-1.
先分析a>>1,因为a是有符号的负数,所以补位时最高位符号位1,最后的补码值还是全1.
再看b>>1,因为b是无符号数,所以补位时最高位补0,最后是出来第一个比特位是0,其他都为1。
那么移位的范围是什么呢?
首先int型的数据只有32位,所以移位最大是31位,那么最小值呢?是最小值是**-31位吗?**不是的,左移还有右移都不能移位负数位。
所以移位的范围是0~31位。
看个例子
比较下优先级的问题。
int a = 1; a = a << 2 + 3; printf("%d", a);
首先,结果是32,那么这样看的话,是先进行(2+3),在进行移位。
所以使用移位符时,要考略优先级的问题。
<>5.移位符应用
使用移位符可以逐比特位置为0或1.
逐比特位,置1.
unsigned int a = 1; int i = 0; for (i = 0; i < 32; i++) { a = a|(a << i); }
printf("%d", a);
因为最后是有符号数,所以打印为-1。
逐比特位,置0
unsigned int a = -1; for (int i = 0; i < 32; i++) { a = a & (a >> i); } printf(
"%d", a);
因为a为无符号数,所以补位时,补0,进行移位后在进行按位或。最后打印是0。
<>6. 一些技巧
* x&1 == 0判断是否偶数,偶数的最后一位比特位都是0.
* 两个数的值可以通过异或交换。
* x & (x-1)可以使最右边的比特位上的1变为0.
* 对于正数而言,x&(x-1)== 0就是判断是不是2的幂次方。
* 两个相同的数异或,结果是0,一个数和0异或,结果是他本身。 可以用来找数。
<>7.下期预告
这期还是没把 ++的东西写完。下期一定讲++和–相关的知识。
下期更精彩~~~