有几种不同类型的字符串: c风格字符串(包括字符串字面常量和指向以空字符结尾的字符数组的指针),string类型(类类型)
c风格字符串
c风格字符串必须符合某种编码(如ASCII),并且除了字符串的末尾之外,字符串里面不能包含空字符(空字符是字符结束的标志).这些限制使得c风格字符串只能保存文本数据,而不能保存二进制数据(如图片,音频等)
c风格字符串不保存自身长度,要获取一个c字符串的长度,需要遍历整个字符串,直到遇到代表字符串结尾的空字符为止,这个操作的时间复杂度为O(n)(n是字符串长度).
c字符串容易造成缓冲区溢出
如使用strcat函数将src字符串中的内容拼接到字符串的末尾时,
1
char *strcat(char* dest, const char* src)
由于c字符串不记录自身的长度,所以strcat假定用户在执行这个函数时,已经为dest分配了足够多的内存,可以容纳src字符串中的所有内容,但是万一这个假设不成立就会造成缓冲区溢出.
c字符串修改字符串长度时需要进行内存重分配;内存重分配涉及复杂的算法,而且可能需要执行系统调用,通常来说比较耗时.
字符串,字符数组相关API
- c标准库string函数, 共有4个函数
- strlen(p), strcmp(p1, p2), strcat(p1, p2), strcpy(p1, p2)
- 传入此类函数的指针必须指向以空字符结尾的数组
不能使用strlen函数求”使用列表初始化的字符数组的长度,因此列表初始化的字符数组不以空字符结尾 - strlen计算c风格字符串的长度时,c风格字符串末尾的空字符不计算在内
- strcpy(char* dest, const char*src)
- 把src所指向的字符串复制到dest,包括结尾处的空字符
- 如果目标数组dest的内存空间比src的内存空间小,会出现缓冲区溢出
- strcmp(const char* str1, const char* str2)
- 依次比较str1和str2中的一对字符,直到str1或者str2到达字符串结尾或者被比较的一对字符不等.
- 当两个字符串相等时返回0.
- http://www.cplusplus.com/reference/cstring/strcmp/
1 | void testCharArray3() { |
运行结果
1 | strlen("danam"): 5 |
memset和memstcpy fill
- memset
- 头文件string.h(c++头文件cstring)
- memset可以对数组中每个元素赋以相同的值.但是因为memset按字节赋值,即对每个字节赋相同的值,一般只用来填充char型数组(char类型占一个字节),如果填充int数组最好只在要对数组赋值0或-1时使用memset.
- memset函数的格式为:memset(数组名,值,sizeof(数组名))
- 与fill相比,memset执行速度较快.
- fill
- 头文件algorithm
- fill()函数可以将数组或者容器中的某一段区间赋为某个相同的值.和memset不同,这里的赋值可以是数组类型对应范围的任意值.
- fill函数格式:
- fill(arr, arr+n, 0) (其中arr为指向数组首元素的指针,arr+n为指向数组尾元素的指针, 0为要赋的值)
- fill(vec.begin(), vec.end(), 0) (vec.begin()和vec.end()为迭代器表示的范围)