2013-04-17 75 views
11

if ((a & b) == b) có nghĩa là gì trong khối mã sau?Câu lệnh này có ý nghĩa gì trong C#?

if ((e.Modifiers & Keys.Shift) == Keys.Shift) 
{ 
    lbl.Text += "\n" + "Shift was held down."; 
} 

Tại sao nó không như thế này?

if (e.Modifiers == Keys.Shift) 
{ 
    lbl.Text += "\n" + "Shift was held down."; 
} 
+4

Google 'bitwise AND', sau đó là google' bit flag'. – mbeckish

+0

bản sao có thể có của [Cái gì đơn lẻ | hoặc & mean?] (http://stackoverflow.com/questions/9736751/what-does-a-single-or-mean) –

Trả lời

17

Nếu bạn xem Keys enum, đây là flag enum với thuộc tính [FlagsAttribute].

Sử dụng thuộc tính tùy chỉnh FlagsAttribute để chỉ liệt kê nếu thao tác bitwise (AND, OR, EXCLUSIVE OR) phải được thực hiện trên giá trị số.

Xác định hằng số đếm trong lũy ​​thừa của hai, nghĩa là, 1, 2, 4, 8, v.v. Điều này có nghĩa là các cờ riêng lẻ trong các hằng số liệt kê kết hợp không trùng lặp.

Vì vậy e.Modifiers có thể là một sự kết hợp của nhiều hơn một enum:

e.Modifiers = Keys.Shift | Keys.Cancel | Keys.Enter 

giả định sự rất đơn giản để giải thích các khái niệm:

Keys.Shift : 001 (1) 
Keys.Cancel : 010 (2) 
Keys.Enter : 100 (4) 

Vì vậy:

e.Modifiers = Keys.Shift | Keys.Cancel | Keys.Enter equal 001 | 010 | 100 = 111 

Và điều kiện:

e.Modifiers & Keys.Shift equal 111 & 001 = 001 

nó có nghĩa là:

e.Modifiers & Keys.Shift == Keys.Shift 

nếu e.Modifiers không chứa Keys.Shift:

e.Modifiers = Keys.Cancel | Keys.Enter (110) 

Vì vậy, kết quả sẽ là:

e.Modifiers & Keys.Shift equals 110 & 001 = 000 (is not Keys.Shift) 

Để hầm chứa nước lên, tình trạng này kiểm tra wheth er e.Modifiers chứa Keys.Shift hoặc không

+1

'010 & 001' bằng' 0' –

+0

@MattBurland: THanks chỉ ra, chỉnh sửa –

3

Một dấu và duy nhất (&) là một phép toán AND, vì vậy nó là cơ bản thêm các giá trị của (a & b) và sau đó thử nghiệm cho sự bình đẳng trong (một & b) == b

Vì vậy, trong ví dụ của bạn, về cơ bản là nếu phím shift được nhấn (bất kỳ phím shift + shift nào) == shift.

+2

Nó không thêm chúng! Có sự khác biệt ** lớn ** giữa việc áp dụng toán tử bitwise AND và thêm. – antonijn

+0

Vâng, tôi nhận ra điều này. Tôi chỉ đang cố gắng giải thích nó một cách đơn giản. Xin lỗi vì xúc phạm. –

5

Đó là logic boolean (& = "bitwise và"). Bạn kiểm tra xem biến có chứa một giá trị không. Nó giống như một bộ lọc.

dụ:

a -> 00110011 
b -> 00000011 
a&b -> 00000011 

Trong mã của bạn

if ((e.Modifiers & Keys.Shift) == Keys.Shift) 

để kiểm tra Keys.Shift được chứa trong e.Modifiers.

4

Một ký hiệu đơn và tham chiếu đến bitwise AND operator. Khi được sử dụng kết hợp với một enum có thuộc tính [Flags] trên nó, mà Keys enum hiện, nó được sử dụng như bạn đã cho thấy để xác định xem một trong các bit của enum đó có được đặt hay không.

Có thể có nhiều hơn một phím bổ trợ được nhấn đồng thời, vì vậy đó là lý do tại sao nó được sử dụng thay vì so sánh trực tiếp.

Bạn có thể đọc thêm về cờ enum here. Cuộn xuống phần phụ có tựa đề "Các kiểu liệt kê như cờ bit". Bạn sẽ thấy một mẫu khá giống với mẫu này.

3

& là phép toán AND điều hành. Những gì nó đang làm là Keys là một enum cờ, các giá trị trong Keys có thể là một sự kết hợp bitwise của một số giá trị. Vì vậy, để kiểm tra cho bất kỳ giá trị cụ thể nào bạn đầu tiên VÀ giá trị của bạn với giá trị bạn muốn kiểm tra và sau đó so sánh nó với giá trị bạn muốn kiểm tra.

Ví dụ, bạn có thể có cả sự thay đổi và phím ctrl tổ chức xuống, do đó giá trị trong e.Modifier sẽ là một sự kết hợp của Bitwise Keys.ShiftKeys.Ctrl. Vì vậy, điều này:

e.Modifier == Keys.Shift 

Là sai. Shift được giữ lại, nhưng Ctrl cũng được giữ. Nếu bạn muốn biết nếu phím Shift được giữ lại bất kể các phím khác có thể được giữ gìn, trước tiên bạn cần lọc tất cả các phím khác.Đây có thể dễ dàng thực hiện bằng cách sử dụng Keys.Shift như một bộ lọc:

(e.Modifier & Keys.Shift) == Keys.Shift 

này bây giờ sẽ là true nếu phím shift được tổ chức xuống bất kể những gì các phím khác có thể được ép và sai khác.

3

Phần 1

Đó là logic AND điều hành.

Nó được sử dụng khi có nhiều cờ nên settable trong một ví dụ Integer:

một ví dụ là 3 có nghĩa là 00000011 trong ký hiệu nhị phân. Ví dụ: b là 2 có nghĩa là 00000010 trong ký hiệu nhị phân.

Khi bạn muốn kiểm tra xem một có cờ (bit thứ hai từ bên phải) đó B thể hiện thiết bạn sử dụng và nhà điều hành:

một & b = 00000010

Và khi điều này bằng b (hoặc là> 0) bạn biết rằng cờ được đặt.

Phần 2

Nhà điều hành bình đẳng cũng có thể được sử dụng cho các trường hợp bạn muốn kiểm tra xem "Keys.Shift" là chỉ "sửa đổi" chìa khóa và không ai khác được nhấn. Khi bạn sử dụng mã đầu tiên, các phím "bổ trợ" khác có thể được nhấn, và điều kiện if vẫn sẽ đúng.

3

Một ký hiệu đơn (&) thực hiện thao tác AND một cách khôn ngoan; một dấu hai và (& &) thực hiện một phép toán Boolean AND.

Một chút khôn ngoan và thực hiện thao tác AND trên mỗi bit của cả hai đối số (do đó nó được gọi là "bit-wise"). Do đó, đầu ra của một hoạt động AND-khôn ngoan (hoặc bất kỳ hoạt động bit-khôn ngoan) sẽ không phải là một giá trị boolean. Dưới đây là một số ví dụ về các bit-wise VÀ hoạt động:

1001 & 0001 = 0001 
1101 & 1111 = 1101 

Một boolean VÀ hoạt động trên hai giá trị boolean và trả về một boolean:

true && true = true 
false && true = false 

ngắn mạch
Một boolean VÀ hoạt động (& &) cũng có thể được thực hiện trên hai biểu thức trả về giá trị boolean:

int a = 5; 
int b = 10; 
bool result = (a < 3) && (b > 3); 
// result will be false; 

Bởi vì biểu thức đầu tiên (a < 3) đánh giá là false, kết quả không thể là true vì BOTH biểu thức phải đánh giá là true để cho kết quả là true. Bởi vì điều này, biểu thức thứ hai thậm chí sẽ không được đánh giá. Điều này được gọi là "ngắn mạch". Tuy nhiên, với một hoạt động AND khôn ngoan, cả hai biểu thức cần được đánh giá trước khi thực hiện thao tác. Do đó trong phần lớn các tình huống mà bạn chỉ muốn xác định xem hai điều có đúng hay không (boolean) boolean AND (& &) sẽ là tùy chọn tốt nhất.

Trong ví dụ của bạn, mã sẽ so sánh các bit riêng lẻ trong phạm vi e.Modifiers với các bit riêng lẻ trong Keys.Shift. Đối số không đại diện cho một giá trị boolean và do đó hoạt động là bit-khôn ngoan (&) chứ không phải là boolean (& &).

Các vấn đề liên quan