2010-04-16 36 views
6

Hôm nay tôi thấy như sau:Nhân char và int với nhau trong C

#include <stdio.h> 

int main(){ 
char x = 255; 
int z = ((int)x)*2; 

printf("%d\n", z); //prints -2 

return 0; 

} 

Vì vậy, về cơ bản tôi nhận được một tràn vì giới hạn kích thước được xác định bởi toán hạng ở phía bên phải của = ký ??

Tại sao không truyền nội dung đó vào int trước khi nhân công việc?

Trong trường hợp này tôi đang sử dụng char và int, nhưng nếu tôi sử dụng "long" và "long long int" (c99), thì tôi sẽ có được hành vi tương tự. Nó thường được khuyên chống lại làm số học với toán hạng của các kích cỡ khác nhau?

Trả lời

11

char có thể được signed or unsigned, tùy thuộc vào trình biên dịch của bạn.

Trong trường hợp của bạn, nó có vẻ như đã được ký, và 255 nằm ngoài phạm vi nó có thể đại diện (có thể, nó chỉ có thể đại diện cho các số từ -128 đến 127).

Vì vậy, sự cố xảy ra khi bạn chỉ định 255 cho biến số char của mình - điều này dẫn đến giá trị được xác định bởi thực hiện, trong trường hợp của bạn, có vẻ là -1.

Khi bạn nhân -1 cho 2, bạn sẽ nhận được -2. Không có bí ẩn ở đó. Các diễn viên để (int) không có gì - loại hẹp hơn int luôn được thăng cấp thành int hoặc unsigned int trước khi thực hiện bất kỳ phép tính nào.

4

Không, bạn không bị tràn trên dòng thứ hai (phép nhân). Vấn đề là trình biên dịch của bạn đang sử dụng signed char theo mặc định và 255 tràn và sẽ có nghĩa là -1. Về cơ bản, bạn đang khởi tạo biến số x với giá trị -1. Việc đúc -1 đến int sẽ cho kết quả là -1 (signed toán hạng sẽ nhận được gia hạn đăng nhập trong khi phát sóng trong khi các toán hạng unsigned sẽ được mở rộng bằng 0).

Bạn có thể buộc các charunsigned bằng cách thêm tiền tố unsigned:

unsigned char x = 255; 
5

Dường như char được ký kết trên nền tảng của bạn. Vì vậy, char x = 255 có hiệu quả giống như char x = -1. Các diễn viên để int không quan trọng.

Hãy thử thay đổi đó để:

unsigned char x = 255; 
3

Các câu trả lời khác giải thích rõ ràng cách ví dụ của bạn "hoạt động", vì vậy tôi sẽ không giải thích lại điều đó.

Tuy nhiên, hãy để tôi quan sát mà chỉ nếu những gì bạn muốn sử dụng là một "số nguyên 8 bit unsigned", sử dụng <stdint.h> 's uint8_t đã (và 16, 32 tuổi, đồng hành 64bit của nó) và tránh xa tất cả các char s , short s và int s trong thế giới này.

+1

#include cho các loại này. – slartibartfast

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