关于各种编译器stdint.h里的 char 和 unsigned char

这个涉及到了 c 语言的发展历史,c 语言是 1969 到 1970 年代之间孕育发展出来的。而且是先有 unix ,后有的 c。早期的硬件条件可想而知和今天无法相比。早期的类型系统也就非常简陋了,所以早期,c 语言里就用了 char 这个基本类型,这个命名早期用途可能是主要为了表达一个字符,但是它成了类型系统里第一个基本类型,大小也给定了,然后此后它已经不可能给改变了,因为最早的人们就这样决定了,并开发出了编译器,人们写的 c 语言代码也开始积累,在历史条件局限下,人们不可能看到未来的发展,问题也不会成为什么问题。它的存储就固定一个字节大小。在发展过程中就成了一个公理,所有编译器都得遵守( sizeof char = 1 ),所以事实上等同于标准。从今天角度看,这个名字作为类型让人误解,但作为历史遗产,后人只能继承下去。你可以看到把指针转型到 char* 去做加减法非常常见,就是这个道理,如果要做个定义,就是 char 是最小的可寻址单位,是存储设备的寻址精度,是类型系统的起点。但 char 本质上又实际上作为整数的存储单位,有没有符号呢又没有公论了,编译器设个选项,你自己决定。随着 cpu 运算的整数范围和总线宽度的提高,从 8 位,16位,32位发展到 64 位(由于 64 位数字相当的大,所以短期内估计不会再往上折腾),对于 int,short, long,这些应该是对应多大的存储呢,就没能形成像 char 那样的标准化潜规则。所以这些东西开始跟随依赖编译器,而不是标准。后来你可以看到几乎所有软件模块都要根据编译环境重新定义自己的基本数据类型,标准里决定整理一下有些混乱的类型,替大家把这事做了,把它们标准化,就增加了stdint.h。以后大家就不用自己每个人 typedef 一遍。因此,实际上 char 对应一个字节是发展初期的历史遗产,等同于标准,这么认为是不会有问题的。后来标准的加入时间上比较晚,给了它更合理的名称。为了照顾早期版本编译器,你还是可以使用 char 和 unsigned char 来对应字节。默认的,和大多数情况下,编译器还是把 char 当有符号数解释,一个整数有没有符号,对结果的差别可就太大了,所以对此一定要注意。至于一个 byte 有 8 bits ?相当于定义,现实标准。以上以后,我们可以明白那么为什么薛非说一个 byte 不一定是 8 bits 了,就是因为他受到 char 这个名称的误导,误以为 char 就是人类语言中的字符,他本质上想表达的是编程语言中用于存储人类语言中的字符的存储单位大小。例如可能是 char 8 bits,也可能是 wchar_t ,对 vc 可能是 16 bits,对 gcc 可能是 32 bits 。但如果是 char,那就没有争议的是 8 bits 。顺便说说字符编码,有52个英文字母,10个数字,加上几十个标点特殊符号,对于一个字节可以表示256个数字的值空间,显得很充裕。还可以定义一些特殊控制字符。但当推广到其他语言时,尤其东亚国家,我们的常用汉字就有几千个,显然一个字节不够,于是 ascii 有了本地编码扩展,例如大陆使用的 gb2312,启用两个字节表示汉字。当然前面那些英文数字符号的编码还是不动的。大家各自有自己的字符编码,所以有自己的字符编码表(code page)。当大家关起门自己搞扩展编码,显然很容易引起碰撞冲突。utf-8 编码把这些本地编码方案争取统一起来,还是在 ascii 基础上扩展,把所有语言字符放到一个全局空间统一编码,一个字符有1,2,3,4个字节的可能。所以叫做多字节字符(串),ascii 是 UTF-8 的子集,对英语文本占多数的情况下使用起来比较经济划算。但一个字符字节数不固定,对字符串操作显得很不方便,比如对一个字符串中有多少个实际字符,在第n个字符处截断,就只能逐个数过去。所以 UTF-16 (Windows unicode) 就是对所有字符不管是不是英文都使用 2 个字节编码,叫做宽字符。这样字节数固定了,字符串操作又和 ascii 编码只有英文的时代一样方便了。UTF-8 和 UTF-16 都属于 unicode 编码,是所有字符的统一空间,每个字符有确定唯一编码。windows 上说 unicode 就是后者。在 widechartomultybyte 这样的函数中,要求指定多字节字符的 codepage ,是 UTF-8,还是本地语言 ascii 扩展。当然当你安装中文版 windows,系统知道已经默认使用了 gb2312 的编码页。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值