C Primer Plus 手记一
C Primer Plus 手记二
13.位操作
编号 0 0 0 0 0 0 0 0 ^ ^ ^ ^ ^ ^ ^ ^ 7 6 5 4 3 2 1 0 7为最高位,0为最低位' 7-0 每个位置为1分别代表为 128 64 32 16 8 4 2 1 所以一个bytes最大为 128+64+32+16+8+4+2+1 = 255 最小为 0000000 = 0 一个 byte 8位 [] [] [] [] [] [] [] [] 11111111 = 255 00000000 = 0 所以 单字节 取值范围为 0-255
高阶位存储符号 1000 0001 = -1 1111 1111 = -127 1000 0000 = -0 0000 0001 = 1 0111 1111 = +127 0000 0000 = +0
正负0的问题可以用二进制补码来解决 正数的反码和补码都与原码相同。 负数的反码为对该数的原码除符号位外各位取反。 负数的补码为对该数的原码除符号位外各位取反,然后在最后一位加1
二进制运算符
// 取反 ~(10011010) -> 01100101 unsigned char a = 2(0000 0010) ~a = 253 = 255-2 = (1111 1101) // & 1对1 = 1 1对0 0对0 得 0 (10010011) & (00111101) = 00010001 = 15 // | 有1为1 (10010011) | (00111101) = 10111111 // ^ 相应位的只有一位为1 则为1 (1001 0011) ^ (0011 1101) = 1010 1110
打开位
实际上的用法,比如打开扬声器需要在其他位不变的情况下打开 1 号
sound = sound | MASK
MASK 可以为 1000 0000
这样可以保证其他位不变,1 号位为 1
关闭位
关闭 1 号位可以
sound = sound & ~MASK
sound = sound & 0111 1111
这样 1 号位无论如何都会是 0,其他位不变
二进制的每一位可能在底层驱动都是一个开关操作.所以在底层用的较多一些.
切换位
打开已经关闭的位 或者 关闭已经打开的位
sound = sound ^ MASK
·0000 1111 ^ 1011 0110 = 1011 1001
检查位的值
if( (sound & MASK) == MASK) puts("WOW!");
移位运算
1000 1010 <<2 = 0010 1000
三原色解析
#define BYTE_MASK 0XFF int main(){ // R G B // 0010 1010 / 0001 0110 / 0010 1111 unsigned long color = 0X002A162f; unsigned char blue,green,red; // 0010 1010 / 0001 0110 / 0010 1111 red = color & BYTE_MASK; // 0001 0110 / 0010 1111 green = color >> 8 & BYTE_MASK; // 0010 1111 blue = color >> 16 & BYTE_MASK; return 0; }
数值转二进制字符串
#include <limits.h> #include <stdio.h> char *itobs(int, char *); void show_bstr(const char *); int main(void) { char bin_str[CHAR_BIT * sizeof(int) + 1]; int number; puts("Enter integers and see them in binary."); puts("Non-numeric input terminates program."); while (scanf("%d", &number) == 1) { itobs(number, bin_str); printf("%d is ", number); show_bstr(bin_str); putchar('\n'); } puts("Bye!"); return 0; } char *itobs(int n, char *ps) { int i; const static int size = CHAR_BIT * sizeof(int); for (i = size - 1; i >= 0; i--, n >>= 1) { // i=31; ps[31] = 0001 & 0101 = 0001 +'0' = '1'; n = 0101 =5 ; n>>=1 = 0010 = 2 // i=30; ps[30] = 0001 & 0010 = 0000 +'0' = '0'; n = 0010 =2 ; n>>=1 = 0001 = 1 // i=29; ps[29] = 0001 & 0001 = 0001 +'0' = '1'; n = 0001 =1 ; n>>=1 = 0000 = 0 ps[i] = (01 & n) + '0'; printf("i = %d; ps[i] = %c; n = %d; n>>1 = %d;\n", i, ps[i], n, n >> 1); } ps[size] = '\0'; return ps; } void show_bstr(const char *str) { int i = 0; while (str[i]) { putchar(str[i]); if (++i % 4 == 0 && str[i]) { putchar(' '); } } }
后四位取反
#include <limits.h> #include <stdio.h> char *itobs(int n, char *ps); void show_bstr(const char *str); int invert_end(int num, int bits); int main(void) { char bin_str[CHAR_BIT * sizeof(int) + 1]; int number; puts("Enter integers and see them in binary."); puts("Non-numeric input terminates program."); while (scanf("%d", &number) == 1) { itobs(number, bin_str); printf("%d is \n", number); show_bstr(bin_str); putchar('\n'); number = invert_end(number, CHAR_BIT * sizeof(int)); printf("Inverting the last 4 bits gives\n"); show_bstr(itobs(number, bin_str)); puts("\n"); } puts("Bye!"); return 0; } char *itobs(int n, char *ps) { int i; const static int size = CHAR_BIT * sizeof(int); for (i = size - 1; i >= 0; i--, n >>= 1) { ps[i] = (01 & n) + '0'; } ps[size] = '\0'; return ps; } void show_bstr(const char *str) { int i = 0; while (str[i]) { putchar(str[i]); if (++i % 4 == 0 && str[i]) { putchar(' '); } } } int invert_end(int num, int bits) { int mask = 0; int bitval = 1; while (bits-- > 0) { mask |= bitval; bitval <<= 1; } return num ^ mask; }
三原色
#include <stdbool.h> #include <stdio.h> #define SOLID 0 #define DOTTED 1 #define DASHED 2 // 三原色 #define BLUE 4 #define GREEN 2 #define RED 1 #define BLACK 0 // 混合色 // 0001 | 0010 = 0011 = 3 #define YELLOW (RED | GREEN) // 0001 | 0100 = 0101 = 5 #define MAGENTA (RED | BLUE) // 0010 | 0100 = 0110 = 6 #define CYAN (GREEN | BLUE) // 0001 | 0010 | 0100 = 0111 = 7 #define WHITE (RED | GREEN | BLUE) const char *colors[8] = {"black", "red", "green", "yellow", "blue", "magenta", "cyan", "white"}; // :number 位数,用位的结构体 struct box_props { bool opaque : 1; unsigned int fill_color : 3; unsigned int : 4; bool show_border : 1; unsigned int border_color : 3; unsigned int border_style : 2; unsigned int : 2; }; void show_settings(const struct box_props *pb); int main(void) { /* 创建并初始化 box_props 结构 */ struct box_props box = {true, YELLOW, true, GREEN, DASHED}; printf("Original box settings:\n"); show_settings(&box); box.opaque = false; box.fill_color = WHITE; box.border_color = MAGENTA; box.border_style = SOLID; printf("\nModified box settings:\n"); show_settings(&box); return 0; } void show_settings(const struct box_props *pb) { printf("Box is %s.\n", pb->opaque == true ? "opaque" : "transparent"); printf("The fill color is %s.\n", colors[pb->fill_color]); }
#include <limits.h> #include <stdbool.h> #include <stdio.h> // 位字段常量 // 边框线样式 #define SOLID 0 #define DOTTED 1 #define DASHED 2 // 三原色 #define BLUE 4 #define GREEN 2 #define RED 1 // 混合颜色 #define BLACK 0 #define YELLOW (RED | GREEN) #define MAGENTA (RED | BLUE) #define CYAN (GREEN | BLUE) #define WHITE (RED | GREEN | BLUE) // 按位方法中用到的符号常量 #define OPAQUE 0x1 #define FILL_BLUE 0x8 #define FILL_GREEN 0x4 #define FILL_REDD 0x4 #define FILL_MASK 0xE #define BORDER 0x100 #define BORDER_BLUE 0x800 #define BORDER_RED 0x200 #define BORDER_GREEN 0x400 #define BORDER_MASK 0xE00 #define B_SOLID 0 #define B_DOTTED 0x1000 #define B_DASHED 0x2000 #define STYLE_MASK 0x3000 const char *colors[8] = {"black", "red", "green", "yellow", "blue", "magenta", "cyan", "white"}; struct box_props { bool opaque : 1; unsigned int fill_color : 3; unsigned int : 4; bool show_border : 1; unsigned int border_color : 3; unsigned int border_style : 2; unsigned int : 2; }; union Views { struct box_props st_view; unsigned short us_view; }; void show_settings(const struct box_props *pb); void show_settings1(unsigned short); char *itobs(int n, char *ps); int main(void) { //创建Views联合,并初始化initialize struct box view union Views box = {{true, YELLOW, true, GREEN, DASHED}}; char bin_str[8 * sizeof(unsigned int) + 1]; printf("Original box settings:\n"); show_settings(&box.st_view); printf("\nBoxSettings using unsigned int view:\n"); show_settings1(box.us_view); printf("bits are %s\n", itobs(box.us_view, bin_str)); box.us_view &= ~FILL_MASK; box.us_view |= (FILL_BLUE | FILL_GREEN); box.us_view ^= OPAQUE; box.us_view |= BORDER_RED; box.us_view &= ~STYLE_MASK; box.us_view |= B_DOTTED; printf("\nModified box settings\n"); show_settings1(box.us_view); printf("bits are %s\n", itobs(box.us_view, bin_str)); return 0; } void show_settings(const struct box_props *pb) { printf("Box is %s.\n", pb->opaque == true ? "opaque" : "transparent"); printf("The fill color is %s \n", colors[pb->fill_color]); printf("Border %s.\n", pb->show_border == true ? "shown" : "not shown"); printf("The border color is %s\n", colors[pb->border_color]); printf("The border style is"); switch (pb->border_style) { case SOLID: printf("solid.\n"); break; case DOTTED: printf("dotted.\n"); break; case DASHED: printf("dashed.\n"); break; default: printf("unknown type.\n"); break; } } void show_settings1(unsigned short us) { printf("box is %s.\n", (us & OPAQUE) == OPAQUE ? "opaque" : "transparent"); printf("The fill color is %s.\n", colors[(us >> 1) & 07]); printf("Border %s.\n", (us & BORDER) == BORDER ? "shown" : "not shown"); printf("The border style is"); switch (us & STYLE_MASK) { case B_SOLID: printf("solid.\n"); break; case B_DOTTED: printf("dotted.\n"); break; case B_DASHED: printf("dashed.\n"); break; default: printf("unknow type.\n"); } printf("The border color is %s.\n", colors[(us >> 9 & 07)]); } char *itobs(int n, char *ps) { int i; const static int size = CHAR_BIT * sizeof(int); for (i = size - 1; i >= 0; i--, n >>= 1) { ps[i] = (01 & n) + '0'; } ps[size] = '\0'; return ps; }
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于