c - 为什么位移在 C 中是这样写的?
问题描述
也许这个问题会有点愚蠢,但我想知道为什么如果我们想在寄存器的某个特定位置写 0,我们必须这样写:
PORTB &= ~(1 << 2);
而不是这样(因为它不起作用):
PORTB &= (0 << 2);
0 在这里是否意味着像 0b00000000 (对于 8 位寄存器)?
解决方案
让我们逐步分解:
// PORTB &= ~(1 << 2);
int bit_position = 2;
int bit_mask = 1; // = 0000 0001
bit_mask <<= bit_position; // = 0000 0100
int inverted_mask = ~bit_mask; // = 1111 1011
int PORTB = 0x77; // 0111 0111
PORTB &= inverted_mask; // & 1111 1011
// = 0111 0011
而且,您建议的替代方案:
// PORTB &= (0 << 2);
int bit_position = 2;
int bit_mask = 0; // = 0000 0000
bit_mask <<= bit_position; // = 0000 0000
int PORTB = 0x77; // 0111 0111
PORTB &= bit_mask; // & 0000 0000
// = 0000 0000
关键是计算机只是对整个寄存器一个接一个地执行操作。它不知道它应该关心该数字中所有零中的特定零。因此,您不是通过“位置 2 处的零”进行与运算,而只是通过数字零进行与运算。事实上,你不只是移动一个零或一,而是整个数字。
这就是为什么要将特定位设置为零的原因,我们必须与一个掩码进行与,该掩码在除我们希望为零的位置之外的每个位置都有一个。(与 1 进行与运算不会更改位,而与 0 进行与运算使其为零。)
推荐阅读
- c# - C# - 在字符串列表列表中重复而不是正确的值
- javascript - SyntaxError:编译 ejs 时 index.ejs 中出现意外标识符
- r - 如何使“dplyr select”使用字符参数的值而不是其名称作为文字?
- javascript - JavaScript OAuth 弹出窗口处理程序代码
- mysql - MySQL 数据库中 DATE 和 TIME 向用户显示时间的最佳数据类型是什么?
- algorithm - 二分搜索平方根实现
- html - 复选框始终位于其标签的左侧,如何将其移动到右侧?
- c - 我如何使二叉搜索树与拼写检查器的按字母顺序排列的单词列表一起使用?
- url - 这个 URL 是什么类型的编码?
- json - 有人可以帮我处理这个 json,我在 TS 工作,但到目前为止我还无法将它解析成一个类(列表)