C++入门——进一步认识字符串

进一步认识字符串

实现memmove

用C语言实现函数void * memmove(void *dst, const void *src, size_t n)。memmove函数的功能是复制src所指的内存内容前n个字节到dest所指的地址上

这个函数的参数与返回值的类型都是void*,在实现的时候需要把void*转换成可操作的数据类型来处理

主要特别考虑的是内存重叠问题,处理内存重叠的主要思路如下:

  1. 当源内存的首地址大于目标内存的首地址时,从源内存的首地址开始复制
  2. 当源内存的首地址小于目标内存的首地址时,从源内存的首地址加待复制字节长度的地址开始逆序复制

实现代码如下:

void * mymemmove(void *dst, const void *src, size_t num)
{
	if (dst == NULL || src == NULL)
	{
		return NULL;
	}
	char *pdst = (char *)(dst);
	const char *psrc = (char *)(src);
	//内存重叠的情况
	if (pdst > psrc && pdst < psrc + num)
	{
		for (size_t i = num - 1; i != -1; i--)
		{
			pdst[i] = psrc[i];
		}
	}
	else
	{
		for (size_t i = 0; i < num; i++)
		{
			pdst[i] = psrc[i];
		}
	}
	return dst;
}

总结5个需要注意的地方:

  1. 对异常进行判断,判断src与dst是否为空指针
  2. src指针要用const修饰,以避免无意中修改src的内容
  3. 在实现的时候,需要把void*转换成能进行操作的数据类型,如char*
  4. 函数需要返回值,这样这样支持链式表达
  5. 需要特别考虑指针重叠的情况

实现memcpy函数

memcpy函数的功能是从源src所指的内存地址的起始位置开始复制n个字节到目标dest所指的内存的起始位置中。函数原型为

void *memcpy(void *dest, const void *src, size_t n)

memcpy与memmove的功能类似。只不过memmove函数在有内存重叠的情况下也能保证数据复制的正确性;而memcpy在内存不重叠的情况下能保证数据复制的正确性,对于内存重叠的情况,不能保证数据复制的正确性,具体情况根据不同类库的实现有关

实现strcpy()函数

strcpy的原型为extern char *strcpy(char *dest, const char *src);,包含在头文件string.h中,它返回指向dest的指针,其功能是把src所指由'\0'结束的字符串复制到dest所指的数组中。值得注意的是,dest必须有足够的空间容纳src的字符串,src字符串尾的字符串结束标识符'\0'也会被复制过去

另外还需要考虑内存重叠问题,于是可以直接用memmove函数实现

char * strcpy(char *dest, char *src)
{
	assert(dest != NULL && src != NULL);
	char *returnValue = dest;
	memmove(dest, src, strlen(src) + 1);
	return returnValue;
}

size_t strlen(const char* str)
{
	assert(str != NULL);
	size_t length = 0;
	while ((*str++)!='\0')
		length++;
	return length;
}

strstr函数的作用是什么

函数原型:extern char *strstr(char *str1, char *str2);
功能:strstr(str1, str2)函数用于判断字符串str2是否是str1的子串。如果是,则该函数返回str2在str1中首次出现的地址;否则,返回NULL

实现atoi(字符串转换成整型数)

int myatoi(char *str)
{
	if (str == NULL)
	{
		printf("Invalid Input");
		return -1;
	}
	while (*str == ' ') //去掉字符串开始的空格
	{
		str++;
	}
	int nSign = (*str == '-') ? -1 : 1; //确定符号位
	if (*str == '+' || *str =='-')
	{
		str++;
	}
	int nResult = 0;
	while (*str >= '0' && *str <= '9')
	{
		nResult = nResult * 10 + (*str - '0');
		str++;
	}
	while (*str == ' ') //去掉字符串结束的空格
	{
		str++;
	}
	if (*str != '\0')
	{
		printf("Invalid Input");
		return -1;
	}
	return nResult * nSign;
}

实现itoa(整型数转换成字符串)

由于int可以表示数的范围为-2147483648~2147483647,因此吧int转换为字符串后,字符串最大的长度为11,因此最多需要的空间为12

char *myitoa(int num, char str, int radix)
{
char
ptr = str;
int temp;
int sign = num, i == 0, j = 0;
if (sign < 0)
{
num = -num;
}

	while (num)
	{
		*ptr++ = num % radix + '0';
		num /= radix;
		if (num < radix)
		{
			*ptr++ = num + '0';
			break;
		}
	}
	
	if (sign < 0)
	{
		*ptr++ = '-';
	}
	*ptr = '\0';
	
	j = ptr - str - 1;
	for (i = 0; i < j; i++)
	{
		int temp = str[i];
		str[i] = str[j];
		str[j--] = temp;
	}
	return str;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值