C语言中的位与

Bit-wise AND in C language

考虑 Dennis ritchie 在 C 书中给出的以下陈述

The bitwise AND operator & is often used to mask off some set of bits,

for example

n = n & 0177; 

sets to zero all but the low-order 7 bits of n.

关于按位AND运算符,我的理解如下

11010010 & 01101010 = 01000010

即,如果任何操作数中的相应位为 0,则设置为 0

但是在上面引用的语句中,它被告知除最后7位外,其他位均为0。

0177如果用二进制展开就是10110001(8位),低8位就不能说了。我哪里错了?

您将掩码转换为 177,就像它是十进制一样。然而,事实并非如此:前导零使其成为八进制常数。

因此,其二进制表示为

01111111

如您所见,它屏蔽了除低 7 位以外的所有位。

在过去,八进制表示法在 PDP 计算机的程序员中很流行,因为它让他们 "read" 二进制代码更容易。它现在不那么流行了,在定义二进制掩码时,十六进制符号主要取代它。

引用 C11,章节 §6.4.4.1,(强调我的

[...] An octal constant consists of the prefix 0 optionally followed by a sequence of the digits 0 through 7 only. [...]

因此,像 0177 这样的 整数常量 是八进制的,与十进制 127 或十六进制 7F 相同。二进制表示给你01111111,这是

中的真实

[...] sets to zero all but the low-order 7 bits of n.

在 C 中,前缀为 0 的整数是八进制(基数为 8),因此 0177 = 001 111 1112.

在八进制中,每个数字 0-7 正好代表 3 个二进制数字。它有点神秘和陈旧,是 12 位字长并不少见(例如 PDP8)的时代的后遗症。这是一个不幸的表示,因为它比它作为数字符号不再有用时更频繁地抓住粗心的人。

我在编写位字段时的建议是坚持使用十六进制(在本例中为 0x7f),其中每个数字代表 4 个二进制数字,因此符合 8 的倍数 现代架构上的字长。

如果您对输入使用 %i 格式说明符,则会偶然出现另一个陷阱 - 它也将 00x 前缀分别解释为八进制和十六进制,这可能会导致混淆错误如果数据源生成前导小数零。