第四章、串
1、C语言内存管理(内存分区)
C语言经过编译之后将内存分为以下几个区域:
- (1)栈(stack)区:由编译器进行管理,自动分配和释放,存放函数调用过程中的各种参数、局部变量、返回值以及函数返回地址。操作方式类似数据结构中的栈。
- (2)堆(heap)区:用于程序动态申请和释放空间。
C语言中的malloc和free,C++中的new和delete均是在堆中进行的。正常情况下,程序员申请的空间在使用结束后应该释放,若程序员没有释放空间,则程序结束时系统自动回收。注意:这里的堆并不是数据结构中的堆。 - (3)全局(静态)存储区:分为
DATA段和BSS段。DATA段(全局初始化区):存放已初始化的全局变量和静态变量(用static关键字修饰);BSS段(全局未初始化区):存放未初始化的全局变量和静态变量;- 其中
BSS段在程序执行之前会被系统自动清0,所以未初始化的全局变量和静态变量在程序执行之前已经为0; - 程序结束时自动释放。
- (4)文字常量区:存放常量字符串,程序结束后由系统释放。
- (5)程序代码区:存放程序的二进制代码。
全局变量和静态变量保存在内存的全局存储区中,占用静态的、永久性的存储单元;
局部变量保存在栈中,只有所在函数被调用时才由系统动态在栈中分配临时性的存储单元。
2、知识框架

3、串的定义
- 字符串简称串,计算机上非数值处理的对象基本都是字符串数据。
- 串(string) :是由零个或多个字符组成的有限序列。一般记为:
S = 'a1a2 · · · an'(n ≥ 0) - 其中
S是串名,单引号括起来的字符序列是串的值,ai可以是字母、数字或其他字符; - 串中字符的个数
n称为串的长度,n = 0时的串称为空串 (用∅表示); - 由一个或多个空格(空格是特殊字符)组成的串称为空格串 (注意:空格串不是空串),其长度为串中空格字符的个数。
- 串中任意多个连续的字符组成的子序列称为该串的子串,包含子串的串称为主串 。
- 某个字符在串中的序号称为该字符在串中的位置。
- 子串在主串中的位置以子串的第一个字符在主串中的位置来表示。
- 当两个串的长度相等且每个对应位置的字符都相等时,称这两个串是相等的。
例如:有串A = 'China Beijing',B = 'Beijing',C = 'China',则它们的长度分别为13、7和5。B和C是A的子串,B在A中的位置是7,C在A中的位置是1。
- 串的逻辑结构和线性表极为相似,区别仅在于串的数据对象限定为字符集。
- 线性表的基本操作主要以单个元素作为操作对象,如查找、插入或删除某个元素等,而串的基本操作通常以子串作为操作对象,如查找、插入或删除一个子串等。
4、串的存储结构
(1)定长顺序存储表示
- 类似于线性表的顺序存储结构
- 用一组地址连续的存储单元存储串值的字符序列
- 为每个串变量分配一个固定长度的存储区,即定长数组
#define MAXLEN 255 //预定义最大串长为255
typedef struct {
char ch[MAXLEN]; //为每个分量存储一个字符
int length; //串的实际长度
} SString;
- 串的实际长度只能小于等于
MAXLEN,超过预定义长度的串值会被舍去,称为截断。 - 串长有两种表示方法:
- 一是如上述定义描述的那样,用一个额外的变量
length来存放串的长度; - 二是在串值后面加一个不计入串长的结束标记字符
\0,此时的串长为隐含值。
- 一是如上述定义描述的那样,用一个额外的变量
- 在一些串的操作(如插入、联接等)中,若串值序列的长度超过上界
MAXLEN,约定用“截断”法处理。
(2)堆分配存储表示
- 以一组地址连续的存储单元存放串值的字符序列
- 但存储空间是在程序执行过程中动态分配得到的
typedef struct {
char *ch; //按串长分配存储区,ch指向串的基地址
int length; //串的长度
} HString;
- 在C语言中,存在一个称之为“堆”的自由存储区,并利用
malloc和free来完成动态存储管理。 - 利用
malloc为每个新产生的串分配一块实际串长所需的存储空间,若分配成功,则返回一个指向起始地址的指针,作为串的基地址,这个串由ch指针来指示;若分配失败,则返回NULL。 - 已分配的空间可使用
free来释放掉。
(3)块链存储表示
- 类似于线性表的链式存储结构
- 由于串的特殊性(每个元素只有一个字符),在具体实现时,每个结点既可以存放一个字符,也可以存放多个字符。
- 每个结点称为块,整个链表称为块链结构。
- 下图是结点大小为4(即每个结点存放4个字符)的链表,最后一个结点占不满时通常用
#补上:
- 下图是结点大小为1的链表:

5、串的基本操作
StrAssign(&T, chars):赋值操作。把串T赋值为charsStrCopy(&T, S):复制操作。由串S复制得到串TStrEmpty(S):判空操作。若S为空串,则返回TRUE,否则返回FALSEStrCompare(S, T):比较操作。若S>T,则返回值 > 0;若S=T,则返回值 = 0;若S<T,则返回值 < 0StrLength(S):求串长。返回串S的元素个数SubString(&Sub, S, pos, len):求子串。用Sub返回串S的第pos个字符起长度为len的子串Concat(&T, S1, S2):串联接。用T返回由S1和S2联接而成的新串Index(S, T):定位操作。若主串S中存在与串T值相同的子串,则返回它在主串S中第一次出现的位置;否则函数值为0ClearString(&S):清空操作。将S清为空串DestroyString(&S):销毁串。将串S销毁
在上述定义的操作中,串赋值StrAssign</
本文介绍了C语言中内存的五个区域,重点讲解了串(字符串)的概念、存储结构(定长顺序存储、堆分配存储、块链存储)以及串的基本操作。此外,还详细阐述了串的模式匹配算法,包括暴力匹配算法和KMP算法,特别是KMP算法的工作原理、部分匹配值、数组的计算以及优化,旨在提高字符串匹配的效率。
最低0.47元/天 解锁文章
&spm=1001.2101.3001.5002&articleId=130352411&d=1&t=3&u=fbb780168ffd41e3ad2a2a4b841f12ea)
112

被折叠的 条评论
为什么被折叠?



