2013-06-13 40 views
26

Tại sao char theo mặc định trong phạm vi từ -128 đến 127 khi nó được cho là đại diện cho một 'ký tự' có reprezentations văn bản nằm trong khoảng từ 0 đến 255? Theo nghĩa này, tôi đoán char nên được unsigned theo mặc định, chỉ khi chúng tôi dự định để xử lý nó chỉ giống như 'số' chúng tôi sẽ phải thêm 'đã ký' từ khóa. Vì vậy, tôi nên sử dụng unsigned char khi tôi làm việc với các tập tin văn bản?Tại sao 'char' được ký theo mặc định trong C++?

Ngoài ra, tôi không hiểu tại sao các chức năng đọc và viết của std::ofstream sử dụng char và không unsigned char khi tôi cần làm việc với tệp nhị phân. Ở đó tôi không quan tâm đến chữ ký, phải không? Hơn nữa tôi đã thực hiện successfuly một bản sao của một tập tin JPEG sử dụng signed char như thế này:

//..open all streams.. 
char c; 
while(input.peek()!=EOF){ 
    input.read(&c,1); //std::ifstream input; 
    output.write(&c,1); //std::ofstream output; 
} 
//..close all streams.. 

Kể từ khi nó hoạt động Tôi nghĩ rằng read đọc một unsigned byte s (trong xử lý hình ảnh một unsigned char thường được sử dụng) và đặt c để giá trị có một số giải thích ngẫu nhiên đã ký trong phần bổ sung của 2. Tôi cần phải tạo một biểu đồ của các giá trị, nhưng tôi nhận được một lỗi thời gian chạy vì tôi sử dụng char đã ký làm chỉ mục. Không phải là nó khá ngu ngốc mà tôi phải sử dụng một số diễn viên uc = (unsigned char)c;? khi có thể có ít nhất một quá tải đơn giản của đọc/ghi cho char unsigned?

+14

'char' không phải lúc nào cũng được ký. Và ASCII kết thúc ở 127, do đó, nó khá hợp lý không phải để đi qua xem xét gần như tất cả các hệ thống sử dụng nó. – chris

+0

+1 @chris, tùy thuộc vào việc triển khai. –

+0

Ou, tôi dường như bỏ lỡ ghi chú về char trong tài liệu. Trên máy tính của tôi 'char' được ký theo mặc định và bộ char của nó bao gồm một số lettes có dấu, do đó, nó không có ý nghĩa đối với tôi. –

Trả lời

40

Nó không phải.

Ký kết của char không phải là signed char hoặc unsigned char được xác định thực hiện. Nhiều hệ thống làm cho nó được ký để khớp với các loại khác được ký theo mặc định (như int), nhưng nó có thể không được ký trên một số hệ thống. (Giả sử, nếu bạn vượt qua -funsigned-char đến GCC.)

+1

@DanielKatz: Nó không quan trọng nếu nó là trên trình biên dịch của bạn; đó là * định nghĩa triển khai *. Bạn đã định nghĩa nó theo một cách, người khác có thể sử dụng một cách khác. –

27

Dưới đây là câu trả lời của bạn từ tiêu chuẩn:

3.9.1 loại cơ bản [basic.fundamental]

1 đối tượng khai báo là ký tự char) phải đủ lớn để lưu trữ bất kỳ thành viên của việc thực hiện của bộ ký tự cơ bản. Nếu một ký tự từ tập hợp này được lưu trữ trong một đối tượng ký tự, giá trị tích phân của đối tượng ký tự đó bằng với giá trị của dạng ký tự chữ cái đơn của ký tự đó. Nó được thực hiện xác định cho dù một đối tượng char có thể giữ giá trị âm. Các ký tự có thể được khai báo rõ ràng hoặc không được ký. Plain char, char đã ký, và unsigned char là ba loại riêng biệt. Một char, char đã ký, và một unsigned char chiếm cùng một lượng lưu trữ và có cùng yêu cầu căn chỉnh (basic.types); có nghĩa là chúng có cùng một biểu diễn đối tượng. Đối với các loại ký tự, tất cả các bit của biểu diễn đối tượng đều tham gia biểu diễn giá trị. Đối với các loại ký tự không dấu, tất cả các mẫu bit có thể có của đại diện giá trị đại diện cho các số. Những yêu cầu này không giữ cho các loại khác. Trong bất kỳ việc triển khai cụ thể nào, một đối tượng char đơn giản có thể thực hiện các giá trị giống như một char đã ký hoặc một char chưa ký; cái nào được định nghĩa thực hiện.

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