2009-03-05 21 views
135

Câu hỏi đơn giản thực sự; là có một sự khác biệt giữa các giá trị này (và có sự khác biệt giữa BOOL và bool)? Một đồng nghiệp đã đề cập rằng họ đánh giá những thứ khác nhau trong Objective-C, nhưng khi tôi nhìn vào typedefs trong các tệp .h tương ứng, YES/TRUE/true được định nghĩa là 1 và NO/FALSE/false đều được định nghĩa là 0. Có sự khác biệt nào không?Có sự khác nhau giữa CÓ/KHÔNG, TRUE/FALSE và đúng/sai trong mục tiêu-c không?

+4

Từ quan điểm thực tế không có sự khác biệt. Bạn có thể có thể thực hiện các thủ thuật khác nhau để chứng minh sự khác biệt, nhưng bạn thường sẽ đi lạc vào lãnh thổ "hành vi không xác định". –

Trả lời

70

Không có sự khác biệt thực tiễn cung cấp bạn sử dụng BOOL biến như boolean. C xử lý biểu thức boolean dựa trên việc họ đánh giá 0 hay không 0. Vì vậy:

if(someVar) { ... } 
if(!someVar) { ... } 

nghĩa giống như

if(someVar!=0) { ... } 
if(someVar==0) { ... } 

đó là lý do bạn có thể đánh giá bất kỳ loại nguyên thủy hoặc biểu hiện như một thử nghiệm boolean (bao gồm, ví dụ như con trỏ). Lưu ý rằng bạn nên làm cái cũ, không phải cái sau.

Lưu ý rằng có một sự khác biệt nếu bạn gán giá trị tù đến một cái gọi là BOOL biến và kiểm tra cho các giá trị cụ thể, vì vậy luôn sử dụng chúng như các phép toán luận và chỉ gán chúng từ #define giá trị của họ.

Quan trọng hơn, không bao giờ thử nghiệm boolean bằng cách so sánh nhân vật - không chỉ mạo hiểm vì someVar có thể được gán giá trị khác 0, nhưng theo quan điểm của tôi quan trọng hơn, nó không thể hiện đúng ý định:

if(someVar==YES) { ... } // don't do this! 
if(someVar==NO) { ... } // don't do this either! 

Nói cách khác, sử dụng các cấu trúc như họ đang dự định và tài liệu được sử dụng và bạn sẽ tha cho mình khỏi thế giới của những nỗi đau trong C.

-7

Không, YES/NO là một cách khác nhau để tham khảo TRUE/FALSE (1/0)

+3

-1 vì không nói lý do tại sao – Supuhstar

+3

-1 vì không chỉ định – vilanovi

1

tôi nghĩ rằng họ thêm YES/NO là hơn tự giải thích trong nhiều trường hợp. Ví dụ:

[button setHidden:YES]; 

âm thanh tốt hơn so với

[button setHidden:TRUE]; 
+1

Tôi không đồng ý; cả hai đều đọc như vậy, với tôi. Tuy nhiên, trong một giao diện người dùng cho một người cư ngụ, tôi nghĩ Có/Không có vẻ đẹp hơn. –

+14

Tôi cũng không đồng ý. Nếu bất cứ điều gì, nó đọc kém do không gắn bó với các tiêu chuẩn bất thành văn đã được sử dụng trong nhiều năm bằng các ngôn ngữ khác. IE là một ví dụ điển hình về những gì xảy ra khi bạn không tuân theo một số lượng lớn các tiêu chuẩn. – FreeAsInBeer

+5

-1 để để lại hai câu trả lời có thể được liệt kê là một trong số – Supuhstar

13

Bạn có thể muốn đọc những câu trả lời cho question này. Nói tóm lại, trong Objective-C (từ định nghĩa trong objc.h):

typedef signed char  BOOL; 
// BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C" 
// even if -funsigned-char is used. 
#define OBJC_BOOL_DEFINED 


#define YES    (BOOL)1 
#define NO    (BOOL)0 
90

Tôi tin rằng có một sự khác biệt giữa boolBOOL, hãy kiểm tra trang web này cho một lời giải thích lý do tại sao:
http://iosdevelopertips.com/objective-c/of-bool-and-yes.html

BOOL là một unsigned char chứ không phải là một loại nguyên thủy, các biến kiểu BOOL có thể chứa các giá trị khác hơn YESNO.

xem xét mã này:

BOOL b = 42; 

if (b) { 
    printf("b is not NO!\n"); 
} 

if (b != YES) { 
    printf("b is not YES!\n"); 
} 

Đầu ra là:

b phải là không có!
b không phải là CÓ!

Đối với hầu hết mọi người, đây là mối quan tâm không cần thiết, nhưng nếu bạn thực sự muốn một boolean thì tốt hơn nên sử dụng bool. Tôi nên thêm: iOS SDK thường sử dụng BOOL trên định nghĩa giao diện của nó, do đó, đó là một đối số để gắn bó với BOOL.

+4

Nhưng lưu ý rằng triển khai C ban đầu không có 'bool', và do đó nó là truyền thống sử dụng' int' hoặc 'char' làm Boolean, đôi khi với #define để ẩn sự khác biệt và đôi khi không. Trong thực tế, tôi không chắc chắn nếu ngay cả các tiêu chuẩn hiện tại yêu cầu 'bool' được thực hiện theo cách ngăn cản việc kiểm tra cấu trúc nội bộ của nó. –

+1

Mặc dù, 'printf' đầu tiên nói dối. Giá trị của 'b' không phải là' CÓ', đó là "số không", đó là điều kiện kiểm tra. Vì vậy, bạn nên có 'printf (" b không phải là số không ")', mà không nhất thiết phải giống như 'CÓ'. Trong trường hợp này, 'b' là cả hai" số không "và" không CÓ ". –

