字符串的堆分配

    201672614:47:30
    为什么需要字符串的堆分配?
    因为字符串的顺序存贮结构中,对字符串的操作,在字符串中插入一个子字符串,连接两个字符串以及串的替换操作,度可能会
    出现空间的不足,而必须要舍弃部分数据的情况,而数组的空间如果分配的过大,又会浪费内存空间,为了避免顺序存贮结构的
    局限性,可以使用动态内存分配的方式来表示串,并实现串的基本操作
    什么是堆分配?
    通常在函数中定义的变量,都属于局部变量,他们属于静态内存分配,是由程序所在的软件,请求操作系统分配一块空闲的存贮空间
    当函数运行完毕后,函数会弹栈,静态分配的存贮空间就会被操作系统释放,程序员无法手动编写代码来分配和释放这些内存空间,
    而动态内存分配则不同,动态内存分配可以由程序员手动分配内存空间,是使用堆排序的方式进行分配的,函数运行完毕后,函数以及
    它的所有局部变量都会出栈,但是堆分配产生的内存空间则任然存在,这些内存空间必须由程序员手动进行释放.空间可以动态的
    缩小与扩充.

    realloc函数:指针名 = (数据类型 * )realloc(需要改变内存大小的指针名,新的大小);动态内存调整
    使用时必须包含头文件#include<stdlib.h>;
    功能:先判断当前指针是否有足够的连续空间,如果有,扩大mem_address指向的地址,并且将mem_address返回.
        如果内存空间不够,先按照新指定的大小分配空间,将原来数据从头到尾拷贝到新分配的内存区域,(注意:原来指针是自动释放的)
        不需要使用free函数进行释放,同时返回新分配的内存区域的首地址,

    返回值:如果分配成功则返回被分配内存空间的首地址,如果分配失败,则返回NULL;
    注意:当内存不在使用时,应使用free()函数将内存块进行释放;
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#define MAXISIZE 100

//字符串的堆分配表示与实现
typedef struct string 
{
    char * str;//保存的是堆内存的串的起始地址的指针
    int length;//动态数组的长度
}HeapString;

//函数前置声明
void initString(HeapString * pH);//初始化字符串
void strAssign(HeapString * pH,char cstr[]);//给字符串赋值
void traverseStr(HeapString * pH);//将给定的字符串遍历输出
int  getLength(HeapString * pH);//获取字符串的长度
void strCopy(HeapString * S,HeapString * T);//字符串的复制
int  strInsert(HeapString * pH,HeapString * S);//字符串的插入

//字符串的插入,将S所指向的字符串插入到pH所指向的字符串pos中,成功返回1,失败返回0
int strInsert(HeapString * pH,int pos,HeapString * S)
{
    int i;
    //判断pos的值是否合法;
    if(pos<1||pos>pH->length+1)
    {
        printf("位置不合适!\n");
        return 0;
    }
    //从新分配内存空间
    pH->str = (char *)realloc(pH->str,(pH->length+S->length)*sizeof(char));
    if(!pH->str)
    {
        printf("动态内存分配失败!\n");
        exit(-1);
    }
    //将pos及其以后的所有元素向后移动:方法一
    /*for(i = pH->length+S->length-1;i>=pos-1+S->length;i--)
    {

        //pH->str[pH->length+S->length-1] = pH->str[pH->length-1];
        //pH->str[pH->length+S->length-1-1] = pH->str[pH->length-1-1];
        pH->str[i] = pH->str[i-S->length];
    }*/
    //将pos及其以后的所有元素向后移动:方法二
    for(i = pH->length-1;i>=pos-1;i--)
    {
        //pH->str[pH->length-1+S->length] = pH->str[pH->length-1];
        //pH->str[pH->length-1+S->length-1] = pH->str[pH->length-1-1];
        pH->str[i+S->length] = pH->str[i];
    }
    //将元素插入到pH所指向的字符串的"空"出来的部分:方法一
    for(i = 0;i<S->length;i++)
    {
        //pH->str[pos-1] = S->str[0];
        //pH->str[pos] = S->str[1];
        pH->str[i+pos-1]= S->str[i];
    }
    //将元素插入到pH所指向的字符串的"空"出来的部分:方法二
    /*for(i = pos-1;i<pos-1+S->length;i++)
    {

        //pH->str[pos-1] = S->str[0];
        //pH->str[pos] = S->str[1];
        pH->str[i] = S->str[i-(pos-1)];
    }*/
    pH->length = pH->length+ S->length;
    return 1;

}

//字符串的复制
void strCopy(HeapString * pH,HeapString * T)
{
    int i;
    int len = pH->length;
    T->str = (char * )malloc(len*sizeof(char));
    if(!T->str)
    {
        printf("动态内存分配失败!\n");
        exit(-1);
    }
    for( i = 0;i<pH->length;i++)
    {
        T->str[i] = pH->str[i];
    }
    T->length = pH->length;
    return;
}

//获取字符串的长度
int getLength(HeapString * pH)
{
    return  pH->length;
}

//字符串的遍历
void traverseStr(HeapString * pH)
{
    int i;
    for(i = 0;i<pH->length;i++)
    {
        printf("%c",pH->str[i]);
    }
    printf("\n");
    return ;
}

//给指定的字符串赋值
void strAssign(HeapString * pH,char cstr[])
{
    int i;
    int len;
    if(pH->str)
        free(pH->str);
    for( i = 0;cstr[i]!='\0';i++);
    len = i;
    if(!cstr)
    {
        pH->length = 0;
        pH->str = '\0';
    }
    else
    {
        pH->str = (char * )malloc(len*sizeof(char));
        if(!pH->str)
        {
            printf("动态内存分配失败!\n");
            exit(-1);
        }
        for(i = 0;i<len;i++)
        {
            pH->str[i] = cstr[i];
        }
        pH->length = len;
    }
    return ;
}

//初始化串
void initString(HeapString * pH)
{
    pH->str ='\0';
    pH->length = 0;
    return ;
}

//主函数
int main(void)
{
    HeapString pH;
    char cstr[MAXISIZE];
    initString(&pH);
    printf("请输入一个字符串:");
    gets(cstr);
    strAssign(&pH,cstr);
    traverseStr(&pH);
    return 1;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值