第9章 字符串、字符和字节
9.1 字符串基础
字符串就是一串 零个或多个字符,并且以一个位模式为全0的NUL字节结尾。因此,字符串所包含的字符内部不能出现NUL字节。NUL字节是字符串的终止符,但它本身并不是字符串的一部分,所以字符串的长度并不包括NUL字节。
头文件string.h包含了使用字符串函数所需的原型和声明。
9.2 字符串长度
库函数strlen的原型如下:
size_t strlen(char const *string);
注意:size_t类型在头文件stddef.h中定义,是无符号整型。
无符号数绝不可能是负的。
程序9.1 字符串长度
1 #include <stddef.h>
2
3 size_t strlen(char const *string) {
4 int length;
5
6 for (length = 0; *string++ != '\0';)
7 length += 1;
8
9 return length;
10 }
提示:寻找一种更好的算法比改良一种差劲的算法更有效率,复用已经存在的软件比重新开发一个效率更高。
9.3 不受限制的字符串函数
最常用的字符串函数都是“不受限制”的,只是通过寻找字符串参数结尾的NUL字节来判断长度。
9.3.1 复制字符串
复制字符串的函数是strcpy,原型如下所示:
char *strcpy(char *dst, char const *str);
由于dst参数将进行修改,dst必须是个字符数组或者是一个指向动态分配内存的数组的指针,不能使用字符串常量。
目标参数的以前内容将被覆盖并丢失。即使新的字符串比dst原先的内存更短,由于新字符串是以NUL字节结尾,所以老字符串最后剩余的几个字符也会被有效地删除。(内存中残余字符依然存在,但是无法进行访问操作了)
9.3.2 连接字符串
strtcat函数把一个字符串添加(连接)到另一个字符串的后面,原型如下:
char *strcat(char *dst, char const *str);
要求dst参数原先已经包含了一个字符串(可以是空字符串)。
9.3.3 函数的返回值
9.3.4 字符串比较
“词典比较”
库函数strcmp用于比较两个字符串,原型如下:
9.4 长度受限的字符串函数
9.5 字符串查找基础
9.5.1 查找一个字符
在一个字符串中查找一个特定字符最容易的方法是使用strchr和strchr函数,原型如下所示:
9.5.2 查找任何几个字符
查找任何一组字符第1次在字符串中出现的位置。
9.5.3 查找一个子串
程序9.2 查找子串最右一次出现的位置
1 #include <string.h>
2 char* my_strrstr(char const *s1, char const *s2) {
3 register char *last;
4 register char *current;
5 last = NULL;
6 }
9.6 高级字符串查找
9.6.1 查找一个字符串前缀
strspn和strcspn函数用于在字符串的起始位置对字符计数。原型如下所示:
group字符串指定一个或多个字符。受托人span返回str起始部分匹配group中任意字符的字符数。
第17章 经典抽象数据类型
17.1 内存分配
所有的ADT都必须确定一件事情——如何获取内存来存储值。有三种可选的方案:静态数组、动态分配的数组和动态分配的链式结构。
警告:必须保证目标字符数组的空间足以容纳需要复制的字符串。
17.2 堆栈
后进先出(LIFO)
17.2.1 堆栈接口
17.2.2 实现堆栈
堆栈是最容易实现的ADT之一。
一、数组堆栈
提示:所有不属于外部接口的内容都被声明为static,这可以防止用户使用预定义接口之外的任何方式访问堆栈中的值。
三、链式堆栈
17.3 队列
队列是一种先尽显出(FIFO)的结构。
17.4 树
二叉搜索树
17.5 实现的改进
17.5.4 标准函数库的ADT
泛型(genericity)