<分区>
- 您使用位运算做什么?
- 为什么它们这么方便?
- 有人可以推荐一个非常简单的教程吗?
<分区>
最佳答案
虽然每个人似乎都对标志用例着迷,但这并不是按位运算符的唯一应用(尽管可能是最常见的)。此外,C# 是一种足够高级的语言,其他技术可能很少使用,但仍然值得了解它们。这是我能想到的:
<<
和 >>
运算符可以快速乘以 2 的幂。当然,.NET JIT 优化器可能会为您执行此操作(以及其他语言的任何体面的编译器),但如果您真的担心每一微秒,您可能会写这个是为了确定。
这些运算符的另一个常见用途是将两个 16 位整数填充到一个 32 位整数中。喜欢:
int Result = (shortIntA << 16 ) | shortIntB;
这对于与 Win32 函数的直接接口(interface)很常见,有时出于遗留原因使用此技巧。
当然,当您想让没有经验的人感到困惑时,例如在提供家庭作业问题的答案时,这些运算符很有用。 :)
尽管在任何实际代码中使用乘法会好得多,因为它具有更好的可读性并且 JIT 将其优化为 shl
和 shr
说明,所以没有性能损失。
处理 ^
的一些奇怪的技巧运算符(异或)。这实际上是一个非常强大的运算符,因为它具有以下特性:
A^B == B^A
A^B^A == B
A^B
那么就不可能说出什么A
和 B
是,但如果您知道其中之一,则可以计算出另一个。我看到的一些使用此运算符的技巧:
在没有中间变量的情况下交换两个整数变量:
A = A^B // A is now XOR of A and B
B = A^B // B is now the original A
A = A^B // A is now the original B
双向链表,每一项只有一个额外的变量。这在 C# 中用处不大,但对于每个字节都很重要的嵌入式系统的低级编程可能会派上用场。
这个想法是您跟踪第一个项目的指针;最后一项的指针;对于每件商品,您都会跟踪 pointer_to_previous ^ pointer_to_next
.这样你就可以从任一端遍历列表,而开销只是传统链表的一半。这是用于遍历的 C++ 代码:
ItemStruct *CurrentItem = FirstItem, *PreviousItem=NULL;
while ( CurrentItem != NULL )
{
// Work with CurrentItem->Data
ItemStruct *NextItem = CurrentItem->XorPointers ^ PreviousItem;
PreviousItem = CurrentItem;
CurrentItem = NextItem;
}
要从末尾开始遍历,您只需将第一行从 FirstItem
更改为至 LastItem
.这是另一个内存节省。
我使用 ^
的另一个地方C# 中的定期运算符是当我必须为我的复合类型的类型计算 HashCode 时。喜欢:
class Person
{
string FirstName;
string LastName;
int Age;
public int override GetHashCode()
{
return (FirstName == null ? 0 : FirstName.GetHashCode()) ^
(LastName == null ? 0 : LastName.GetHashCode()) ^
Age.GetHashCode();
}
}
关于c# - 位运算的实际应用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3883384/