首页 > 编程知识 正文

ascii和utf8,unicode和utf8的关系

时间:2023-05-06 00:37:32 阅读:258440 作者:521

1.编码

ASCII 码使用指定的7 位二进制数组合来表示128 种可能的字符。标准ASCII 码也叫基础ASCII码,使用7 位二进制数(剩下的1位二进制为0)来表示所有的大写和小写字母,数字0 到9、标点符号,以及在美式英语中使用的特殊控制字符。
ANSI编码是一种对ASCII码的拓展:ANSI编码用0x00–0x7f (即十进制下的0到127)范围的1 个字节来表示 1 个英文字符,超出一个字节的 0x80~0xFFFF 范围来表示其他语言的其他字符。也就是说,ANSI码仅在前128(0-127)个与ASCII码相同,之后的字符全是某个国家语言的所有字符。不同的国家和地区制定了不同的标准,由此产生了 GB2312、GBK、GB18030、Big5、Shift_JIS 等各自的编码标准。这些使用多个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码。不同语言之间的ANSI码之间不能互相转换,这就会导致在多语言混合的文本中会有乱码。
Unicode码它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。Unicode 编码共有三种具体实现,分别为utf-8,utf-16,utf-32,其中utf-8占用一到四个字节,utf-16占用二或四个字节,utf-32占用四个字节。对可以用ASCII表示的字符使用UNICODE并不高效,因为UNICODE比ASCII占用大一倍的空间,而对ASCII来说高字节的0对他毫无用处。为了解决这个问题,就出现了一些中间格式的字符集,他们被称为通用转换格式,即UTF(Unicode Transformation Format)。常见的UTF格式有:UTF-7, UTF-7.5, UTF-8,UTF-16, 以及 UTF-32。UTF-8(8位元,Universal Character Set/Unicode Transformation Format)是针对Unicode的一种可变长度字符编码。它可以用来表示Unicode标准中的任何字符,而且其编码中的第一个字节仍与ASCII相容,使得原来处理ASCII字符的软件无须或只进行少部份修改后,便可继续使用。

2.typedef

typedef是在计算机编程语言中用来为复杂的声明定义简单的别名,它与宏定义有些差异。它本身是一种存储类的关键字,与auto、extern、mutable、static、register等关键字不能出现在同一个表达式中。
在编程中使用typedef目的一般有两个,一个是给变量一个易记且意义明确的新名字,另一个是简化一些比较复杂的类型声明。

2.1 typedef 与 #define 的异同

利用typedef可以为某一类型自定义名称,这方面与 #define类似,但是两者有3处不同:

与#define不同,typedef 创建的符号名只受限于类型,不能用于值typedef 由编译器解释,不是预处理器在其受限范围内,typedef 比#define(#define只是简单的字符串替换,而且#define之后是没有分号的)更灵活 2.2用法 2.2.1基本用法

假设要用BYTE表示1字节的数组,
只需像定义char类型变量一样定义BYTE,然后在定义前面加上关键字typedef即可:

typedef unsigned char BYTE;//随后,便可使用BYTE来定义变量:BYTE x, y[10], *z;//BYTE x; 等价于 unsigned char x;//BYTE y[10]; 等价于 unsigned char y[10];//BYTE *z; 等价于 unsigned char *z;

通常,typedef定义中用大写字母表示被定义的名称,以提醒用户这个类型名实际上是一个符号缩写。

2.2.2用于指针 typedef char* STRING;//没有typedef关键字,编译器将把STRING识别为一个指向char类型的指针变量;//有了typedef关键字,编译器则把STRING解释成一个类型的标识符,该类型是指向char的指针。//因此:STRING name, sign;//相当于:char *name, *sign;//即name和sign都是指向char类型的指针 2.2.3用于结构 typedef struct complex{float real;float imag;}COMPLEX;//然后便可使用COMPLEX类型代替complex结构来表示复数。//所以,可以这样使用COMPLEXCOMPLEX c1 = {3.0, 6.0};COMPLEX c2; 2.2.4用于给复杂的类型命名

使用typedef时要记住,typedef并没有创建任何新类型,它只是为某个已存在的类型增加了一个方便使用的标签。

typedef char(*FRPTC())[5];//把FRPTC声明为一个函数类型,该函数返回一个指针,该指针指向内含5个char类型元素的数组

