C# 左右移动的目的是什么
我知道左班和右班是干什么的 当我有0011>>1和右移时,它将是→ 0001 如果我们使用0011>>2,它只需除以C# 左右移动的目的是什么,c#,C#,我知道左班和右班是干什么的 当我有0011>>1和右移时,它将是→ 0001 如果我们使用0011>>2,它只需除以2上的值,它将除以4,以此类推。。。 但目的是什么 我刚开始使用tcp套接字,我看到我们发送的缓冲区大小如下 var bytes = new Array(4) bytes[1] = int >> 24 bytes[2] = int >> 16 bytes[3] = int >> 8 bytes[4] = int
2上的值,它将除以4,以此类推。。。
但目的是什么
我刚开始使用tcp套接字,我看到我们发送的缓冲区大小如下
var bytes = new Array(4)
bytes[1] = int >> 24
bytes[2] = int >> 16
bytes[3] = int >> 8
bytes[4] = int
我不知道为什么我们用24,16和8
有时他们只使用8
like
var bytes = new Array(2)
bytes[1] = int >> 8
bytes[2] = int
同样,当他们想要读取大小时,他们只需使用与右移
相反的左移
size = buff[1] << 24 | buff[2] << 16 | buff[3] << 8 | buff[4]
size=buff[1],因为如果您将使用位的工作形象化,会使生活更轻松
一个int
在内存中有4个字节大,因此我们可以将其作为4个独立的字节来移动
some int: 11111111 10101010 11110000 11001100
为了得到这些比特块和4个单独的字节,我们可以肯定地除以2的幂,但要想可视化,要比仅仅将整个东西滑动到正确的24个位置,留下我们存储在一个字节中的11111111
(从右侧滑动的所有东西都丢失了)更困难。。或者向右滑动16个位置,留下11111111 10101010
,当我们将11111111
存储在一个字节中时,它会被切断(分配给一个字节时,最右边8位左边的所有内容都会丢失)
这有点像玩比特
至于为什么您可以使用左移位从4个字节重新组合int-想象一下玩一个反向版本的堆栈器,其中32个插槽被安排为4组,您必须将这8位(从前导字节)放入最左侧的存储桶,然后将后续字节的位放入下一个存储桶:
some byte: 11111111
next byte: 10101010
some int: ________ ________ ________ ________
“某个字节”需要向左滑动24位,下一个字节为16位。它们获取0(成为仅设置了一些位的整数),结果:
some byte shifted: 11111111 00000000 00000000 00000000
next byte shifted: 10101010 00000000 00000000
some int result: ________ ________ ________ ________
然后将它们按位或按位合并,以生成结果:
some byte: 11111111 00000000 00000000 00000000
next byte: 00000000 10101010 00000000 00000000
some int: 11111111 10101010 00000000 00000000
或者是“逐列工作,如果列中的任何值为1,则列中的结果值为1,否则为0”
为什么这些事情总是以字节的形式进行
因为这就是网络传输的方式,因为所有东西最终都是一个字节(int是4个字节),如果你想这样看的话,就是位。即使您使用将int写入套接字的抽象,它也会将其转换为字节。在这里,你只是在欣赏这种转换是如何进行的(不一定非得是这样;还有其他排列位和字节的方法。只要你是一致的,你怎么做并不重要)
您还可以看到它用于标记枚举:
flags enum Perms{
None = 0,
Read = 1 << 0,
Write = 1 << 1,
Delete = 1 << 2
}
没有人会因为bitshift版本而解雇您,尽管作为操作,它们比powers更不常见,因此下一个维护代码的人可能必须查找它的含义,而power形式可能已经很好地理解了
至于它们是如何产生的,位移位操作通常比乘/除操作快得多(它们对于CPU来说实现起来非常简单,但应用有限),因此对于有限的上下文非常有用
flags enum Perms{
None = 0,
Read = 2^0,
Write = 2^1,
Delete = 2^2
}