从C++里的一大堆字符串说起
写数据库管理系统时遇到了不少关于C++字符串的问题,要命的是C++的字符串种类实在是太多了,今天试着搜集一些资料总结一下。
¶char foo[bar] 和 char* foo
char foo[bar]
这种形式被称为“C风格字符串”,它是从C语言中流传下来的。它实际上完全就是char型的数组,只是你可以用这样的方式来给它赋值,看上去比较像“字符串”:
1 | //这两行都定义了相同的字符串"Hello" |
char* foo
是声明了一个字符指针,指向单个字符,可以将其当作以'\0'
为末尾的字符串的首字符地址。如果要把字符串赋给它,需要先申请内存空间,再使用memcpy()
或strcpy()
。当然,也可以不分配空间,直接用十分危险的指针赋值。
1 | char* foo1 = (char*)calloc(6, sizeof(char)); |
¶CString
CString
是MFC
的类,使用它需要包含afx.h
。
什么是MFC?
微软基础类库(英语:Microsoft Foundation Classes,简称MFC)是一个微软公司提供的类库(class libraries),以C++类的形式封装了Windows API,并且包含一个(也是微软产品的唯一一个)应用程序框架,以减少应用程序开发人员的工作量。其中包含的类包含大量Windows句柄封装类和很多Windows的内建控件和组件的封装类。
总之,作为Visual C++的一部分,这是一个上古遗留之物。不愧是十年前的课设……
CString是MFC中最常用的字符串类。其数据成员只有一个,那就是字符串在内存中的起始地址。它还有许多方法,如多种构造函数、用于连接和比较的运算符重载、用于格式化的Format
,以及各种用于对字符串进行替换、查找、删除的方法。这个类将C++中极为复杂、包含大量内存操作的字符串操作简化了不少。
¶string
string之前一直弄不太明白。这明明是每个语言都应该有的基本东西,但是鉴于C和C++之间乱七八糟的关系以及错综复杂的各种标准,就连这种“基本”也轮廓模糊到让人难以提起兴趣探索。
需要知道的是,**string是C++标准库中的类。**确切地说,string类定义于C++标准库的<string>
头文件。
关键的问题是,什么是C++标准库?这个名字很容易和标准模板库(Standard Template Libraries, STL)混淆,但实际上它们最开始是不同的东西。C++被标准化最早是1998年的ISO/IEC 14882:1998
,即所谓的C++98。而STL始于C++尚未被标准化的1993年,它很大程度上影响了几年后C++标准中标准库的制定,因此其内容与C++标准库有非常大的重合。但需要注意的是,STL不完全是C++标准库的一部分,C++标准里也从来没有“STL”这一说法。C++标准库中的“STL”可以说是STL的一个“Fork”。
C++标准库包含一系列不带.h
后缀的头文件,用尖括号引用。其中除宏定义以外的内容包含在名称空间std
中,这也是许多C++程序都有一句using namespace std;
的原因。
这是cppreference上对std::qsort
的一段示例:
1 |
|
¶LPSTR,以及各种乱七八糟的
这就是较为难以理解的东西了,名字让人一头雾水。LPSTR
算是最简单的形式,还有什么LPCTSTR
,PCTSTR
等等,这都是些啥?
其实这些全大写的神秘数据类型依然来自MFC,它们都是Windows特色数据类型。STR显然代表的是字符串,重要的是它们的前缀。
前缀中主要包含这么几个字母:
- LP:长指针Long Pointer,代表这是一个32位指针。说是Long是因为上古Windows中的Pointer还是16位。
- C:常量Const,代表这是一个常量。
- T:代表使用
_T
宏,这个宏是用于动态支持Unicode这样的宽字节编码(即用多个字节代表一个字符)的。如果Unicode有定义,那么带T前缀的字符串就是Unicode编码的,否则依然是窄字节编码ANSI。 - W:宽Wide,代表使用宽字节编码,如Unicode。
此外,MFC中还有神秘的BYTE
、WORD
、DWORD
,其实就是分别对应unsigned char
、unsigned short
、unsigned long
。
关于ANSI和Unicode,另外再开一篇文章讲好了。