提问人:Nitin Bhartiya 提问时间:7/31/2022 最后编辑:John BollingerNitin Bhartiya 更新时间:7/31/2022 访问量:96
无法理解 C 中按位运算器中的 showbit() 函数 [已关闭]
can't understand showbit() function in bitwise operatrers in C [closed]
问:
/* Print binary equivalent of characters using showbits( ) function */
#include <stdio.h>
void showbits(unsigned char);
int main() {
unsigned char num;
for (num = 0; num <= 5; num++) {
printf("\nDecimal %d is same as binary ", num);
showbits(num);
}
return 0;
}
void showbits(unsigned char n) {
int i;
unsigned char j, k, andmask;
for (i = 7; i >= 0; i--) {
j = i;
andmask = 1 << j;
k = n & andmask;
k == 0 ? printf("0") : printf("1");
}
}
分配的样本编号:0,1,2,3,4 ...num
有人可以详细解释一下发生了什么吗?,这是一个数字,例如 2,如何成为具有 的同一运算符的操作数,例如 10000000,因为 2 是 1 位值,而 100000000 是多位值?k = n & andmask
n
&
andmask
还有为什么是用于而不是?char
n
int
答:
乍一看,此函数似乎以二进制表示形式打印 8 位值(0 和 1)。它创建一个掩码,用于隔离 char 值的每个位(将所有其他位设置为 0),如果掩码值为 0,则打印“0”,否则打印“1”。 之所以在此处使用,是因为该函数旨在打印 8 位值的二进制表示形式。如果在此处使用,则只会正确打印 [0-255] 范围内的值。
我不明白你对 1 位值和多位数值的看法。char
int
评论
00000010
showbit()
scanf
printf
让我们来看看它。
假设是 。的二进制表示形式是 。n
2
2
00000010
第一次通过循环等于 。声明j
7
andmask = 1 << j;
取 的二进制表示,即 ,并将其向左移动 7 位,得到 ,赋值为 。1
00000001
10000000
andmask
声明
k = n & andmask;
对 和 执行按位 AND 运算:n
andmask
00000010
& 10000000
--------
00000000
并将结果分配给 。然后,如果它打印一个“0”,否则它打印一个“1”。k
k
0
所以,每次通过循环,它基本上都在做
j andmask n result output
- -------- -------- -------- ------
7 10000000 & 00000010 00000000 "0"
6 01000000 & 00000010 00000000 "0"
5 00100000 & 00000010 00000000 "0"
4 00010000 & 00000010 00000000 "0"
3 00001000 & 00000010 00000000 "0"
2 00000100 & 00000010 00000000 "0"
1 00000010 & 00000010 00000010 "1"
0 00000001 & 00000010 00000000 "0"
因此,输出为“00000010”。
因此,该函数正在打印出其输入值的二进制表示形式。他们使用而不是保持输出易于阅读(8 位而不是 16 位或 32 位)。showbits
unsigned char
int
此代码的一些问题:
- 它假设始终为 8 位宽;虽然通常是这种情况,但它可以(并且从历史上看)比这更广泛。为了安全起见,它应该使用中定义的宏:
unsigned char
CHAR_BIT
limits.h
#include <limits.h> ... for ( i = CHAR_BIT - 1; i >= 0; i++ ) { ... }
?:
不是控制结构,不应用于替换 - 会更恰当地写成 That tell to output a if is non-zero,否则。if-else
printf( "%c", k ? '1' : '0' );
printf
'1'
k
'0'
评论
printf
1fb6
017666
0001111110110110
2
00000010
00000010
有人可以详细解释一下发生了什么吗?n 是一个数字,例如 2,如何成为具有 的相同运算符的操作数,例如 10000000,因为 2 是 1 位值,而 100000000 是多位值?
k = n & andmask
&
andmask
数字中的位数是该数字的特定表示形式的特征。在所呈现的代码的上下文中,您实际上似乎自己使用了两种不同的表示形式:
- “2”似乎以 (i) 为基数 10,(ii) 没有前导零。
另一方面,我采取
- “10000000”,以 (i) 为基数 2,(ii) 不带前导零。
在这种表示组合中,您关于数字数的主张是正确的,但不是特别有趣。假设我们考虑可比较的表示。例如,如果我们以 256 为基数表示两个数字呢?这两个数字在该基数中都有个位数表示。
这两个数字在基数 256 中也具有任意长度的多位数表示,通过在个位数表示之前加上任意数量的前导零而形成。当然,在任何基地都是如此。带有前导零的表示在人类交流中并不常见,但它们在计算机中是常规的,因为计算机最自然地使用固定宽度的数字表示。
对于按位和 () 来说,重要的是操作数的 base-2 表示形式,即 C 内置算术类型之一的宽度。根据 C 的规则,如有必要,任何算术运算符的操作数都会转换为通用数值类型。它们彼此具有相同数量的二进制数字(即位),其中一些通常是前导零。正如我推断您所理解的,运算符通过组合来自这些 base-2 表示的相应位来计算结果,以确定结果的位。&
&
也就是说,组合的位是
(leading zeroes)10000000 & (leading zeroes)00000010
还有为什么是用于而不是?
char
n
int
它是 ,不是 ,它用于 和 。这是开发人员的选择。 可以改为,该函数将为原始数据类型 () 中可表示的所有输入生成相同的输出。unsigned char
char
n
andmask
n
int
showbits()
unsigned char
评论
printf
评论
2 is 1 digit value
以十进制表示。它(至少)是二进制的 2 位值,但您始终可以在它前面添加更多 s,而无需更改其数值,就像二进制中仍然是十进制的 2 一样10
0
000010
char
int
n & 10000000 (binary)
n
00000000 (binary)
k
n & 01000000 (binary)
00100000 (binary)
00010000 (binary)
00001000 (binary)