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;
}
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于