數(shù)據(jù)結(jié)構(gòu)中提到的串,即字符串,由 n 個(gè)字符組成的一個(gè)整體( n >= 0 )。這 n 個(gè)字符可以由字母、數(shù)字或者其他字符組成。
特殊的串
空串:含有零個(gè)字符的串。例如:S = “”(雙引號(hào)中沒有任何東西),一般直接用 ? 表示。
空格串:只包含空格的串。注意和空串區(qū)分開,空格串中是有內(nèi)容的,只不過包含的是空格,且空格串中可以包含多個(gè)空格。例如,a = ” ”(包含3個(gè)空格)。
子串與主串:串中任意個(gè)連續(xù)字符組成的字符串叫做該串的子串,包含子串的串稱為主串。
兩個(gè)串相等的標(biāo)準(zhǔn):如果兩個(gè)串的串值完全相同,那么這兩個(gè)串相等。
串的三種存儲(chǔ)結(jié)構(gòu)
- 定長(zhǎng)順序存儲(chǔ)
- 堆分配存儲(chǔ)
- 塊鏈存儲(chǔ)
定長(zhǎng)順序存儲(chǔ)
采用固定長(zhǎng)度的數(shù)組(即靜態(tài)數(shù)組)存儲(chǔ)串。
例如:char a[7] = "abcdfg";
此方式存儲(chǔ)串時(shí),需要預(yù)估串的長(zhǎng)度提前申請(qǐng)足夠的存儲(chǔ)空間。目標(biāo)串如果超過了數(shù)組申請(qǐng)的長(zhǎng)度,超出部分會(huì)被自動(dòng)舍棄(稱為“截?cái)唷保?/p>
堆分配存儲(chǔ)
采用動(dòng)態(tài)數(shù)組存儲(chǔ)串。
- 在C語言中,存在著一個(gè)被稱之為“堆”的自由存儲(chǔ)區(qū),用 malloc 函數(shù)和 free 函數(shù)管理,malloc 函數(shù)負(fù)責(zé)申請(qǐng)空間,free 函數(shù)負(fù)責(zé)釋放空間。
例如:char * a = (char)malloc(5sizeof(char));//創(chuàng)建 a 數(shù)組,動(dòng)態(tài)申請(qǐng)5個(gè) char 類型數(shù)據(jù)的存儲(chǔ)空間
使用堆分配存儲(chǔ)的優(yōu)勢(shì)在于:當(dāng)發(fā)現(xiàn)申請(qǐng)的空間不夠用時(shí),可以通過 realloc() 函數(shù)重新申請(qǐng)更大的存儲(chǔ)空間。
例如:a = (char)realloc(a, 10sizeof(char));//前一個(gè)參數(shù)指申請(qǐng)空間的對(duì)象;第二個(gè)參數(shù),重新申請(qǐng)空間的大小
使用 malloc 函數(shù)申請(qǐng)的存儲(chǔ)空間,不會(huì)自動(dòng)釋放,需要程序員調(diào)用 free() 函數(shù)手動(dòng)釋放。如果不手動(dòng)釋放,當(dāng)程序執(zhí)行徹底結(jié)束,由操作系統(tǒng)進(jìn)行回收。
例如:free(a);//釋放動(dòng)態(tài)數(shù)組a申請(qǐng)的空間
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char * a1=NULL;
char * a2=NULL;
a1=(char*)malloc(3*sizeof(char));
strcpy(a1, "abc");//將字符串“abc”復(fù)制給a1
a2=(char*)malloc(3*sizeof(char));
strcpy(a2, "defg");
//長(zhǎng)度 strlen
int lengthA1=strlen(a1);
int lengthA2=strlen(a2);
if (lengthA1<lengthA1+lengthA2) {
a1=(char*)realloc(a1, (lengthA1+lengthA2)*sizeof(char));
}
for (int i=lengthA1; i<lengthA1+lengthA2; i++) {
a1[i]=a2[i-lengthA1];
}
printf("%s",a1);
free(a1);
free(a2);
return 0;
}
注:在程序中,我們給 a1 和 a2 賦值的時(shí)候,使用了 strcpy 復(fù)制函數(shù)。在這里不能直接用:a1 = ”abc”這種方式,如果你這樣做,程序編譯會(huì)出錯(cuò),告訴你,沒有 malloc 的空間不能 free 。
原因是: strcpy 函數(shù)是將字符串復(fù)制到申請(qǐng)的存儲(chǔ)空間中,而直接賦值是字符串存儲(chǔ)在別的內(nèi)存空間(本身是一個(gè)常量,放在常量區(qū))中,更改了指針 a1 和 a2 的指向,也就是說,之前動(dòng)態(tài)申請(qǐng)的存儲(chǔ)空間雖然申請(qǐng)了,結(jié)果還沒用呢就丟了。
塊鏈存儲(chǔ)
塊鏈存儲(chǔ),其實(shí)就是借用鏈表的存儲(chǔ)結(jié)構(gòu)來存儲(chǔ)串。一般情況下使用單鏈表就足夠了,而且不需要增設(shè)頭結(jié)點(diǎn)。
注
在平時(shí)編寫程序,經(jīng)常會(huì)用到例如:char *a = ”abcd”;這種方式表示字符串,和上面三種存儲(chǔ)方式最主要的區(qū)別是:這種方式用于表示常量字符串,只能使用,不能對(duì)字符串內(nèi)容做修改(否則程序運(yùn)行出錯(cuò));而以上三種方式都可以對(duì)字符串進(jìn)行刪改的操作。
三種存儲(chǔ)表示方式中,最常用的是堆分配存儲(chǔ),因?yàn)樗诙ㄩL(zhǎng)存儲(chǔ)的基礎(chǔ)上通過使用動(dòng)態(tài)數(shù)組,避免了在操作串時(shí)可能因?yàn)樯暾?qǐng)存儲(chǔ)空間的不足而丟失字符數(shù)據(jù);和塊鏈存儲(chǔ)方式相比,結(jié)構(gòu)相對(duì)簡(jiǎn)單,更容易操作。