char,wchar_t,TCHAR 三者的区别与联系(ZZ)

来源:互联网 发布:淘宝网2017女装夏装 编辑:程序博客网 时间:2024/05/22 04:57

char,wchar_t,TCHAR 三者的区别与联系
 
 
char wchar_t TCHAR

TCHAR根据预定义情况,可以是char和wchar_t中的一种,不再是什么特殊类型。

char是个8位一个字节的正数,也就是首位为0;
char型可以读写汉字,但由于汉字需要2个字节来表示,因此实际操作时有很多不便之处.
缺点如下:
1 引用字符数组中的汉字不方便.
如 char ch[]="真不方便";
引用中的"真",不可以用ch[0]来引用,这样只有半个字节,而且是负数,显示"?";
2 中间读写不方便.
依照愚见,要我把上述数组中的'不'改成'是'的话,我要采用这个笨方法:
char temp[]="是";
ch[2]=temp[0];ch[3]=temp[1];
读我也这么读.
3 查找不方便.查找指定汉字的话,由于汉字不是单一字节字符,所以要每个比较2次;
不可以用STL中find算法了,但可以用子串匹配算法seach.但同样有很多麻烦事情要做.
4 当有asc码去替换汉字时候,由于一个字节要替换2个字节的位置,因此要多个空位,怎么办?
当然,不介意的话可以用空格补充.但注意,标准输入函数对于常量字符串常常忽略空格,这样你还得注意这个方面.
不幸的事情马上发生,用汉字去替代普通的ascII码,怎么办?你不得不把所有的字符向后移动一个位置.如果碰巧这是个常量字符串,就会出现数组越界的问题.
5统计字符数目是个头痛的问题.当汉字与asc码交错出现的时候,你用strlen或者.size()得到值仅仅是个数量上的,实际上,谁会把在数汉字的时候,一个算2个呢?
为此必须计算总体字符数,还有字符为负的字符数,然后 实际字数=总体-负数/2;

唯一值得一提的是,对于全部直接读写没有任何问题,cout自动就能正确的写出汉字来.这一点比起wchar_t,我想是最大的优点了.


c++标准中规定,wchar_t的实现根据具体编译器而定.这就是说,wchar_t不一定是个什么东西呢.
但wchar_t是一个short型的整数,16位,2字节,这个是没有错的.
定义一个wchar_t变量的方法如下:
wchar_t p[]=L"这个是宽字符~~!";//加上一个标示符L,表示long
用sizeof(p[0]),发现值等于2;说明确实是2个字节的.对于普通asc码拓展方式为,
如 a 为65,拓展为 65 00(非16进制,只是简单描述下);
因此
wchar_t p[]=L"admin~~!";
strlen((char*)p)=1;因为a的后面有休止符0了.
对于宽字符的结束符为00 00;
讨论asc码的宽字符没有啥意义,关键是讨论汉字的宽字符.

   wchar_t p[]=L"这个是宽字符~~!";
对于汉字的wchar_t实现是怎么样的呢?汉字已经是2个字节了,就不用补一个字节的零位了.是么?c++标准中规定,wchar_t的实现根据具体编译器而定.这就是说,wchar_t不一定是个什么东西呢.
按照我用的dev-c++4.9.9.2结果确实是不用再扩充零位了.
为了编译成功,我在编译选项中添加了: -finput-charset=GB2312
#include<iostream>
using namespace std;
int main(){
 wchar_t p[]=L"啊shi";
 char q[3];
 q[1]=(p[0]+32896)>>8;
 q[0]=(p[0]+32896)&255;
 q[2]='/0';
 char qq[]="啊";
 cout<<"p[0]="<<p[0]<<" ( p[1]="<<p[1]<<"    p[2]="<<p[2]<<endl;
 cout<<"p="<<(char*)p<<endl;
 cout<<"q[0]="<<(int)q[0]<<"    q[1]="<<(int)q[1]<<"    q[2]="<<(int)q[2]<<endl;
 cout<<"q="<<q<<endl;
 cout<<"qq[0]="<<(int)qq[0]<<"    qq[1]="<<(int)qq[1]<<"    qq[2]="<<(int)qq[2]<<endl;
 cout<<"qq="<<qq<<endl;

 cout<<strlen((char*)p)<<endl;
 cout<<"p[0]长度="<<sizeof(p[0])<<endl;
 cout<<"p[1]长度="<<sizeof(p[1])<<endl;
 int a;
 cin>>a;
      return 0;
}
运行结果如下
p[0]=21834 ( p[1]=115    p[2]=104
p=JUs
q[0]=-54    q[1]=-43    q[2]=0
q=收
qq[0]=-80    qq[1]=-95    qq[2]=0
qq=啊
3
p[0]长度=2
p[1]长度=2
可以发现的就是:
1 'J'=74,'U'=85,21834=85*256+74;而p[0]=74,p[1]=85,这个顺序值得注意.
2 宽字符和char汉字编码不一样啊,由
q[0]=-54    q[1]=-43    q[2]=0
q=收
qq[0]=-80    qq[1]=-95    qq[2]=0
qq=啊
可以看出,同时也不一定为负.J,U都是正数啊.用的是UFT_8码
但同时有人指出(参看参考资料),有时候编译器实现把汉字扩充为4个字节
比如 "啊",应该为 74 85 ,但扩充为74 00 85 00,据说是 Dev-CPP4990 版本.我和他就差2个小版本号,差距有这么大么?
汗了~~
然后说下输入输出问题.
用cout<<p;结果输出了p的地址;
据说用wcout可以,结果不能编译(dev-c++4.9.9.2),对于其他的,还得使用wchar_t特有的版本函数.这里就更乱了.改日探索清楚再说.
还有许多标准string只支持char,同样引发很多麻烦呢.
对于这些麻烦,我觉得甚至不能完成任务了;而char,尽管怎么麻烦,还是可以的.所以,我还是决定先只用char了.
还有其他很多问题尚待解决.

在vc.net2005中,用w_chart完全可以胜任汉字的任务,我已经验证过了。在dev-c++中还有一些困难,导致2者很多不兼容的地方。

上述讨论肯定有很多错误,希望大家批判阅读,同时有中肯意见,请留言。

参考资料 http://www.vckbase.com/document/viewdoc/?id=1317
 
 

原创粉丝点击