+0

Cảm ơn Lawrence, tôi đã cập nhật những dòng này. –

46

Tôi đã làm một bài kiểm tra đầy đủ về điều này. kết quả của tôi nên nói cho mình:

//These will all print "1" 
NSLog(@"%d", true == true); 
NSLog(@"%d", TRUE == true); 
NSLog(@"%d", YES == true); 
NSLog(@"%d", true == TRUE); 
NSLog(@"%d", TRUE == TRUE); 
NSLog(@"%d", YES == TRUE); 
NSLog(@"%d", true == YES); 
NSLog(@"%d", TRUE == YES); 
NSLog(@"%d", YES == YES); 

NSLog(@"%d", false == false); 
NSLog(@"%d", FALSE == false); 
NSLog(@"%d", NO == false); 
NSLog(@"%d", false == FALSE); 
NSLog(@"%d", FALSE == FALSE); 
NSLog(@"%d", NO == FALSE); 
NSLog(@"%d", false == NO); 
NSLog(@"%d", FALSE == NO); 
NSLog(@"%d", NO == NO); 


//These will all print "0" 
NSLog(@"%d", false == true); 
NSLog(@"%d", FALSE == true); 
NSLog(@"%d", NO == true); 
NSLog(@"%d", false == TRUE); 
NSLog(@"%d", FALSE == TRUE); 
NSLog(@"%d", NO == TRUE); 
NSLog(@"%d", false == YES); 
NSLog(@"%d", FALSE == YES); 
NSLog(@"%d", NO == YES); 

NSLog(@"%d", true == false); 
NSLog(@"%d", TRUE == false); 
NSLog(@"%d", YES == false); 
NSLog(@"%d", true == FALSE); 
NSLog(@"%d", TRUE == FALSE); 
NSLog(@"%d", YES == FALSE); 
NSLog(@"%d", true == NO); 
NSLog(@"%d", TRUE == NO); 
NSLog(@"%d", YES == NO); 

Đầu ra là:

2013-02-19 20:30:37.061 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.061 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.072 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.073 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.073 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.074 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.074 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.075 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.075 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.076 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.077 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.077 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.078 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.078 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.079 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.079 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.080 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.080 BooleanTests[27433:a0f] 1 
2013-02-19 20:30:37.081 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.081 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.082 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.091 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.092 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.093 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.093 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.094 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.094 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.095 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.095 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.096 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.096 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.097 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.098 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.101 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.102 BooleanTests[27433:a0f] 0 
2013-02-19 20:30:37.102 BooleanTests[27433:a0f] 0 
+3

[[NSObject] alloc] init] không bằng TRUE hoặc YES. Vì vậy, thử nghiệm cho khởi tạo đối tượng với nếu ([[NSObject] alloc] init] == ​​TRUE) sẽ thất bại. Tôi chưa bao giờ cảm thấy thoải mái với một ngôn ngữ xác định một giá trị "đúng" số ít khi thực tế bất kỳ giá trị khác không sẽ làm. –

+2

@SamuelRenkert Tôi chưa bao giờ cảm thấy thoải mái với ngôn ngữ sử dụng giá trị không Boolean trong 'if' hoặc' while'. Giống như ... 'while (" guitar nhẹ nhàng khóc ")' không nên hoạt động ... – Supuhstar

+0

@SamuelRenkert cũng là backdoor Linux đã được tìm thấy vào năm 2003: 'if (user_id = ROOT_UID)' – Supuhstar

0

Có một lỗi tinh tế mà không ai đã đề cập ở đây, mà tôi nghĩ tôi sẽ bao gồm ... chi tiết của một logic lỗi hơn bất cứ điều gì:

int i = 2; 
if(i);  //true 
if(i==YES); // false 
if((!!i)==YES); //true 

do đó vấn đề ở đây chỉ là (YES==1) và trong C so sánh không phải là một boolean, nhưng dựa trên giá trị.

YES chỉ là một #define (chứ không phải là nội dung nào đó cho ngôn ngữ), nó phải là một số giá trị và 1 có ý nghĩa nhất.

+0

Đây thực chất là câu trả lời giống như DanJ's, từ 2 năm trước, với ít chi tiết hơn. –

+0

@LawrenceDol Tôi không biết, nó đề cập rằng CÓ chỉ là #defined là 1 và không nội tại đối với ngôn ngữ, giống như nó có thể ở một ngôn ngữ cấp cao hơn ... ai đó có thể có được giá trị từ đó ... nhưng tốt trolling, với ya. –

4

Sự khác biệt chính (nguy hiểm!) Giữa trueYES là trong tuần tự hóa JSON.

Ví dụ, chúng tôi có yêu cầu máy chủ JSON-type và cần phải gửi đúng/sai trong json sence:

NSDictionary *r1 = @{@"bool" : @(true)}; 
NSDictionary *r2 = @{@"bool" : @(YES)}; 
NSDictionary *r3 = @{@"bool" : @((BOOL)true)}; 

Sau đó chúng tôi chuyển nó sang JSON chuỗi trước khi gửi như

NSData *data = [NSJSONSerialization dataWithJSONObject:requestParams options:0 error:nil]; 
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 

Các kết quả là

jsonString1 // {"bool":1} 
jsonString2 // {"bool":true} 
jsonString3 // {"bool":true} 

Do logic API jsonString1 có thể dẫn đến lỗi.

Vì vậy, hãy cẩn thận với các phép toán trong Mục tiêu-C.

P.S. Bạn có thể sử dụng

@{@"bool" : @"true"}; // {"bool":true} 
Các vấn đề liên quan