2013-04-23 26 views
10

Vì vậy, tôi chạy vào một vấn đề lớn tại nơi làm việc vì tôi đã có một cái gì đó như thế này trong mã của tôi:Objective C: Unsigned int so sánh

int foo = -1; 
    NSArray *bar = [[NSArray alloc] initWithObjects:@"1",@"2",@"3", nil]; 
    if (foo > [bar count]){ 
     NSLog(@"Wow, that's messed up."); 
    } else { 
     NSLog(@"Rock on!"); 
    } 

Như bạn có thể đã biết bởi tôi gửi bài này, đầu ra là:

"Ồ, điều đó đã sai lầm."

Từ những gì tôi thu thập, mục tiêu C đang chuyển đổi số âm của tôi thành int "đã ký" và do đó, làm giảm so sánh của tôi.

Tôi đã xem các bài đăng khác về vấn đề này và tất cả đều nêu rõ vấn đề là gì nhưng không ai trong số họ đề xuất bất kỳ giải pháp đơn giản nào để so sánh này thực sự hoạt động. Ngoài ra, tôi bị sốc rằng không có cảnh báo trình biên dịch, vì đây là những vấn đề nghiêm trọng đối với tôi.

+8

Có một cảnh báo trình biên dịch cho điều này nhưng nó không được bật theo mặc định. Chuyển đến tab Cài đặt Xây dựng cho mục tiêu của bạn và tìm kiếm "So sánh Đăng nhập". Bật cảnh báo trình biên dịch đó. Điều này có thể dẫn đến rất nhiều cảnh báo. – rmaddy

+2

Bạn có thể muốn xem xét lại mã của bạn có nghĩa là gì để làm, vì vì 'count' là unsigned mệnh đề if của bạn về cơ bản là một nhánh chết và có thể được gỡ bỏ. – axiixc

+0

Tôi đang lặp qua một mảng bằng cách nhấn các nút "tiếp theo" hoặc "trước" thay đổi biến chỉ mục. Các giá trị mảng cần phải lặp lại, vì vậy khi chỉ mục nhỏ hơn 0, nó sẽ được đặt thành phần tử cuối cùng trong mảng. Nếu chỉ số lớn hơn chiều dài mảng, nó sẽ được đặt thành 0. Vì vậy, có thể có thể là một tình huống mà chỉ mục là -1 và tôi so sánh nó với chiều dài mảng như được hiển thị ở trên. –

Trả lời

9

Hãy thử điều này

- (IBAction)btnDoSomething:(id)sender { 
     int foo = -1; 
     NSArray *bar = [[NSArray alloc] initWithObjects:@"1",@"2",@"3", nil]; 
     if (foo > (signed)[bar count]) { 
      NSLog(@"Wow, that's messed up."); 
     } else { 
      NSLog(@"Rock on!"); 
     } 
    } 

Working

Nếu bạn đang so sánh hai loại khác nhau của các biến sau đó nó sẽ ngầm chuyển đổi kiểu dữ liệu của cả hai biến để loại cao trong số họ.

Trong ví dụ này,
biến foo là loại ký int và đếm mảng là của unsigned int,
Vì vậy, nó sẽ chuyển đổi kiểu dữ liệu của foo để unsigned int
sau đó giá trị của foo sẽ trở thành số lớn, nhỏ hơn số lượng mảng 3.

Vì vậy, trong ví dụ này, bạn cần giảm số lượng mảng xuống đã ký int.


vấn đề

Khi đếm mảng của bạn vượt quá giới hạn tối đa của ký int sau đó sau khi đúc nó sẽ tròn lại như [- (âm) giới hạn tối đa -> 0 -> + Hạn mức tối đa ] là kết quả không mong muốn.

Giải pháp

  • loại Tránh đúc nếu bạn không chắc chắn về chiều dài mảng tối đa.
  • Thực hiện truyền nếu bạn chắc chắn về giới hạn (độ dài mảng tối đa sẽ không vượt quá chữ ký int giới hạn tối đa).

Để biết thêm chi tiết kiểm tra này
http://visualcplus.blogspot.in/2006/02/lesson-4-casting-data-types.html

+2

'foo' đã được ký. Không cần dùng dàn diễn viên trên 'foo'. – rmaddy

+0

@rmaddy bạn nói đúng, không cần phải bỏ foo. –

+1

Đây là câu trả lời tôi đang tìm kiếm, chính xác cách để so sánh này hoạt động. Cảm ơn! –

10

Vấn đề

Vấn đề bạn đang gặp phải là vì foo là một số nguyên có chữ ký và -[NSArray count] trả về một số nguyên unsigned , foo đang trải qua chuyển đổi loại ẩn thành số nguyên không dấu. Xem Implicit Type Conversion để biết thêm thông tin. Ngoài ra, có thêm thông tin về các quy tắc chuyển đổi loại trong C here.

Giải pháp

-[NSArray count] trả về một giá trị unsigned vì một mảng không bao giờ có thể có một số tiêu cực của các yếu tố; giá trị nhỏ nhất có thể là 0. So sánh số lượng của một mảng với -1 không có ý nghĩa nhiều - số lượng sẽ luôn luôn là lớn hơn bất kỳ số âm nào (các vấn đề ký hiệu bất kể).

Vì vậy, giải pháp ngay tại đây, và cách để tránh những loại vấn đề, là sử dụng một loại phù hợp với giá trị trả về của -[NSArray count], cụ thể là NSUInteger (U là dành cho unsigned).

+1

+1. Đây là giải pháp đúng –

+2

Chính xác, ** khi bạn so sánh đảm bảo cả hai toán hạng đều có cùng kiểu **. Đây là câu trả lời – Krishnabhadra

+1

Không, điều đó thật điên rồ. Như @Caleb đề cập, so sánh độ dài của một mảng với '-1' không * có nghĩa là * bất kỳ thứ gì. Sử dụng '0'. –