C++中char类型详解

来源:互联网 发布:百度网盘会员破解mac 编辑:程序博客网 时间:2024/06/06 05:11
# 1char与字符的关系    ##1.1char类型到底代表什么      提到char类型,我相信学过C/C++的并不会陌生,char类型代表一个字节,在内存中有8位,所以signed char的范围为-128~127,unsigned char的范围为0~255。不过C++中的char到底真的指这个么?在这之前,首先需要明白位和字节的概念。    ##1.2位和字节      在计算机中,通常8位代表1个字节,即1byte=8bits,然而C++对于字节的定义与此不同,这或许跟我们熟知的8bit代表1字节截然不同。C++对字节的定义是至少能够容纳实现的基本字符集的相邻位组成,也就是说可能取值的范围至少大于等于字符数目,而我们目前熟知的ASCII码以及EBDCIC码用8位组合足以表示,在这种字符集系统上C++的字节确实是8位,然而在国际编程中采用更大的字符集比如Unicode等时,8位组合无法表示所有字符,因此一个字节可能需要16位甚至更多,在这种系统上,C++中的一个字节可能就不是代表8bit了,这是C++对字节的定义,这里我们一定不能搞混淆了。只有在常见的ASCII码等字符集上才是如此,一个char用8位表示。    ##1.3什么是字符集      字符集是多个字符的集合,比如数字,字母,符号等,比如有常见的ASCII码,它是由美国ANSI制定的,包括常见的数字,字母等等,它通过8位二进制数来表示某个字符,比如字符‘A’,它的10进制数是65,16进制数是0x41,我们用UE打开1个文本文件,通过16进制视图可以清晰的看到‘A’的值是0x41,而‘0’的10进制数是48,它在16进制数中是0x30。这里的10进制数和16进制数代表什么意思呢?其实不管是字母还是数字还是其它看起来奇奇怪怪的符号,在二进制中都是存储在一个字节中,也就是8位。我们所看到的‘A’其实在内存中表示的数据为01000001,而这块内存数据如果被解释为整数,那就是65,如果是16进制数,那就是0x41,下面来看两个定义,这两条定义是否等价?    char score =65;    char score=‘A’;      答案是仅在ASCII码编码系统上才有效,因为‘A’在ASCII码编码方式中它的10进制就是65,所以两者等效,而如果在其它编码方式中的‘A’换成了87,那么65就可能表示的是其它字符而不是‘A’了,因此需要根据系统采用的字符集来定,这里我们都采用ASCII码。至于其它例如EBCDIC,Unicode等编码方式如果有兴趣继续了解的话可以自行参考其它相关资料。#2C++中的char    ##2.1如何表示char      正如上面写到的,char代表一个字符,其实就是把内存中的某些二进制组合代表某个字符。声明某个字符的时候可以使用char,unsigned char 或者signed char,字符用单引号括起来,且单引号内只能有1个字符,例如    char a=‘b’;    unsigned char b='\032';    signed char c='\n';      C++中的char并不指明这个char是signed的,这点和int、long等其它整型不同,例如int、long等如果不带unsigned则默认表示属于signed。对于第一种定义方式直接指明变量a是字符‘b’,变量b则通过‘\032’定义为8进制为032(10进制就是26)的字符也就是Ctrl+Z这个字符,变量c通过转义字符定义为换行字符。      如果将char用作数值类型,unsigned char可以表示0~255,而signed char只能表示-128~127,如果要用1个char存储200,那么有些系统可以这样做,而有些不可以。但是unsigned char都可以,因为它可以表示到255。另一方面,如果是存储ASCII码字符,则有没有符号都没关系,直接用char即可。      可以看到我们在定义字符的时候无论通过直接字符赋值还是用其8进制,10进制,16进制等都可以。其中10进制数可以直接赋值,而8进制,16进制,转义字符等需要用‘’括起来并在前面加转义序列\才行。不过尽量推荐在可以同时使用数字转义序列和符号转义序列时采用符号转义序列,因为数字表示与特定编码方式有关,而符号表示适用于任何编码方式。    ##2.2通用字符名      C++除了允许基本的源字符集外,还允许提供扩展的源字符集以及执行字符集,比如德国的日耳曼元音变音等等。C++有这样一种表示特殊字符字符的机制,它独立于任何特定的键盘,使用的是通用字符名。通用字符名的用法类似于转义序列。可以以\u或者\U大头。\u后面跟4个16进制数,\U后面跟8个16进制数。这些位表示的是ISO 10646的码点。这些扩展字符可以在标识名或者字符串中使用,例如:    int k\u00F6rper;    cout<<"Let them eat g\u00F6teau.\n";      其中\u00F6表示的字符是Ö,那么第一个it变量就是kÖrper,第2个变量字符串打印出来则是Let them eat gÖteau.      如果系统不支付ISO 10646,则无法打印出上述的字符。C++使用通用编码名是因为应将\u00F6解释为Unicode码点为U-00F6的字符。支持Unicode的编译器会知道这表示字符Ö,但无需使用内部编码00F6,在不同的系统中该字符的编码可能不同。在源代码中可使用适用于所有系统的通用编码名,而编译器将根据当前系统使用合适的内部编码表示它。      补充:Unicode编码提供了一种表示各字符集的解决方案,ASCII码只是其一个子集,Unicode还包括很多拉丁字符,象形文字等。到目前为止,其可以表示10万多个符号和90多个手写符号并在不断发展。Unicode给每个字符指定了一个编码-码点,比如U-222B,U表示这是一个Unicode字符,而222B是该字符(积分正弦符号)的码点。ISO建立了1个小组开发ISO 10646,这也是一个对多种语言文本进行编码的标准。    #2.3wchar_t      前面已经介绍过字符集了,那么程序处理的字符集可能无法用1个8位的字节表示,比如日文汉字系统。对于这种情况,C++处理方式有两种:第一,编译器厂商把char定义为16位的字节甚至更大,第二,可以同时支持小型基本字符集和较大的扩展字符集。8位的char表示基本字符集,而wchar_t(宽字符类型)表示扩展字符集。wchar_t是一种整数类型,有足够大的空间表示系统使用的最大扩展字符集,依据底层系统来实现,在一个系统中可能是unsigned short,在另外一个系统中可能是int。定义一个wchar_t类型的字符时,需要在字符前面加上前缀L,比如:    wchar_t name=L'l';      而在C++中用cin,cout进行输入输出时,无法处理wchar_t类型,因为它们把输入输出当成char流,需要采用wcin和wcout,比如输出宽字符串:    wcout<<L"xixi"<<endl;    ##2.4C++11新增的char16_t和char32_t      随着Unicode的发展,wchar_t也不能满足需求了,并且在计算机上进行字符和字符串编码时,仅使用Unicode码点并不够。C++11标准新增了两个新增的类型,char16_t和char32_t,前者长16位,后者长32位,并且都是无符号类型。      C++11中使用小写u前缀表示char16_t字符常量或者字符串常量,使用大写U前缀表示char32_t字符常量或者字符串常量,u或者U前缀指明该字符的类型为char16_t还是char32_t,比如:    char16_t ch1=u'q';    char32_t cha2=U"\U0000022B";
1 0
原创粉丝点击