2013-05-12 53 views
16

Xét đoạn mã sau:Sự khác biệt giữa char và ký char trong C++?

#include <iostream> 
#include <type_traits> 

int main(int argc, char* argv[]) 
{ 
    std::cout<<"std::is_same<int, int>::value = "<<std::is_same<int, int>::value<<std::endl; 
    std::cout<<"std::is_same<int, signed int>::value = "<<std::is_same<int, signed int>::value<<std::endl; 
    std::cout<<"std::is_same<int, unsigned int>::value = "<<std::is_same<int, unsigned int>::value<<std::endl; 
    std::cout<<"std::is_same<signed int, int>::value = "<<std::is_same<signed int, int>::value<<std::endl; 
    std::cout<<"std::is_same<signed int, signed int>::value = "<<std::is_same<signed int, signed int>::value<<std::endl; 
    std::cout<<"std::is_same<signed int, unsigned int>::value = "<<std::is_same<signed int, unsigned int>::value<<std::endl; 
    std::cout<<"std::is_same<unsigned int, int>::value = "<<std::is_same<unsigned int, int>::value<<std::endl; 
    std::cout<<"std::is_same<unsigned int, signed int>::value = "<<std::is_same<unsigned int, signed int>::value<<std::endl; 
    std::cout<<"std::is_same<unsigned int, unsigned int>::value = "<<std::is_same<unsigned int, unsigned int>::value<<std::endl; 
    std::cout<<"----"<<std::endl; 
    std::cout<<"std::is_same<char, char>::value = "<<std::is_same<char, char>::value<<std::endl; 
    std::cout<<"std::is_same<char, signed char>::value = "<<std::is_same<char, signed char>::value<<std::endl; 
    std::cout<<"std::is_same<char, unsigned char>::value = "<<std::is_same<char, unsigned char>::value<<std::endl; 
    std::cout<<"std::is_same<signed char, char>::value = "<<std::is_same<signed char, char>::value<<std::endl; 
    std::cout<<"std::is_same<signed char, signed char>::value = "<<std::is_same<signed char, signed char>::value<<std::endl; 
    std::cout<<"std::is_same<signed char, unsigned char>::value = "<<std::is_same<signed char, unsigned char>::value<<std::endl; 
    std::cout<<"std::is_same<unsigned char, char>::value = "<<std::is_same<unsigned char, char>::value<<std::endl; 
    std::cout<<"std::is_same<unsigned char, signed char>::value = "<<std::is_same<unsigned char, signed char>::value<<std::endl; 
    std::cout<<"std::is_same<unsigned char, unsigned char>::value = "<<std::is_same<unsigned char, unsigned char>::value<<std::endl; 
    return 0; 
} 

Kết quả là:

std::is_same<int, int>::value = 1 
std::is_same<int, signed int>::value = 1 
std::is_same<int, unsigned int>::value = 0 
std::is_same<signed int, int>::value = 1 
std::is_same<signed int, signed int>::value = 1 
std::is_same<signed int, unsigned int>::value = 0 
std::is_same<unsigned int, int>::value = 0 
std::is_same<unsigned int, signed int>::value = 0 
std::is_same<unsigned int, unsigned int>::value = 1 
---- 
std::is_same<char, char>::value = 1 
std::is_same<char, signed char>::value = 0 
std::is_same<char, unsigned char>::value = 0 
std::is_same<signed char, char>::value = 0 
std::is_same<signed char, signed char>::value = 1 
std::is_same<signed char, unsigned char>::value = 0 
std::is_same<unsigned char, char>::value = 0 
std::is_same<unsigned char, signed char>::value = 0 
std::is_same<unsigned char, unsigned char>::value = 1 

Có nghĩa là intsigned int được coi là cùng loại, nhưng không charsigned char. Tại sao vậy ?

Và nếu tôi có thể chuyển đổi một char vào signed char sử dụng make_signed, làm thế nào để làm điều ngược lại (chuyển đổi một signed char đến một char)?

+0

Thú vị, tôi biết 'char' có thể được ký hoặc chưa ký, nhưng tôi nghĩ ít nhất nó sẽ tương đương với một trong số đó. – chris

+0

Có thể trùng lặp của [char! = (Ký char), char! = (Unsigned char)] (https://stackoverflow.com/questions/436513/char-signed-char-char-unsigned-char) – jtbandes

Trả lời

12

Theo thiết kế, C++ standard nói char, signed charunsigned char là các loại khác nhau. Tôi nghĩ bạn có thể sử dụng dàn diễn viên tĩnh để chuyển đổi.

5

Thật vậy, tiêu chuẩn chính xác nói rằng char, ký char và unsigned char là 3 loại khác nhau. Một char thường là 8 bit nhưng điều này không được áp đặt theo tiêu chuẩn. Một số 8 bit có thể mã hóa 256 giá trị duy nhất; sự khác biệt chỉ là cách mà 256 giá trị duy nhất đó được diễn giải. Nếu bạn xem xét giá trị 8 bit dưới dạng giá trị nhị phân có dấu, nó có thể biểu diễn các giá trị số nguyên từ -128 (tất cả 1) đến +127. Nếu bạn coi nó là unsigned, nó có thể biểu diễn các giá trị 0 tới 255. Theo tiêu chuẩn C++, char đã ký được đảm bảo để có thể giữ các giá trị -127 đến 127 (not -128!), Trong khi một unsigned char có thể giữ các giá trị 0 đến 255.

Khi chuyển đổi một char thành int, kết quả được thực hiện xác định! kết quả có thể, ví dụ: là -55 hoặc 201 theo việc thực hiện máy của single char 'É' (ISO 8859-1). Thật vậy, một CPU giữ char trong một từ (16bits) hoặc có thể lưu trữ FFC9 hoặc 00C9 hoặc C900, hoặc thậm chí C9FF (trong đại diện lớn và nhỏ endian). Sử dụng ký hoặc unsigned char làm đảm bảo char để int chuyển đổi kết quả.

8

ba biệt nhân vật loại cơ bản: char, char kýchar unsigned. Mặc dù có ba loại ký tự, chỉ có hai biểu diễn: đã ký và chưa ký. (Plain) char sử dụng một trong các biểu diễn này. Biểu diễn hai ký tự nào khác tương đương với charphụ thuộc vào trình biên dịch.

Trong loại không dấu, tất cả các bit đại diện cho giá trị. Ví dụ: một số không ký hiệu char có thể chứa các giá trị từ 0 đến 255 bao gồm.

Tiêu chuẩn không xác định cách các loại đã ký được thể hiện, nhưng chỉ định rằng phạm vi phải được chia đều giữa các giá trị dương và âm. Do đó một 8-bit ký char được đảm bảo để có thể giữ giá trị từ -127 đến 127.


Vậy làm thế nào để quyết định Loại sử dụng không?

Tính toán sử dụng char thường có vấn đề.Char theo mặc định được ký trên một số máy và không được ký trên các máy khác. Vì vậy, chúng tôi không nên sử dụng (plain) char trong biểu thức số học. Chỉ sử dụng nó để giữ các ký tự. Nếu bạn cần một số nguyên nhỏ, hãy chỉ định rõ ràng ký hiệu char hoặc unsigned char.

+0

Tôi biết điều này bài viết là từ lâu rồi nhưng câu trả lời này giống hệt một đoạn trong * C++ Primer *, chương thứ hai. – pkqxdd