对复杂变量建立一个类型别名的方法很简单,你只要在传统的变量声明表达式里用类型名替代变量名,然后把关键字typedef加在该语句的开头就行了。

int *(*func[5])(int, char*);//pFun是我们建的一个类型别名typedef int *(*pFun)(int, char*);//使用定义的新类型来声明对象pFun func[5];//等价于int* (*func[5])(int, char*);//func 右边是一个[]运算符,说明func是具有5个元素的数组;func的左边有一个*,说明func的元素是指针(注意这里的*不是修饰func,而是修饰 func[5]的,原因是[]运算符优先级比*高,func先跟[]结合)。跳出这个括号,看右边,又遇到圆括号,说明func数组的元素是函数类型的指 针,它指向的函数具有int*类型的形参,返回值类型为int。void (*b[10]) (void (*)());//首先为上面表达式void (*)()部分声明一个新类型typedef void (*pFunParam)();//整体声明一个新类型typedef void (*pFun)(pFunParam);//使用定义的新类型来声明对象pFun b[10];//等价于void (*b[10]) (void (*)());double(* (*pa)[9])();//首先为上面表达式(*pa)[9]部分声明一个新类型typedef double(*pFun)();//整体声明一个新类型typedef pFun (*pFunParam)[9];//使用定义的新类型来声明对象,等价于double(*(*pa)[9])();pFunParam pa;//pa是一个指针,指针指向一个数组,这个数组有9个元素,每一个元素都是“doube(*)()”--也即一个指针,指向一个函数,函数参数为空,返回值是“double”。 2.2.5提高程序的可移植性

现有类型创建一个名称,看上去真是多此一举,但是它有时候的确很有用。
C标准规定time()返回整数类型,但是让实现来决定具体是什么整数类型。其原因是,C标准委员会认为没有哪个类型对于所有的计算机平台都是最优选择。所以,C标准委员会决定建立一个新的类型名(如:time_t),并让实现使用typedef来设置它的具体类型。以这样的方式,C标准提供以下通用原型:

time_t time(time_t *);//time_t 在一个系统中是 unsignde long,在另一个系统中可以是unsignde long long.//只要包含time.h头文件,程序就能访问合适的定义。 3.TCHAR

为了使代码兼容ANSI码(使用" “包裹)和Unicode编码(使用L” "包裹),微软公司还提供了通用字符类型TCHAR(就是儒雅的毛巾的字符设置成什么就是什么)
通用字符类型的含义是:
如果在项目属性中选择“Unicode字符集”,则TCHAR代表WCHAR(宽字节变量类型),
如果在项目中选择“多字符集”,则TCHAR代表char(单字节变量类型)。

为了让编译器识别Unicode字符串,必须以在前面加一个“L”,定义宽字节类型(宽字节类型每个变量占用2个字节)方法如下:

wchar_t * p = L"Hello!" ; wchar_t a[] = L"Hello!" ;

如果在程序中既包括ANSI又包括Unicode编码,需要包括头文件tchar.h。
TCHAR是定义在该头文件中的宏,它视你是否定义了_UNICODE宏而定义成:
定义了_UNICODE: typedef wchar_t TCHAR ;
没有定义_UNICODE: typedef char T CHAR ;

_T( )也是定义在该头文件中的宏,视是否定义了_UNICODE宏而定义成:
定义了_UNICODE: #define _T(x) L##x
没有定义_UNICODE: #define _T(x) x

_T宏可以把一个引号引起来的字符串,根据你的环境设置,使得编译器会根据编译目标环境选择合适的(Unicode还是ANSI)字符处理方式
如果你定义了UNICODE,那么_T宏会把字符串前面加一个L。这时 _T(“ABCD”) 相当于 L"ABCD" ,这是宽字符串。
如果没有定义UNICODE,那么_T宏不会在字符串前面加那个L,_T(“ABCD”) 就等价于 “ABCD” 。

在VC++中,我们可以看到如下的定义:

typedef WCHAR TCHAR, *PTCHAR;//原来,它就等价于typedef char TCHAR;typedef char *PTCHAR;//*PTCHAR是char的别名,进一步的意思是说PTCHAR是指向char的地址,即PTCHAR是char*型

_t开头的都是VC++定义的宏,用来匹配不同的版本。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。