2009-03-04 30 views
88

Tôi chỉ muốn lật một boolean dựa trên những gì nó đã có. Nếu nó đúng - làm cho nó sai. Nếu nó sai - làm cho nó đúng.Cách dễ nhất để lật giá trị boolean?

Đây là mã trích tôi:

switch(wParam) { 

case VK_F11: 
    if (flipVal == true) { 
    flipVal = false; 
    } else { 
    flipVal = true; 
    } 
break; 

case VK_F12: 
    if (otherVal == true) { 
    otherValVal = false; 
    } else { 
    otherVal = true; 
    } 
break; 

default: 
break; 
} 

Trả lời

285

Bạn có thể lật một giá trị như sau:

myVal = !myVal; 

do đó, mã của bạn sẽ rút ngắn xuống:

switch(wParam) { 
    case VK_F11: 
    flipVal = !flipVal; 
    break; 

    case VK_F12: 
    otherVal = !otherVal; 
    break; 

    default: 
    break; 
} 
+4

Đây không chỉ là dễ nhất, nhưng cũng là cách sạch nhất. – sharptooth

+4

Tôi sử dụng Boolean "chuyển đổi" tất cả thời gian trong mã. –

+1

succint và rõ ràng là cách duy nhất mã – Jason

2

tôi thích John T của giải pháp, nhưng nếu bạn muốn đi tất cả code-golfy, tuyên bố của bạn một cách hợp lý làm giảm này:

//if key is down, toggle the boolean, else leave it alone. 
flipVal = ((wParam==VK_F11) && !flipVal) || (!(wParam==VK_F11) && flipVal); 
if(wParam==VK_F11) Break; 

//if key is down, toggle the boolean, else leave it alone. 
otherVal = ((wParam==VK_F12) && !otherVal) || (!(wParam==VK_F12) && otherVal); 
if(wParam==VK_F12) Break; 
+0

Bạn không phải kiểm tra wParam với VK_F11 và VK_F12? – drby

+0

Doh! Vâng, cảm ơn bạn ... Tôi đã thực hiện chỉnh sửa đó. – JosephStyons

4

Giải pháp codegolf'ish sẽ như thế nào nữa:

flipVal = (wParam == VK_F11) ? !flipVal : flipVal; 
otherVal = (wParam == VK_F12) ? !otherVal : otherVal; 
+5

Vâng, nếu chúng ta sẽ codegolf: flipVal = (wParam == VK_F11)! = FlipVal; ... – bobince

+0

ok, các bạn thắng ... :) Tôi chưa bao giờ là một tay golf nhiều. – JosephStyons

26

Nếu bạn biết giá trị là 0 hoặc 1, bạn có thể làm flipval ^= 1.

+1

Tại sao sử dụng toán tử bitwise cho phép toán logic? Mùi của obfuscation không cần thiết với tôi. –

+4

@Mark: Xin lỗi. Đoán tôi là lỗi thời.Nhưng nó sẽ giúp ích nếu biểu thức L-value của bạn thực sự dài, vì vậy bạn không phải lặp lại nó. Ngoài ra, bạn có thể nói flipval^= TRUE. Điều đó có tốt hơn không? –

+0

@Mark - xem bài đăng của tôi - bởi vì đôi khi giá trị logic của bạn được lưu trữ theo bit. Không phải ai cũng muốn lãng phí toàn bộ 8 bit (hoặc nhiều hơn) chỉ cho một boolean. – Alnitak

66

Rõ ràng bạn cần một mẫu nhà máy!

KeyFactory keyFactory = new KeyFactory(); 
KeyObj keyObj = keyFactory.getKeyObj(wParam); 
keyObj.doStuff(); 


class VK_F11 extends KeyObj { 
    boolean val; 
    public void doStuff() { 
     val = !val; 
    } 
} 

class VK_F12 extends KeyObj { 
    boolean val; 
    public void doStuff() { 
     val = !val; 
    } 
} 

