Windows上代理项对的wchar_t*大小(BMP中的Unicode字符)

Size of wchar_t* for surrogate pair (Unicode character out of BMP) on Windows

本文关键字:BMP 大小 中的 Unicode 字符 代理 wchar Windows      更新时间:2023-10-16

我在Windows8上遇到了一个有趣的问题。我测试了我可以用wchar_t*字符串表示BMP之外的Unicode字符。以下测试代码给我带来了意想不到的结果:

const wchar_t* s1 = L"a";
const wchar_t* s2 = L"U0002008A"; // The "Han" character
int i1 = sizeof(wchar_t); // i1 == 2, the size of wchar_t on Windows.
int i2 = sizeof(s1); // i2 == 4, because of the terminating '' (I guess).
int i3 = sizeof(s2); // i3 == 4, why?

U+2008A是Han字符,它不在二进制多语言窗格中,因此它应该由UTF-16中的代理对表示。这意味着——如果我理解正确的话——它应该由两个wchar_t字符表示。因此,我预计sizeof(s2)为6(代理项对的两个wchar_t-s为4,终止\0为2)。

那么,为什么sizeof(s2)==4呢?我测试了s2字符串的构造是否正确,因为我已经用DirectWrite渲染了它,并且Han字符显示正确。

更新:正如Naveen所指出的,我试图错误地确定数组的大小。以下代码产生正确的结果:

const wchar_t* s1 = L"a";
const wchar_t* s2 = L"U0002008A"; // The "Han" character
int i1 = sizeof(wchar_t); // i1 == 2, the size of wchar_t on Windows.
std::wstring str1 (s1);
std::wstring str2 (s2);
int i2 = str1.size(); // i2 == 1.
int i3 = str2.size(); // i3 == 2, because two wchar_t characters needed for the surrogate pair.

sizeof(s2)返回存储指针s2或任何其他指针所需的字节数,在系统中为4个字节。它与s2指向的中存储的字符无关。

sizeof(wchar_t*)sizeof(void*)相同,换句话说就是指针本身的大小。在32位系统上总是4,在64位系统上是8。您需要使用wcslen()lstrlenW()而不是sizeof():

const wchar_t* s1 = L"a"; 
const wchar_t* s2 = L"U0002008A"; // The "Han" character 
int i1 = sizeof(wchar_t); // i1 == 2
int i2 = wcslen(s1); // i2 == 1
int i3 = wcslen(s2); // i3 == 2

答案的附录
RE:解开i1i2i3在问题更新中使用的不同单元。

i1值2是以字节为单位的大小
i2值1是wchar_t中的大小,IOW 4字节(假设sizeof(wchar_t)为4)
i3值2是wchar_t中的大小,IOW 8字节