char16_t、unsigned short 和 UTF-16 之间有密切的关系:
- 定义和大小:
// 这三种类型在大多数系统上都是16位
static_assert(sizeof(char16_t) == 2, "char16_t must be 16 bits");
static_assert(sizeof(unsigned short) == 2, "unsigned short must be 16 bits");
- 关系说明:
-
char16_t:
- C++11引入的类型
- 专门用于表示UTF-16编码的字符
- 保证16位大小
- 类型安全,语义明确
-
unsigned short:
- 传统C/C++类型
- 通常是16位
- 常用来存储UTF-16编码
- 平台可能有差异
-
UTF-16:
- 一种Unicode编码方式
- 使用16位或32位(代理对)表示字符
- 基本平面字符用16位表示
- 扩展平面字符用代理对(32位)表示
- 使用示例:
// 不同表示方式的等价性
char16_t c1 = u'你';
unsigned short c2 = 0x4F60; // "你"的UTF-16编码
- 转换示例:
// 类型转换
char16_t* str1 = u"Hello";
unsigned short* str2 = (unsigned short*)str1;
// UTF-16编码处理
void process_utf16(const char16_t* str) {
while (*str) {
if (*str >= 0xD800 && *str <= 0xDBFF) {
// 处理代理对
char16_t high = *str++;
char16_t low = *str++;
// 计算实际Unicode码点
int codepoint = ((high - 0xD800) << 10) +
(low - 0xDC00) + 0x10000;
} else {
// 基本平面字符
int codepoint = *str++;
}
}
}
- 实际应用:
// 字符串转换函数
std::string utf16_to_utf8(const char16_t* input) {
std::string output;
while (*input) {
char16_t ch = *input++;
if (ch < 0x80) {
// ASCII
output += static_cast<char>(ch);
}
else if (ch < 0x800) {
// 2字节UTF-8
output += static_cast<char>(0xC0 | (ch >> 6));
output += static_cast<char>(0x80 | (ch & 0x3F));
}
else if (ch >= 0xD800 && ch <= 0xDBFF) {
// 处理代理对
char16_t high = ch;
char16_t low = *input++;
int codepoint = ((high - 0xD800) << 10) +
(low - 0xDC00) + 0x10000;
// 4字节UTF-8
output += static_cast<char>(0xF0 | (codepoint >> 18));
output += static_cast<char>(0x80 | ((codepoint >> 12) & 0x3F));
output += static_cast<char>(0x80 | ((codepoint >> 6) & 0x3F));
output += static_cast<char>(0x80 | (codepoint & 0x3F));
}
else {
// 3字节UTF-8
output += static_cast<char>(0xE0 | (ch >> 12));
output += static_cast<char>(0x80 | ((ch >> 6) & 0x3F));
output += static_cast<char>(0x80 | (ch & 0x3F));
}
}
return output;
}
- 区别要点:
-
类型安全:
char16_t* str1 = u"Hello"; // 明确的UTF-16字符串 unsigned short* str2; // 可能是任何16位数据
-
编译器支持:
// char16_t支持字面量前缀 char16_t* str = u"你好"; // UTF-16字面量
-
平台兼容性:
#ifdef _WIN32 typedef wchar_t utf16_char; // Windows #else typedef char16_t utf16_char; // 其他平台 #endif
- 最佳实践:
// 现代C++推荐使用char16_t
void process_text(const char16_t* text) {
// UTF-16处理
}
// 处理遗留代码
void legacy_function(const unsigned short* text) {
// 转换为char16_t处理
const char16_t* modern_text = reinterpret_cast<const char16_t*>(text);
process_text(modern_text);
}
总结:
- char16_t是专门为UTF-16设计的类型
- unsigned short常用于旧代码中表示UTF-16
- 两者在大多数情况下可以互换使用
- 推荐在新代码中使用char16_t
- UTF-16编码可以用这两种类型存储