六、数据结构-线性-串

串与线性表相似,但它的组成是字符,而且操作不是以单个数据元素操作,而是以子串进行操作。

6.1串的结构定义

顺序结构:

typedef struct{
   char *ch;      
   int  length;   //定义和顺序表相同
}HString;

串的销毁:

int Destroy_SString(SString *S){
    if(!S){return -1;}
    free(S);
    return 0;
} 

链式结构:
串的的链式存储特殊性在于,每个结点可以是多个字符,结点(块)大小直接影响存储效率。


串的链式存储
#define CHUNKSIZE 80       //可由用户定义的块大小
typedef struct Chunk{
   char  ch[CHUNKSIZE];
   struct Chunk *next;
}Chunk;

typedef struct{
   Chunk *head,*tail;      //串的头指针和尾指针
   int len;             //串的当前长度
}LString;

易错点:

  • 以下代码在UpperCase和main函数里都用sizeof()计算数组的项目。一般sizeof如用于数组,只能测出静态数组的大小,无法检测动态分配的或外部数组大小。main中的str是一个静态定义的数组,因此其大小为6,因为还有’\0′,UpperCase内的str实际只是一个指向字符串的指针,没有任何额外的与数组相关的信息,因此sizeof作用于上只将其当指针看,一个指针为4个字节,因此返回4。
void UpperCase(char *str){ // 将 str 中的小写字母转换成大写字母
    for(int i=0;i<sizeof(str)/sizeof(str[0]);i++){
        if('a'<=str[i]&&str[i]<='z'){
            str[i]=str[i]-('a'-'A');
        }
    }
}

int main(){
    char str[] ="aBcDe";
    cout << "str字符长度为:"<< sizeof(str)/sizeof(str[0]) << endl;
    UpperCase(str);
    cout << str << endl;
}

注:以上代码在CPP中执行是成功的,以后如果使用sizeof()计算字符串大小出错可以换一种写法:

s=str;
for(len=0;*s;len++,s++);//循环在s指向内容(*s)为0(到达字符串尾)时跳出

另外,数组在传参时,形参可以像上例写为char *str,也可以写为char str[]。实参可以写为UpperCase(str),即用头指针指代整个数组。

  • 计算机的栈区、堆区和全局区(静态区):
    1、栈区—由编译器自动分配释放,存放函数的参数值,局部变量的值等。如以下在free这一步会内存错误,因为这里的a数组时存在栈区的,不能手动释放。
int main(){
    int a[5];
    for(int i=0;i<5;i++){
        a[i]=0;}
    free(a[4]);
    printf("%d",sizeof(a));
}

2、堆区—由程序员分配释放,即动态申请的区域,若程序员不释放,程序结束时可能由系统回收。C或C++的Malloc或new是用的堆空间,需要手动用Free或delete释放。
3、全局区(静态区)(static)存放全局变量和静态变量,在程序编译的时候就已经分配好。
静态变量:指在程序执行前系统就为之静态分配,也即在运行时中不再改变分配情况的一类变量。
全局变量:程序在所有函数外面定义的变量,main函数里的是局部变量。

计算机内存

  • 字符串的申明。C语言字符串申明可以用char *x或char x[],两者本质上是一样的,都是以字符数组形式存储。两者区别在于,用char *定义的x,会自动在末尾加上'\0',但用char []定义x,可能末尾没有'\0'。而C语言在输出x时,会一直到'\0'为止,所以char []定义的可能输出时会有乱码出现。
char *x="abc";
char x[]="abc";

当然我们可以在字符数组初始化时人工加上\0(位数多1)。用char *x申明时如果没有赋值,那么只是一个野指针,需要手动申请空间,如以下代码是错误的:

int *a;
for(int i=0;i<5;i++){
        a[i]=0;
}

改成:

int *a=new int[5];;
for(int i=0;i<5;i++){
        a[i]=0;
}
char str[]={'I',' ','a','m',' ','h','a','p','p','y','\0'};

说明:
(1)上述这种字符数组的整体赋值的形式,只能在字符串初始化时使用,程序执行过程中只能一一赋值,如下面的赋值方式是错误的:

char str[];
str="I am happy";

(2)定义为指针所指向的字符串是常量字符串,只能读取不能写入。如以下程序执行会出错。

int main() {
    char *str = "media";
    char *tmp = "aaa";
    printf("str: %s\n",str);
    strcat(str,tmp);
    printf("str: %s\n",str);
    return 0;
}

*上面把char *str = "media"改成char str[20]= "media"就对了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容