??xml version="1.0" encoding="utf-8" standalone="yes"?>
strlen与sizeof的区?br />
2.sizeof是算W,strlen是函数?
3.sizeof可以用类型做参数Qstrlen只能用char*做参敎ͼ且必L?'\0''l尾的?/p>
4.数组做sizeof的参C退化,传递给strlen退化ؓ指针了?
5.大部分编译程序在~译的时候就把sizeof计算q了 是类型或是变量的长度q就是sizeof(x)可以用来定义数组l数的原?
char str[20]="0123456789";//str是编译期大小已经固定的数l?br />int a=strlen(str); //a=10;//strlen()在运行v定
int b=sizeof(str); //而b=20;//sizeof()在编译期定
6.strlen的结果要在运行的时候才能计出来,是用来计字W串的实际长度,不是cd占内存的大小?
7.sizeof后如果是cd必须加括弧,如果是变量名可以不加括弧。这是因为sizeof是个操作W不是个函数?br /> char c;
sizeof c;//变量名可以不加括?/strong>
8.当适用了于一个结构类型时或变量, sizeof q回实际的大,
当适用一静态地I间数组Q?sizeof 归还全部数组的尺寸?br /> sizeof 操作W不能返回动态地被分z了的数l或外部的数l的寸
9.数组作ؓ参数传给函数时传的是指针而不是数l,传递的是数l的首地址Q?br />如:
fun(char [8])
fun(char [])
都等价于 fun(char *)
在C++里参C递数l永q都是传递指向数l首元素的指针,~译器不知道数组的大?br />如果惛_函数内知道数l的大小Q?需要这样做Q?br />q入函数后用memcpy拯出来Q长度由另一个Ş参传q去
fun(unsiged char *p1, int len)
{
unsigned char* buf = new unsigned char[len+1]
memcpy(buf, p1, len);
}
我们能常在用?sizeof ?strlen 的时候,通常是计字W串数组的长?br />看了上面的详l解释,发现两者的使用q是有区别的Q从q个例子可以看得很清楚:
har str[11]="0123456789";//注意q里str大小因该大于{于11Q应考虑'\0'在内Q否则编译器会报?br />int a=strlen(str); //a=10; >>>> strlen 计算字符串的长度Q以l束W?0x00 为字W串l束?br />int b=sizeof(str); //而b=11; >>>> sizeof 计算的则是分配的数组 str[11] 所占的内存I间的大,不受里面存储的内Ҏ变。?
上面是对静态数l处理的l果Q如果是Ҏ针,l果׃一样了
char* ss = "0123456789";
sizeof(ss) l果 4 Q=Q》ss是指向字W串帔R的字W指针,sizeof 获得的是一个指针的之所占的I间,应该是长整型的,所以是4
sizeof(*ss) l果 1 Q=Q?ss是第一个字W?其实是获得了字W串的第一?0' 所占的内存I间Q是charcd的,占了 1 位strlen(ss)= 10 >>>> 如果要获得这个字W串的长度,则一定要使用 strlen
另外,下面的方法可以用于确定该静态数l可以容U_素的个数Q?br />int a[3]={1,2,3};
cout << sizeof a/sizeof ( typeid( a[0] ).name() );
UNICODE~译讄Q?br />C/C++, Preprocessor difinitions 去除_MBCSQ加_UNICODE,UNICODE
在ProjectSetting/link/output 中设|Entry为wWinMainCRTStartup
反之为MBCSQANSIQ编译?/p>
Unicode Q宽字节字符?/p>
1. 如何取得一个既包含单字节字W又包含双字节字W的字符串的字符个数Q?br />可以调用Microsoft Visual C++的运行期库包含函数_mbslen来操作多字节Q既包括单字节也包括双字节)字符丌Ӏ?br />调用strlen函数Q无法真正了解字W串中究竟有多少字符Q它只能告诉你到辄0之前有多个字节?/p>
2. 如何对DBCSQ双字节字符集)字符串进行操作?
函数 描述
PTSTR CharNext Q?LPCTSTR Q? q回字符串中下一个字W的地址
PTSTR CharPrev Q?LPCTSTR, LPCTSTR Q; q回字符串中上一个字W的地址
BOOL IsDBCSLeadByte( BYTE )Q?如果该字节是DBCS字符的第一个字节,则返回非0?/p>
3. Zq使用UnicodeQ?br />Q?Q?可以很容易地在不同语a之间q行数据交换?br />Q?Q?使你能够分配支持所有语a的单个二q制.exe文g或DLL文g?br />Q?Q?提高应用E序的运行效率?br />Windows 2000是用Unicode从头q行开发的Q如果调用Q何一个Windows函数q给它传递一个ANSI字符Ԍ那ُpȝ首先要将字符串{换成UnicodeQ然后将Unicode字符串传递给操作pȝ。如果希望函数返回ANSI字符Ԍpȝ׃首先Unicode字符串{换成ANSI字符Ԍ然后结果返回给你的应用E序。进行这些字W串的{换需要占用系l的旉和内存。通过从头开始用Unicode来开发应用程序,p够你的应用E序更加有效地运行?br />Windows CE 本n是使用Unicode的一U操作系l,完全不支持ANSI Windows函数
Windows 98 只支持ANSIQ只能ؓANSI开发应用程序?br />Microsoft公司COM?6位Windows转换成Win32Ӟ公司军_需要字W串的所有COM接口Ҏ都只能接受Unicode字符丌Ӏ?/p>
4. 如何~写Unicode源代码?
Microsoft公司为Unicode设计了WindowsAPIQ这P可以量减少代码的媄响。实际上Q可以编写单个源代码文gQ以便用或者不使用Unicode来对它进行编译。只需要定义两个宏QUNICODE和_UNICODEQ,可以修改然后重新编译该源文件?br />_UNICODE宏用于Cq行期头文gQ而UNICODE宏则用于Windows头文件。当~译源代码模块时Q通常必须同时定义q两个宏?/p>
5. Windows定义的Unicode数据cd有哪些?
数据cd 说明
WCHAR Unicode字符
PWSTR 指向Unicode字符串的指针
PCWSTR 指向一个恒定的Unicode字符串的指针
对应的ANSI数据cd为CHARQLPSTR和LPCSTR?br />ANSI/Unicode通用数据cd为TCHARQPTSTR,LPCTSTR?/p>
6. 如何对Unicodeq行操作Q?br />字符?Ҏ?实例
ANSI 操作函数以str开?strcpy
Unicode 操作函数以wcs开?wcscpy
MBCS 操作函数以_mbs开?_mbscpy
ANSI/Unicode 操作函数以_tcs开?_tcscpyQCq行期库Q?br />ANSI/Unicode 操作函数以lstr开?lstrcpyQWindows函数Q?br />所有新的和未过时的函数在Windows2000中都同时拥有ANSI和Unicode两个版本。ANSI版本函数l尾以A表示QUnicode版本函数l尾以W表示。Windows会如下定义:
#ifdef UNICODE
#define CreateWindowEx CreateWindowExW
#else
#define CreateWindowEx CreateWindowExA
#endif // !UNICODE
7. 如何表示Unicode字符串常量?
字符?实例
ANSI “string?br />Unicode L“string?br />ANSI/Unicode T(“string?或_TEXT(“string?if( szError[0] == _TEXT(‘J? ){ }
8. Zq应当尽量用操作系l函敎ͼ
q将有助于稍E提高应用程序的q行性能Q因为操作系l字W串函数常常被大型应用程序比如操作系l的外壳q程Explorer.exe所使用。由于这些函C用得很多Q因此,在应用程序运行时Q它们可能已l被装入RAM?br />如:StrCatQStrChrQStrCmp和StrCpy{?/p>
9. 如何~写W合ANSI和Unicode的应用程序?
Q?Q?文本串视ؓ字符数组Q而不是chars数组或字节数l?br />Q?Q?通用数据cdQ如TCHAR和PTSTRQ用于文本字W和字符丌Ӏ?br />Q?Q?显式数据类型(如BYTE和PBYTEQ用于字节、字节指针和数据~存?br />Q?Q?TEXT宏用于原义字W和字符丌Ӏ?br />Q?Q?执行全局性替换(例如用PTSTR替换PSTRQ?br />Q?Q?修改字符串运问题。例如函数通常希望在字W中传递一个缓存的大小Q而不是字节。这意味着不应该传递sizeof(szBuffer),而应该传递(sizeof(szBuffer)/sizeof(TCHAR)。另外,如果需要ؓ字符串分配一个内存块Qƈ且拥有该字符串中的字W数目,那ُ误住要按字节来分配内存。这是_应该调用
malloc(nCharacters *sizeof(TCHAR)),而不是调用malloc(nCharacters)?/p>
10. 如何对字W串q行有选择的比较?
通过调用CompareString来实现?br />标志 含义
NORM_IGNORECASE 忽略字母的大写
NORM_IGNOREKANATYPE 不区分^假名与片假名字符
NORM_IGNORENONSPACE 忽略无间隔字W?br />NORM_IGNORESYMBOLS 忽略W号
NORM_IGNOREWIDTH 不区分单字节字符与作为双字节字符的同一个字W?br />SORT_STRINGSORT 标点符号作为普通符h处理
11. 如何判断一个文本文件是ANSIq是UnicodeQ?br />判断如果文本文g的开头两个字节是0xFF?xFEQ那q就是UnicodeQ否则是ANSI?/p>
12. 如何判断一D字W串是ANSIq是UnicodeQ?br />用IsTextUnicodeq行判断。IsTextUnicode使用一pdl计Ҏ和定性方法,以便猜测~存的内宏V由于这不是一U确切的U学ҎQ因?IsTextUnicode有可能返回不正确的结果?/p>
13. 如何在Unicode与ANSI之间转换字符Ԍ
Windows函数MultiByteToWideChar用于多字节字符串{换成宽字W串Q函数WideCharToMultiByte宽字符串{换成{h的多字节字符丌Ӏ?/p>
14. Unicode和DBCS之间的区?br />Unicode使用Q特别在CE序设计语言环境里)“宽字符集”。「Unicode中的每个字符都是16位宽而不?位宽。」在Unicode中,没有单单使用8位数值的意义存在。相比之下,在“双位组字符集”中我们仍然处理8位数倹{有些位l自w定义字W,而某些位l则昄需要和另一个位l共同定义一个字W?br />处理DBCS字符串非常杂乱,但是处理Unicode文字则像处理有秩序的文字。您也许会高兴地知道?28个Unicode字符Q?6位代码从0x0000?x007FQ就是ASCII字符Q而接下来?28个Unicode字符Q代码从0x0080?x00FFQ是ISO 8859-1对ASCII的扩展。Unicode中不同部分的字符都同样基于现有的标准。这是ؓ了便于{换。希腊字母表使用?x0370?x03FF的代码,斯拉夫语使用?x0400?x04FF的代码,国使用?x0530?x058F的代码,希伯来语使用?x0590?x05FF的代码。中国、日本和韩国的象形文字(ȝ为CJKQ占用了?x3000?x9FFF的代码。Unicode的最大好处是q里只有一个字W集Q没有一点含p?/p>
15.衍生标准
Unicode是一个标准。UTF-8是其概念上的子集QUTF-8是具体的~码标准。而UQテQOQI是所有想辑ֈ世界l一~码标准的标准。UTF-8标准是UnicodeQISO10646Q标准的一U变形方式,
UTF的全U是QUnicode/UCS Transformation FormatQ其实有两种UTFQ一U是UTF-8Q一U是UTF-16Q?
不过UTF-16使用较少Q其对应关系如下Q?br />在Unicode中编码ؓ 0000 - 007F ?UTF-8 中编码Ş式ؓ: 0xxxxxxx
在Unicode中编码ؓ 0080 - 07FF ?UTF-8 中编码Ş式ؓ: 110xxxxx 10xxxxxx
在Unicode中编码ؓ 0000 - 007F ?UTF-8 中编码Ş式ؓ: 1110xxxx 10xxxxxx 10xxxxxx
utf-8是unicode的一个新的编码标?其实unicode有过好几个标?我们知道一直以来用的unicode字符内码都是16?它实际上q不能把全世界的所有字W编在一个^面系l?比如中国的藏文等语U?所以utf-8扩展C32?也就是说理论在utf-8中可容纳二的三十二次方个字符. UNICODE的思想是x所有的字符l一~码,实现一个统一的标?big5、gb都是独立的字W集,q也叫做q东字符?把它拿到h版的WINDOWS上可能将会引起字W编码的冲突....早期的WINDOWS默认的字W集是ANSI.notepad中输入的汉字是本地编?但在NT/2000内部是可以直接支持UNICODE的。notepad.exe在WIN95?8中都是ANSI字符,在NT中则是UNICODE.ANSI和UNICODE可以方便的实现对应映?也就是{?ASCII?位范围内的字W集Q对于范围之外的字符如汉字它是无法表辄。unicode?6位范围内的字W集Q对于不同地区的字符分区分配Qunicode是多个IT巨头共同制定的字W编码标准。如果在unicode环境下比如WINDOWS NT上,一个字W占两字?6位,而在ANSI环境下如WINDOWS98下一个字W占一个字??Unicode字符?6位宽Q最多允?5,535字符Q数据类型被UCؓWCHAR?
对于已有的ANSI字符Qunicode单的其扩展?6位:比如ANSI"A"=0x43,则对应的UNICODE?br />"A"= 0x0043
而ASCII用七存放128个字W?ASCII是一个真正的国标准,所以它不能满其他国家的需?例如斯拉夫语的字母和汉字于是出现了Windows ANSI字符?是一U扩展的ASCII??位存攑֭W??28位仍然存攑֎来的ASCII?
而高128位加入了希腊字母{?br />if def UNICODE
TCHAR = wchar
else
TCHAR = char
你需要在Project\Settings\C/C++\Preprocesser definitions中添加UNICODE和_UNICODE
UINCODE,_UNICODE都要定义。不定义_UNICODE的话Q用SetText(HWND,LPCTSTR),被解释为SetTextA(HWND,LPTSTR),q时API把你给的Unicode字符串看作ANSI字符Ԍ昄q。因为windows API是已l编译好存在于dll中的Q由于不UNICODEq是ANSI字符Ԍ都被看作一Dbuffer,?0B A3 00 35 24 3C 00 00"如果按ANSI读,因ؓANSI字串是以'\0'l束的,所以只能读C字节"0B A3 \0"Q如果按UNICODE读,完整的d'\0\0'l束?br />׃UNICODE没有额外的指CZQ所以系l必ȝ道你提供的字串是哪种格式。此外,UNICODE好象是ANSI C++规定的,_UNICODE是windows SDK提供的。如果不~写windowsE序Q可以只定义UNICODE?br />开发过E:
围绕着文gd、字W串处理展开。文件主要有两种Q?txt?ini文g
1. 在unicode和非unicode环境下字W串做不同处理的Q那么需要参考以?Q?0两条Q以适应不同环境得字W串处理要求?br />Ҏ件读写也一栗只要调用相x口函数时Q参C的字W串前都加上_TEXT{相兛_。如果写成的那个文g需要是unicode格式保存的,那么在创建文件时需要加入一个字节头?br />CFile file;
WCHAR szwBuffer[128];
WCHAR *pszUnicode = L"Unicode string\n"; // unicode string
CHAR *pszAnsi = "Ansi string\n"; // ansi string
WORD wSignature = 0xFEFF;
file.Open(TEXT("Test.txt"), CFile::modeCreate|CFile::modeWrite);
file.Write(&wSignature, 2);
file.Write(pszUnicode, lstrlenW(pszUnicode) * sizeof(WCHAR));
// explicitly use lstrlenW function
MultiByteToWideChar(CP_ACP, 0, pszAnsi, -1, szwBuffer, 128);
file.Write(szwBuffer, lstrlenW(szwBuffer) * sizeof(WCHAR));
file.Close();
//以上q段代码在unicode和非unicode环境下都有效。这里显式的指明用Unicode来进行操作?br />2. 在非unicode环境下,~省调用的都是ANSI格式的字W串Q此时TCHAR转换为CHARcd的,除非昑ּ定义WCHAR。所以在q个环境下,如果dunicode文gQ那么首先需要移?个字节,然后d得字W串需要用MultiByteToWideChar来{换,转换后字W串信息才代表unicode数据?br />3. 在unicode环境下,~省调用得都是unicode格式得字W串Q也是宽字W,此时TCHAR转换为WCHARQ相兛_API函数也都调用宽字W类型的函数。此时读取unicode文g也和上面一P但是d得数据是WCHAR的,如果要{换成ANSI格式Q需要调用WideCharToMultiByte。如果读取ANSI的,则不用移动两个字节,直接d然后视需要{换即可?/p>
某些语言Q如韩语Q必dunicode环境下才能显C,q种情况下,在非unicode环境下开发,q用字W串函数转换也不能达到显C文字的目的Q因为此时调用得API函数是用ANSI的(虽然底层都是用UNICODE处理但是处理l果是按照程序员调用的API来显C的Q。所以必ȝunicode来开发?br />
1Q?span style="FONT: 7pt 'Times New Roman'"> 预编译器程序正文中所遇到的宏名展开成宏定义?/span>
#define PI 3.1415926
2Q?span style="FONT: 7pt 'Times New Roman'"> 可以定义带参数的宏,h模板的部分功能,但是最好将宏参数用括号括v来?/span>
#define MIN(a,b) (((a)<(b))?(a):(b))
3Q?span style="FONT: 7pt 'Times New Roman'"> 通过 ## 宏运符可以拼接起两个串?/span>
#define NAME Q?/span> a,b Q?/span> a##b
4Q?span style="FONT: 7pt 'Times New Roman'"> #undef X 保证不再有称?/span> X 的有定义的宏?/span>
5Q?span style="FONT: 7pt 'Times New Roman'"> 一U特D的宏:条g~译?/span>
#ifdef MACRO_NAME
??/span>
#endif
意思是Q除非应l定义了名ؓ MACRO_NAME 的宏Q否?/span> #ifdef ?/span> #endif 之间的语句将被忽略?/span>
C++ 中应该尽量避免用宏Q?/span>
1 Q?/span> #define PI 3.1415926 可以使用 const double PI=3.1415926 代替?/span>
2 Q?/span> #define MIN(a,b) (((a)<(b))?(a):(b)) 可以使用函数模板代替?/span>
template <class T>
inline T min(T a, T b)
{
return (a<b)?a:b;
}
3. 用于拼接起两个串的宏和条件编译的宏仍然有其用范围?/span>
宏的优点Q?/span>
1Q?span style="FONT: 7pt 'Times New Roman'"> 效率高,执行速度快。但是有的可以?/span> C++ ?/span> inline 函数代替Q仍然保持其执行效率?/span>
宏的~点Q?/span>
1 Q缺乏类型安全检查和作用域规则检查,~译器能看到的只是宏展开后的形式Q所以在宏中的错误是在宏被展开之后报告的,而不是在它定义时Q导致非帔R以理解的错误信息?/span>
2 Q宏名不能重载,而且宏预处理器不能处理递归调用?/span>