class KeyFactory { 
    public KeyObj getKeyObj(int param) { 
     switch(param) { 
     case VK_F11: 
      return new VK_F11(); 
     case VK_F12: 
      return new VK_F12(); 
     } 
     throw new KeyNotFoundException("Key " + param + " was not found!"); 
    } 
} 

: D

</sarcasm> 
+5

Có thể chúng tôi cũng có thể thêm vào mẫu đơn cho nhà máy. – Drew

+0

@Orm Nguyên nhân bạn là _ORM_? :) – mlvljr

+2

Lưu ý đề xuất tinh tế để chuyển sang Java! –

9

Chỉ cần cung cấp thông tin - nếu thay vì một số nguyên trường bắt buộc của bạn là một chút duy nhất trong một loại lớn hơn, sử dụng 'xor' điều hành thay vì:

int flags; 

int flag_a = 0x01; 
int flag_b = 0x02; 
int flag_c = 0x04; 

/* I want to flip 'flag_b' without touching 'flag_a' or 'flag_c' */ 
flags ^= flag_b; 

/* I want to set 'flag_b' */ 
flags |= flag_b; 

/* I want to clear (or 'reset') 'flag_b' */ 
flags &= ~flag_b; 

/* I want to test 'flag_b' */ 
bool b_is_set = (flags & flab_b) != 0; 
0

Rõ ràng bạn cần một giải pháp linh hoạt có thể hỗ trợ các loại giả mạo như boolean. Sau đây cho phép điều đó:

template<typename T> bool Flip(const T& t); 

Sau đó, bạn có thể chuyên điều này cho các loại khác nhau có thể giả vờ là boolean. Ví dụ:

template<> bool Flip<bool>(const bool& b) { return !b; } 
template<> bool Flip<int>(const int& i) { return !(i == 0); } 

Một ví dụ của việc sử dụng cấu trúc này:

if(Flip(false)) { printf("flipped false\n"); } 
if(!Flip(true)) { printf("flipped true\n"); } 

if(Flip(0)) { printf("flipped 0\n"); } 
if(!Flip(1)) { printf("flipped 1\n"); } 

Không, tôi không nghiêm trọng.

8

Điều này dường như là miễn phí cho tất cả ... Heh.Đây là một varation, mà tôi đoán là ở những thể loại "thông minh" hơn một cái gì đó tôi khuyên bạn nên cho mã sản xuất:

flipVal ^= (wParam == VK_F11); 
otherVal ^= (wParam == VK_F12); 

Tôi đoán đó là ưu điểm là:

  • Rất ngắn gọn
  • Liệu không yêu cầu phân nhánh

Và một bất lợi cũng giống như rõ ràng là

  • Rất terse

Đây gần với giải pháp @ korona sử dụng ?: nhưng thực hiện thêm một bước (nhỏ).

+1

Theo thứ tự các hoạt động, tôi nghĩ bạn có thể bỏ qua dấu ngoặc đơn để có thêm nhiều chi tiết. : O – Drew

6

Chỉ vì yêu thích lẻ bóng theo cách của tôi để chuyển đổi một bool không được liệt kê ...

bool x = true; 
x = x == false; 

làm việc quá. :)

(có các x = !x; là rõ ràng và dễ đọc hơn)

1
flipVal ^= 1; 

Cũng vậy với

otherVal 
19

giải pháp dễ nhất mà tôi tìm thấy:

x ^= true; 
+0

'x =! X;' không chỉ ngắn hơn mà còn dễ đọc hơn. – Rodrigo

+0

Lưu ý rằng, ví dụ: 'longVariableName^= true;' rõ ràng là ngắn hơn 'longVariableName =! longVariableName;' Và mọi lập trình viên đều nên biết XOR. – xamid

+0

Bạn nói đúng. Tôi không biết rằng^= có nghĩa là XOR :) – Rodrigo

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