《C Primer Plus》手记三

本贴最后更新于 717 天前,其中的信息可能已经天翻地覆

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;
}
  • C

    C 语言是一门通用计算机编程语言,应用广泛。C 语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。

    62 引用 • 163 回帖 • 364 关注

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...