Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/268.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 左右移动的目的是什么_C# - Fatal编程技术网

C# 左右移动的目的是什么

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

我知道左班和右班是干什么的

当我有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
我不知道为什么我们用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
}