下面是几个关于位操作的几个题,也是老师的课上讲的,自己也听明白了一些,但还是经常范糊涂,在就是也不经常用,但考试说不定也拿来考,所以小总结一下位的常用例子;
(1)~0 :可以取到全为1的32个二进制位;
(2) 对他实现>> ,<<的操作,以得到我们想要的数;
(3)在次对他进行& ,| 的操作: 0&1=0; 1&1=1; 0|1=1;,1|1=1;
(4)在就是利用的for循环中i的变化实现怎整体移位判断,如: ((n >> i) & 0x01) 与0x01 比来判断是否为0或1;
(5)在就是运用了常数 0xff , 0x01
1.
#include <stdio.h>
/*
0x12345678 4 7
00010010001101000101011001111000
11111111111111111111111100001111
00000000000000000000000011110000
0:
00000000000000000000000000000000
~0:
11111111111111111111111111111111
~0 << (end - start + 1):~0 << 4
11111111111111111111111111110000
~(~0 << (end - start + 1)):
00000000000000000000000000001111
~(~0 << (end - start + 1)) << start:
00000000000000000000000011110000
*/
unsigned cleanbits(unsigned n, int start, int end) //清零2进制操作
{
return n & ~(~(~0 << (end - start + 1)) << start);
}
unsigned setbits(unsigned n, int start, int end) // 2位 相关位设置1;
{
return n | ~(~0 << (end - start + 1)) << start;
}
int main(void)
{
unsigned int n;
int start, end;
scanf("%x %d %d", &n, &start, &end);
printf("cleanbits:0x%x\n", cleanbits(n, start, end));
printf("setbits:0x%x\n", setbits(n, start, end));
return 0;
}
2.位实现乘法;
#include <stdio.h>
int main(void)
{
int m, n, i, result = 0;;
scanf("%d %d", &m, &n);
for(i = 0; i < 32; i++)
if((n >> i) & 0x01)
result += (m << i);
printf("%d * %d = %d\n", m, n, result);
return 0;
}
3.得到二进制的某些位,以及实现某些位的互换;
#include <stdio.h>
//0x12345678 4 11
unsigned getbits(unsigned n, int start, int end)
{
return (n >> start) & ~(~0 << (end - start + 1));
}
int main(void)
{
/*
unsigned n;
int start, end;
scanf("%x %d %d", &n, &start, &end);
printf("getbits:0x%x\n", getbits(n, start, end));
*/
unsigned short a = 0x1234, b = 0x5678;
printf("0x%hx\n", (a & 0xff00) | (b & 0xff));
return 0;
}
4计算二进制有多少个1
#include <stdio.h>
int main(void)
{
unsigned n;
int i, count = 0;
scanf("%x", &n);
for(i = 0; i < 32; i++)
if((n >> i) & 0x01)
count++;
printf("count = %d\n", count);
return 0;
}
5 bits实现大小写字母的转换
#include <stdio.h>
char toup(char c)
{
if(c >= 'A' && c <= 'Z')
return c;
return c & ~0x20;
}
char tolow(char c)
{
if(c >= 'a' && c <= 'z')
return c;
return c | 0x20;
}
int main(void)
{
int c;
while((c = getchar()) != EOF){
if(c == '\n')
continue;
printf("%c\n", c ^ 0x20);
printf("toup:%c\n", toup(c));
printf("tolow:%c\n", tolow(c));
}
return 0;
}
6 使用位操作的知识向数组中保存26个没有重复的英文字母
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
char letter[26];
int tmp, i, j, flag = 0;
srand(time(NULL));
for(i = 0; i < 26;){
tmp = rand() % 26;
if(((flag >> tmp) & 0x01) == 0){
letter[i++] = tmp + 'a';
flag |= (0x01 << tmp);
}
for(j = 31; j >= 0; j--)
printf("%d", (flag >> j) & 0x01);
printf("\n");
}
for(i = 0; i < 26; i++)
printf("%c ", letter[i]);
printf("\n");
return 0;
}
7 位操作实现循环左移、右移
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
unsigned shift_left(unsigned n, int bits)
{
return (n << bits) | (n >> (32 - bits));
}
unsigned shift_right(unsigned n, int bits)
{
return (n >> bits) | (n << (32 - bits));
}
int main(int argc, char *argv[])
{
char *savep;
printf("left:0x%x\n", shift_left(strtol(argv[1], &savep, 16), atoi(argv[2])));
printf("right:0x%x\n", shift_right(strtol(argv[1], &savep, 16), atoi(argv[2])));
return 0;
}