小蚂蚁学习数据结构(16)——串的堆分配储存代码演示

    根据对书上伪代码的理解,编写了这么一段堆分配储存的程序,反正运行着没有什么问题,看看网上其余人的代码,具体细节上有所不一样外,思路上都差很少。保存一下,万一有高手过来,还能给指点一下。
函数

# include <stdio.h>
# include <stdlib.h>
# include <malloc.h>
# include <string.h>

//设置结构体变量
typedef struct string
{
	char * ch;
	int length;
}STRING,* PSTRING;

//函数前置声明
//初始化结构体
void InitString( PSTRING );
//串的赋值操做
void StrAssign( PSTRING, char * );
//串的长度
int StrLength( PSTRING );
//比较两个串的大小
int StrCompare( PSTRING, PSTRING );
//清空一个串
bool ClearString( PSTRING );
//拼接两个串,组成一个新串
bool Concat( PSTRING, PSTRING, PSTRING );
//在某个位置上截取某个长度
bool SubString( PSTRING, PSTRING, int, int );

/*
	初始化
*/
void InitString(PSTRING str)
{
	str -> ch 		= NULL;
	str -> length 	= 0;
}

/*
	串的赋值操做
	@param	PSTRING	str	将目标串赋值到该串
	@param	char *	s   被复制的串
	return	void	
*/
void StrAssign(PSTRING str,char * s)
{
	int i, j;
	
	//判断指针是否为空,若是不为空,将内存再用释放
	if( str -> ch )
	{
		free( str -> ch );
		str -> ch = NULL;
	}
	
	//判断传入字符串的长度
	for( i = 0; s[i] != '\0'; i++ );
	
	//在内存中动态分配出空间
	str -> ch = ( char * )malloc( i * sizeof( char ) );
	if( NULL == str -> ch )
	{
		printf("动态内存分配失败\n");
		return;
	}
	
	//逐个将值复制过来
	for( j = 0; j < i; ++j )
	{
		str -> ch[j] = s[j];
	}
	
	//给长度赋值
	str -> length = i;
	
	return; //结束
	
}

//返回串的长度
int StrLength( PSTRING str )
{
	return str -> length;
}

/*
	比较两个串的大小
	@param	PSTRING	str1 其中一个串
	@param	PSTRING	str2 其中一个串
	return	int
	思路:
		1,逐个比较元素的ascii码,返回正数或者负数
		2,若是比较完毕,在比较两个串的长度,返回0 或者 非0
*/
int StrCompare( PSTRING str1, PSTRING str2 )
{
	int i;
	
	for( i = 0; i < str1->length && i < str2->length; ++i )
	{
		if( str1->ch[i] != str2->ch[i] )
		{
			return str1->ch[i] - str2->ch[i];
		}
	}
	
	return str1->length - str2->length;
}

//清空一个串
bool ClearString( PSTRING str )
{
	free( str -> ch );
	str -> ch = NULL;
	str -> length = 0;
	
	return true;
}

//拼接两个串,组成一个新串
bool Concat( PSTRING str3, PSTRING str1, PSTRING str2 )
{
	int i, total;
	
	//释放上一次使用的空间
	if( str3 -> ch )
	{
		/*
			free( str3 -> ch );
			这里须要注意一下,以前这里老报错,检查以后才知道,
			忘了为str3初始化。不初始化的结果就是:str3 -> ch中
			保存的是一个垃圾值,而后到了下行要释放空间的时候,由于
			保存的是一个垃圾值,或者是一个野指针,因此,程序出错,
			初始化一下str3,就行了。
			PS:对初始化的认知更深入了。
		*/
		free( str3 -> ch );
		str3 -> ch = NULL;
		str3 -> length = 0;
	}
	
	//若是要拼接的两个串是空串,返回false
	if( str1 -> length == 0  && str2 -> length == 0 )
	{
		return false;
	}
	
	//计算出两个串的总长度
	total = str1->length + str2->length;
	//为str3动态分配内存空间
	
	str3 -> ch = ( char * )malloc( total * sizeof( char ) );
	if( NULL == str3 -> ch )
	{
		printf( "动态内存分配失败\n" );
		return false;
	}
		
	//将str1的内容复制到str3	
	for( i = 0; i < str1 -> length; ++i )
	{
		str3 -> ch[i] = str1 -> ch[i];
	}
	
	//将str2的内容复制到str3
	for( i = 0; i < str2 -> length; ++i )
	{
		str3 -> ch[str1->length + i] = str2 -> ch[i];
	}
	
	//把总长度赋值给str3
	str3 -> length = total;
	
	return true;
}

/*
	截取字符串
	@param	PSTRING	str	截取以后的新子串
	@param	PSTRING str1 将要截取的串
	@param	int		pos	 要截取的位置
	@param	int		len	 要截取的长度
	return boolean
*/
bool SubString( PSTRING str, PSTRING str1, int pos, int len )
{
	int i;
	/*
		首先对传入参数进行验证
		pos 的取值范围 1 <= pos <= str1->length
		len 的取值范围 0 <  len <= str1->length - pos + 1
	*/
	if( pos < 1 && pos > str1->length && len <= 0 && len > str1->length - pos + 1 )
	{
		return false;
	}
	
	//释放上一次使用的空间
	if( str -> ch )
	{
		free( str -> ch );
		str -> ch = NULL;
		str -> length = 0;
	}
	
	//分配空间
	str -> ch = ( char * )malloc( len * sizeof(char) );
	if( NULL == str -> ch )
	{
		printf("动态内存分配失败\n");
		return false;
	}
	
	//赋值操做
	for( i = 0; i < len; ++i )
	{
		str -> ch[i] = str1 -> ch[pos - 1 + i];
	}
	
	str -> length = len;
	
	return true;
}

//主函数
int main( void )
{
	int i;
	
	STRING str1, str2, str3, str4;
	InitString( &str1 );
	InitString( &str2 );
	InitString( &str3 );
	InitString( &str4 );
	
	printf( "将“abcde”赋值给str1\n" );
	printf( "将“fghijklmn”赋值给str2\n" );
	StrAssign( &str1, "abcde" );
	StrAssign( &str2, "fghijklmn" );
	
	i = StrCompare( &str1, &str2 );
	
	printf( "比较str1和str2的结果:%d\n", i );
	
	printf( "拼接str1和str2,而且赋值给str3:\n" );
	Concat( &str3, &str1, &str2 );
	for( i = 0; i < str3.length; ++i )
	{
		printf( "%c ", str3.ch[i] );
	}
	
	printf( "\n" );
	
	printf( "从str3的第5个元素截取5个值,赋予str4:\n" );
	SubString( &str4, &str3, 5, 5 );
	for( i = 0; i < str4.length; ++i )
	{
		printf( "%c ", str4.ch[i] );
	}
	
	printf( "\n" );
	
	printf( "清空str3串:\n" );
	if( ClearString( &str3 ) )
	{
		printf( "str3已经被清空\n" );
	}

	
	return 0;
}
/*
	在VC++6.0中输出的结果是:
	===========================
	将“abcde”复制给str1
	将“fghijklmn”复制给str2
	比较str1和str2的结果:-5
	拼接str1和str2,而且赋值给str3:
	a b c d e f g h i j k l m n
	从str3的第5个元素截取5个值,赋予str4:
	e f g h i
	清空str3串:
	str3已经被清空
	===========================
*/

    就这么着吧,有时间再把块链的代码实现一下,书上也真够简单的,伪代码也给省略了……spa


    学PHP的小蚂蚁 博客 http://my.oschina.net/woshixiaomayi/blog.net