C语言模拟实现strcpy、strcat、strcmp

strcpy

        完成字符串拷贝。

        strcpy函数的返回类型是字符指针,参数有两个,都是字符指针。

        返回值是目标地址的起始地址。

        第一个参数是目标字符串的地址,第二个是以‘\0’结尾的源字符串的地址。参数不能传空指针(NULL),对空指针进行解引用,程序崩溃。

        strcpy的功能是拷贝字符串,包括'\0',将源字符串的内容拷贝的目标地址中,拷贝的过程不对越界进行检查,如果目标地址的数组大小比源字符串大小小,会破坏目标地址数组的结构,程序崩溃。需要目标空间足够大,找到'\0'并且拷贝到目标地址,这个函数才会结束。

char arr[5];
strcpy(arr, "abcdef");
// 字符数组5个字节,拷贝字符串需要7个字节,无法正常拷贝,越界崩溃

        目标空间必须可修改。

const char* p = "abcd";
strcpy(p, "abc");

        如果目标地址和源字符串地址指向的是同一块空间(不是相同地址的意思,比如目标字地址是字符数组"abc"的首地址,源字符串的地址是同一个字符数组其它元素的地址),这是标准未定义的行为。(不要使用strcpy完成同内存拷贝)

#include <stdio.h>
#include <assert.h>

// strcpy模拟实现
char* Strcpy(char* dest, const char* source)
{
    // 优化,不加也无所谓
    assert(dest != NULL && source != NULL);
    
    char* ret = dest;
    while (*dest++ = *source++)
    {
        ;
    }

    return ret;
}

int main()
{
    char arr[20];
    printf("%s", Strcpy(arr, "hello world"));
    return 0;
}

        assert里面条件不成立,编译器会直接报错。

        后置++,先使用后++,先对两个指针解引用,将源字符串的字符赋值给目标空间,目标地址和源字符串地址都+1,往后移一位,再判断该字符是不是'\0',如果不是'\0',继续重复,如果是'\0',条件不成立,因为'\0'的ASCII码值是0,结束循环。

        源字符串的地址指向的数据'h'拷贝到目标地址上,两个地址++往后走,重复,直到找到'\0'结束。 

        需要返回值,创建一个字符指针保存目标地址的起始地址。返回值的目的是为了实现链式访问(返回值作为下一个函数的参数);因为源字符串的内容不需要改变,形参写成const char* source,具有常属性,无法被修改,函数里无法通过*source修改字符串内容,在编译期间报语法错误,直接发现问题,防止将目标地址的数据拷贝到源字符串中。

strcat

        字符串追加到另一字符串后。

        strcat函数的返回类型是字符指针,参数有两个,都是字符指针。

        返回值是目标字符串的起始地址。

        第一个参数是目标地址的起始地址,第二个参数是源字符串的地址。这两个参数指向的字符串要有'\0'作为结束标志,参数不能传空指针(NULL),对空指针进行解引用,程序崩溃。目标空间必须可修改。

        strcat是功能是将源字符串追加到目标字符串后,先在目标字符串中找到'\0',在这个位置开始追加源字符串,拷贝到源字符串的'\0'结束,'\0'也要拷贝。strcat函数追加的过程不对越界进行检查,如果源字符串追加到目标字符串后大于数组大小,破坏目标地址数组的结构,程序崩溃。

        strcat也不能完成同内存字符串的追加,这是标准未定义的。

#include <stdio.h>
#include <assert.h>

// strcat模拟实现
char* Strcat(char* dest, char* src)
{
	assert(dest && src);
	char* ret = dest;
	// 找目标空间中的\0
	while (*dest)
	{
		dest++;
	}
	// 追加
	while (*dest++ = *src++)
	{
		;
	}
 
	return ret;
}

int main()
{
    char arr[20] = "hello";
    printf("%s", Strcat(arr, " world"));
    return 0;
}

        不需要改变源字符串,形参源字符串的地址加const修饰。 

strcmp

        比较字符串大小,不能直接使用>、<、==这些操作符,使用strcmp函数比较字符串。

        strcmp函数的返回类型是整型,参数有两个,都是字符指针。

        返回值是一个整型,如果字符串1大于字符串2,返回一个大于0的整型。如果两个字符串相等,返回0。如果字符串1小于字符串2,返回一个小于0的整型。

        两个字符指针,都是指向字符串的首元素的地址,需要是以'\0'结尾的字符串。参数不能传空指针(NULL),对空指针进行解引用,程序崩溃。

        strcmp比较两个字符串字符的ASCII码值,按顺序依次比较,到'\0'结束,如果中途遇到不一样直接返回值差值即可。

#include <stdio.h>
#include <assert.h>

// strcmp模拟实现
int Strcmp(const char* s1, const char* s2)
{
	assert(s1 && s2);
    // 比较两个字符
	while (*s1 == *s2)
	{
        // 如果字符是'\0',结束,两个字符串相同
		if (*s1 == '\0')
		{
			return 0;
		}
 
		s1++;
		s2++;
	}
    // 两个字符不相同,返回差值
	return *s1 - *s2;
}

int main()
{
    int ret = Strcmp("abc", "abbc");
    if (ret == 0)
        printf("两个字符串相同\n");
    else
        printf("两个字符串不相同\n");
    return 0;
}

        比较两个字符串,不需要修改,形参加const修饰。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值