2011-07-09 34 views
6

phép nói rằng tôi có các tình huống sau:Quy tắc chung để so sánh các loại dữ liệu khác nhau trong C là gì?

int i = 10; 
short s = 5; 

if (s == i){ 
    do stuff... 
} else if (s < i) { 
    do stuff... 
} 

Khi C không so sánh nó chuyển đổi các kiểu dữ liệu nhỏ hơn, trong trường hợp này ngắn để int hay nó chuyển đổi các kiểu dữ liệu trên quyền kiểu dữ liệu bên trái? Trong trường hợp này int là ngắn?

+3

Trong C, quy tắc chung là * vui lòng không làm điều đó *. Nhưng 'short' sẽ được phát triển thành' int' trong ví dụ của bạn. –

Trả lời

8

Điều này được điều chỉnh bởi chuyển đổi số học thông thường. Đối với các trường hợp đơn giản, quy tắc chung là loại có độ chính xác "ít" được chuyển đổi để khớp với loại có độ chính xác "nhiều hơn", nhưng nó hơi phức tạp khi bạn bắt đầu trộn signedunsigned.

Trong C99, điều này được mô tả bởi phần 6.3.1.8, mà tôi bao gồm đây để thuận tiện cho bạn:

  • Đầu tiên, nếu loại thực tương ứng của một trong hai toán hạng là long double, các toán hạng khác được chuyển đổi, mà không thay đổi miền loại, thành loại có loại thực tế tương ứng là long double.

  • Ngược lại, nếu các loại thực tương ứng của một trong hai toán hạng là double, các toán hạng khác được chuyển đổi, mà không cần thay đổi kiểu miền, để một kiểu mà tương ứng với loại thực sự là double.

  • Ngược lại, nếu các loại thực tương ứng của một trong hai toán hạng là float, các toán hạng khác được chuyển đổi, mà không cần thay đổi kiểu miền, để một kiểu mà tương ứng với loại thực sự là float.

  • Nếu không, các chương trình khuyến mãi số nguyên được thực hiện trên cả hai toán hạng. Sau đó các quy tắc sau đây được áp dụng cho các toán hạng khuyến khích:

    • Nếu cả hai toán hạng có cùng loại, sau đó không có chuyển đổi nữa là cần thiết.
    • Nếu không, nếu cả hai toán hạng đã ký các kiểu nguyên hoặc cả hai đều có loại unsigned integer, các toán hạng với loại ít nguyên rank chuyển đổi được chuyển đổi sang các loại của toán hạng với thứ hạng cao hơn.
    • Ngược lại, nếu các toán hạng có kiểu dữ liệu integer unsigned có rank lớn hơn hoặc bằng cấp bậc của các loại của toán hạng khác, sau đó toán hạng với kiểu số nguyên ký được chuyển đổi sang kiểu của toán hạng với loại số nguyên không dấu.
    • Ngược lại, nếu kiểu của toán hạng với kiểu số nguyên ký thể đại diện cho tất cả các giá trị của các loại của toán hạng với unsigned loại số nguyên, sau đó các toán hạng với unsigned kiểu số nguyên được chuyển thành loại toán hạng với loại số nguyên đã ký.
    • Nếu không, cả hai toán hạng sẽ được chuyển thành loại số nguyên không dấu tương ứng với loại toán hạng với loại số nguyên đã ký.

tôi đã nêu bật một phần áp dụng cho ví dụ cụ thể của bạn.

Khái niệm về xếp hạng chuyển đổi nguyên được định nghĩa trong phần 6.3.1.1 và về cơ bản mô tả những gì bạn có thể mong đợi (loại có độ chính xác thấp hơn xếp hạng thấp hơn loại có độ chính xác cao hơn).

5

Từ Type Conversions:

Các bộ chuyển đổi tiềm ẩn trên trang 44, mặc dù tuyên bố không chính thức, chính là bộ nhớ cho bây giờ. Chúng dễ dàng để nhớ nếu bạn nhận thấy rằng, như tác giả nói, the `lower' type is promoted to the `higher' type,'' where the trật tự '' các loại là

char < short int < int < long int < float < double < long double 

quy tắc Đó là dễ nhớ - "thấp đến cao" - nhưng về ký kết và các loại số nguyên không dấu nó không giúp được gì nhiều, chúng được giải thích một cách độc đáo trong bài viết của Oli. Nhưng thật dễ dàng để nhớ và giúp bạn trong hầu hết các trường hợp.

+0

Làm thế nào để 'unsigned' phù hợp ở đó? là '-1' nhỏ hơn' 2U'? – pmg

+0

Bạn nói đúng, nó chỉ là một phần của toàn bộ câu chuyện. Tôi sẽ tính đến điều này. – emboss

+0

+1: các dấu hiệu thực sự nên là '<=' và, trong C99, có 'dài int' để thêm vào sự nhầm lẫn :) – pmg

2

Theo nguyên tắc chung, C sẽ không so sánh hai giá trị nếu chúng không cùng loại và sẽ không bao giờ chuyển đổi ngầm một biến thành loại có độ chính xác thấp hơn. Trong mã mẫu của bạn, short được đề bạt lên một int, tương đương với văn bản:

int i = 10; 
short s = 5; 

if ((int)s == i){ 
    do stuff... 
} else if ((int)s < i) { 
    do stuff... 
} 

này sẽ làm chính xác những gì bạn mong đợi, nhưng điều này cũng không thực sự của ký/so sánh unsigned.

1

Kiểu dữ liệu là một loại trừu tượng .. theo như máy tính được quan tâm thì không có int hoặc short. Có bộ nhớ và có dữ liệu.

Khi bạn nói int x, bạn đang nói với một máy tính "cho tôi đủ byte để lưu trữ một int", khi bạn nói short y, bạn đang nói ... bạn đoán nó.

short, như bạn mong đợi sẽ nhận ít byte hơn sau đó là int và do đó có thể (và thường xuyên) chứa dữ liệu trong các byte lân cận. Khi so sánh dữ liệu của các loại khác nhau vấn đề là "bit liền kề có gây ra kết quả sai lệch hay không?"

Bất cứ khi nào bạn so sánh hai kiểu dữ liệu khác nhau, bạn thực sự đang so sánh các bit được lưu trữ ở hai vị trí khác nhau. Số lượng tối đa các bit riêng lẻ được lưu trữ để biểu thị dữ liệu cần phải có cùng kích thước để so sánh với công việc

Casting được sử dụng để trợ giúp việc này.

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