zoukankan      html  css  js  c++  java
  • 宽字符标量L"xx"在VC6.0/7.0和GNU g++中的不同实现。

    锲子:本文源于在VCKBASE C++论坛和周星星大哥的一番讨论,这才使我追根索源,找到了理论依据和实践的证明。(本文一些资料和测试代码由周星星提供)

    《The C++ Programming Language 3rd》中有这么两段话:
    from 4.3:
    A type wchar_ t is provided to hold characters of a larger character set such as Unicode. It is a distinct type. The size of wchar_t is implementation-defined and large enough to hold the largest character set supported by the implementation’s locale (see §21.7, §C.3.3). The strange name is a leftover from C. In C, wchar_t is a typedef (§4.9.7) rather than a builtin type. The suffix _  t was added to distinguish standard typedefs.
    from 4.3.1:
    Wide character literals are of the form L´ab´, where the number of characters between the quotes and their meanings is implementation-defined to match the wchar_t type. A wide character literal has type wchar_t.

    这两段话中有两个要点是我们关心的:
    1〉wchar_t的长度是由实现决定的;
    2〉L'ab'的含义是由实现决定的。

    那么GNU g++和VC6.0/7.0各是怎么实现的呢?看下面代码:

     prt padd size_t n p padd pe p n ppep printfp printf a b
        prt aa
        prt bb
        system    
        HWND h FindWindow NULL
        SetWindowTextA h a
        system
        SetWindowTextW h b
        system

    这段代码说明了,g++(Dev-CPP用的是MingGW编译器)中L"xx"解释为把作为non-wide-char的"xx"扩展为作为wide-char的wchar_t,不足则在高位补0;而VC6.0的L"xx"解释为把作为MBCS的"xx"转换为作为unicode的WCHAR,目前的MBCS是以char为一个存储单元的,而WCHAR在winnt.h中定义为typedef wchar_t WCHAR。在win平台上,只要是超过0~127范围内的char型字符,都被视为MBCS,它由1到2个字节组成,MBCS字符集跟它的地区代码页号有关。在某个特定的win平台,默认的代码页号可以在控制面板-〉区域选项中设定。

    关于上述结论可以有下面这个程序来验证:

     prt padd size_t n p padd pe p n ppep printfp printf a b
        prt aa
        prt bb
    
        PSTR pMultiByteStrPSTRa
        PWSTR pWideCharStr nLenOfWideCharStr    nLenOfWideCharStr MultiByteToWideChar CP_ACP pMultiByteStr NULL
        pWideCharStrPWSTRHeapAlloc GetProcessHeap nLenOfWideCharStrWCHAR
        assert pWideCharStr
        MultiByteToWideChar CP_ACP pMultiByteStr pWideCharStr nLenOfWideCharStr
    
        prt pWideCharStr nLenOfWideCharStrWCHAR
    
        system
    

    呵呵,问题已经明了,总结一下:

    1> ISO C中wchar_t是一个typedef,ISO C++中wchar_t是语言内建的数据类型,L'xx'是ISO C/C++语言内建的表示wchar_t的文本量的语法;
    2> wchar_t的长度是由实现决定的;
    3> L'xx'的意义是由实现决定的;
    4> 默认的'xx'是non-wide-char,其每个元素数据的类型是char;与其想对应的L'xx'是wide-char,其每个元素数据的类型是wchar_t。

    为什么C/C++语言把L'xx'定义为由实现决定的呢?这显然是为了C/C++的普适性、可移植性。Bjarne的观点认为,C++的方式是允许程序员使用任何字符集作为串的字符类型。另外,unicode编码已经发展了若干版本了,是否能永久适合下去也不得而知。有关unicode的详细论述以及和其它字符集的比较,我推荐你看《无废话xml》 。

    原文链接:https://blog.csdn.net/linghushaonian/article/details/275359

    补充:

    char a[] = "xxx"; // 鬼知道什么编码,决定的因素太多了
    wchar_t b[] = L"xxx"; // 宽字符,但仍然不知道是何编码,比如在VC中为UTF16,而gcc为UTF32

    char c[] = u8"I'm a UTF-8 string."; // utf8编码
    char16_t d[] = u"This is a UTF-16 string." // UTF-16编码
    char32_t e[] = U"This is a UTF-32 string." // UTF-32编码

    作者:周星星
    链接:https://www.zhihu.com/question/28228731/answer/39946165
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 相关阅读:
    cin 与 getline
    ubuntu换源
    unbuntu 安装 bochs
    np.random.randint()的返回值
    vs2019 写入访问权限冲突
    44.Android之Shape设置虚线、圆角和渐变学习
    43.Android之ListView中BaseAdapter学习
    42.Android之ListView中ArrayAdapter简单学习
    Java编程思想学习(十六) 并发编程
    Java编程思想学习(十五) 注解
  • 原文地址:https://www.cnblogs.com/a3192048/p/12241311.html
Copyright © 2011-2022 走看看