• 返璞归真vc++之字符类型


      在今天,大量使用java与.net的程序员已经很少去真实了解字符的底层表达,但是使用VC++编程,对字符的处理却非常慎重,刚学习vc++肯定会为其中的字符类型给晕头转向,今天本人学习第一节,从字符开始

      特别说明:本文章所有开发环境选用vs2012开发

      在计算机系统中所有的数据与程序指令都是二进制的形式存在的,CPU处理器给特定序列的二进制序列包含有特殊的意义,及我们常说的计算机指令,计算机指令目前流行的X86指令集,以及目前流行android平台下arm指令集,同时所有的数据也是以二进制的形式表达在计算机中,主要表达在计算机体系中的内存,寄存器,以及CPU缓存。所以计算机认识到的字符也就是一串二进制格式的数据,计算机的首要任务就是给这些二进制进行字符的映射,但是在不同的指令集与CPU下,对这些二进制进行翻译的过程中又产生了高位与低位只说,这个只是CPU级别的二进制读取顺序,如何给这些特定的二进制翻译成我们熟悉的人类语言,于是就产生了我们经常所说的字符串编码,常用的有ASCII编码,以及Unicode,

      asccii编码,及单个字节编码,1个字节8个位,也就是说,在计算机内存中,8个连续的位能代码一个字符,那么如何映射成字符呢,那么就是通过我们的assicc表来实现,如下

    八进制十六进制十进制字符八进制十六进制十进制字符
    00 00 0 nul 100 40 64 @
    01 01 1 soh 101 41 65 A
    02 02 2 stx 102 42 66 B
    03 03 3 etx 103 43 67 C
    04 04 4 eot 104 44 68 D
    05 05 5 enq 105 45 69 E
    06 06 6 ack 106 46 70 F
    07 07 7 bel 107 47 71 G
    10 08 8 bs 110 48 72 H
    11 09 9 ht 111 49 73 I
    12 0a 10 nl 112 4a 74 J
    13 0b 11 vt 113 4b 75 K
    14 0c 12 ff 114 4c 76 L
    15 0d 13 cr 115 4d 77 M
    16 0e 14 so 116 4e 78 N
    17 0f 15 si 117 4f 79 O
    20 10 16 dle 120 50 80 P
    21 11 17 dc1 121 51 81 Q
    22 12 18 dc2 122 52 82 R
    23 13 19 dc3 123 53 83 S
    24 14 20 dc4 124 54 84 T
    25 15 21 nak 125 55 85 U
    26 16 22 syn 126 56 86 V
    27 17 23 etb 127 57 87 W
    30 18 24 can 130 58 88 X
    31 19 25 em 131 59 89 Y
    32 1a 26 sub 132 5a 90 Z
    33 1b 27 esc 133 5b 91 [
    34 1c 28 fs 134 5c 92
    35 1d 29 gs 135 5d 93 ]
    36 1e 30 re 136 5e 94 ^
    37 1f 31 us 137 5f 95 _
    40 20 32 sp 140 60 96 '
    41 21 33 ! 141 61 97 a
    42 22 34 " 142 62 98 b
    43 23 35 # 143 63 99 c
    44 24 36 $ 144 64 100 d
    45 25 37 % 145 65 101 e
    46 26 38 & 146 66 102 f
    47 27 39 ` 147 67 103 g
    50 28 40 ( 150 68 104 h
    51 29 41 ) 151 69 105 i
    52 2a 42 * 152 6a 106 j
    53 2b 43 + 153 6b 107 k
    54 2c 44 , 154 6c 108 l
    55 2d 45 - 155 6d 109 m
    56 2e 46 . 156 6e 110 n
    57 2f 47 / 157 6f 111 o
    60 30 48 0 160 70 112 p
    61 31 49 1 161 71 113 q
    62 32 50 2 162 72 114 r
    63 33 51 3 163 73 115 s
    64 34 52 4 164 74 116 t
    65 35 53 5 165 75 117 u
    66 36 54 6 166 76 118 v
    67 37 55 7 167 77 119 w
    70 38 56 8 170 78 120 x
    71 39 57 9 171 79 121 y
    72 3a 58 : 172 7a 122 z
    73 3b 59 ; 173 7b 123 {
    74 3c 60 < 174 7c 124 |
    75 3d 61 = 175 7d 125 }
    76 3e 62 > 176 7e 126 ~
    77 3f 63 ? 177 7f 127 del

    其中,每一个二进制序列对应这一个英文与数字字符,例如常说的十进制数65的二进制表达是1000001,对应的十六进制为0x41;

    我们都知道c语言中,字符是用char类型表示,同时默认的编码格式为asccii编码,也就是说当0x41这个十六进制数在转换成整形值是65,在进行asccii字符转换时,如上表所示,即我们常说的大写字母A,

    下面我们做一个实验,即可证明以上观点是否正确

    #include "stdafx.h"
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        //数值数据
        int i=0x41;
        //内存数据按整形值翻译打印出来
        printf("this is int%d
    ",i);
        //内存数据按照asccii翻译打印出来
        printf("this is char%c
    ",i);
        //打印出内存数据的十六进制格式
        printf("this is binary 0x%x
    ",i);
        return 0;
    }

    打印结果如下

    由此可见,数据的表达都是二进制,只是人为的定义了一些一些含义,你认为是字符的时候,就转换成字符,你认为是数字的时候就变成了数字,你认为是指令的时候,就编程了是指令,只是指令已经被CPU确定了含义。

    那么同理得出Unicode也是类似的结构,只是有点不同

    1、Unicode为双字节编码,也就是说一个字符需要两个字节的容量才能保存

    所以需要特别注意的地方到了,那么以上这些函数printf能处理Unicode字符串吗?

    答案显然是不能的,我们依然写一个程序去验证我们的结果

     

    #include "stdafx.h"
    #include <Windows.h>
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        WCHAR unicodeChar='';
        printf("this is unicode Char%c
    ",unicodeChar);
    
        return 0;
    }

     

     打印的结论:

    可以看到,最终被一个问号代替了,也就是说,printf函数并没有把他解析出来,它依然按照asccii标准去解析,所以变成了问号,那么疑问出来了

    WCHAR到底是一个什么类型呢,怎么在c++标准中并不存在这样一个类型呢?

    答案马上揭晓,我们找到了下面的宏定义

    #ifndef _MAC //非苹果硬件平台
    typedef wchar_t WCHAR;  //实际值是wchar_t  // wc,   16-bit UNICODE character
    #else
    // some Macintosh compilers don't define wchar_t in a convenient location, or define it as a char
    typedef unsigned short WCHAR; //苹果硬件平台实际上是unsigned short
    // wc, 16-bit UNICODE character #endif

     

     也就是如上所述:

    所以在我们常用的电脑下,都是wchar_t类型,那么这又是一个什么类型呢?

    百度百科给出的定义如下,http://baike.baidu.com/link?url=s9f5p8uJEuzVarbu0ilC2XTNRSEQHmxMM0pAHJE5w-Iysq2KFAmRXQUqSuYbbIF-AwmC0e_-Rtsy9NUKP6QVYK

    char是8位字符类型,最多只能包含256种字符,许多外文字符集所含的字符数目超过256个,char型无法表示。
    wchar_t数据类型一般为16位或32位,但不同的C或C++库有不同的规定,如GNU Libc规定wchar_t为32位[1],总之,wchar_t所能表示的字符数远超char型。
    标准C++中的wprintf()函数以及iostream类库中的类和对象能提供wchar_t宽字符类型的相关操作。
    所以是一个宽字符,也就是比char类型大,支持多种语言,比如东南亚国家的语言等,所以我认为在后续的编程中,应该尽可能的使用宽字符类型,同时对于宽字符类型,c++标准也提供了wprintf一系列类来操作
    今天就是以上学习的内容啦,大概就这么多了,通过理解原理,然后去看vc++对这些类型的宏包装,其中不同类型的相互转换应该也是有所理解的。
  • 相关阅读:
    shell脚本基础->
    1->小规模集群架构规划
    推荐系统读书笔记(一)好的推荐系统
    数据挖掘概念与技术读书笔记(二)认识数据
    Linux编辑器vi使用方法详细介绍
    用户不在sudoers文件中的解决方法
    机器学习实战读书笔记(三)决策树
    机器学习实战读书笔记(二)k-近邻算法
    机器学习实战读书笔记(一)机器学习基础
    R语言实战读书笔记(十三)广义线性模型
  • 原文地址:https://www.cnblogs.com/lichaoxyz/p/3636906.html
Copyright © 2020-2023  润新知