• c语言分层理解(c语言字符串+内存库函数)


    1. 求字符串长度

    1.1 strlen库函数

    size_t strlen ( const char * str );

    1.1.1 注意要点

    1. 字符串已经 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包
      含 ‘\0’ )
    2. 参数指向的字符串必须要以 ‘\0’ 结束。
    3. 注意函数的返回值为size_t,是无符号的

    1.1.2 strlen模拟实现

    #include 
    #include 
    int my_strlen(const char* str)
    {
    	assert(str);
    	const char* start = str;
    	const char* end = str;
    	while (*end != '\0')
    	{
    		end++;
    	}
    	return end - start;
    }
    int main()
    {
    	char arr[] = "abcdef";
    	int ret = my_strlen(arr);
    	printf("%d\n", ret);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    2. 长度不受限制的字符串函数

    2.1 strcpy库函数

    char* strcpy(char * destination, const char * source );

    2.1.1 主要要点

    1. 源头字符串必须以’\0’结束
    2. 会把源头字符串中的’\0’拷贝到目标空间中
    3. 目标空间必须足够大,以确保存放源字符串
    4. 目标空间必须可变

    2.1.2 strcpy模拟实现

    #include 
    #include 
    char* my_strcpy(char* destenation, const char* source)
    {
    	assert(destenation && source);
    	char* ret = destenation;
    	while (*destenation++ = *source++)
    	{
    		;
    	}
    	return ret;
    
    }
    int main()
    {
    	char arr1[] = "xxxxxxxxxxx";
    	char arr2[] = "hello";
    	printf("%s\n", my_strcpy(arr1, arr2));
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    2.2 strcat库函数

    ##3 2.2.1 注意要点

    1. 源头字符串必须以’\0’结束
    2. 目标空间必须足够大,能容纳源头字符串的内容
    3. 目标空间必须可修改
    4. strcat库函数自己给自己追加造成死循环

    2.2.2 strcat模拟实现

    #include 
    #include 
    char* my_strcat(char* destenation, const char* source)
    {
    	char* record = destenation;
    	while (*record != '\0')
    	{
    		record++;
    	}
    	while (*record++ = *source++)
    	{
    		;
    	}
    	return destenation;
    }
    int main()
    {
    	char arr1[20] = "math ";
    	char arr2[] = "easy";
    	printf("%s\n",my_strcat(arr1, arr2));
    	return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    2.3 strcmp库函数

    int strcmp ( const char * str1, const char * str2 );

    2.3.1 注意要点

    1. 第一个字符串大于第二个字符串返回大于0的数字;第一个字符串等于第二个字符串返回0;第一个字符串小于第二个字符串返回小于0的数字
    2. 从左到右一个一个字符依次比较,比较的是字符的ASCII值

    2.3.2 strcmp模拟实现

    #include 
    #include 
    int my_strcmp(const char* s1, const char* s2)
    {
    	assert(s1 && s2);
    	while (*s1 == *s2)
    	{
    		if (*s1 == '\0')
    		{
    			return 0;
    		}
    		s1++;
    		s2++;
    	}
    	return *s1 - *s2;
    }
    
    int main()
    {
    	char arr1[] = "abcdef";
    	char arr2[] = "abd";
    	int ret = my_strcmp(arr1, arr2);
    	if (ret > 0)
    	{
    		printf("arr1>arr2");
    	}
    	else if (ret < 0)
    	{
    		printf("arr1);
    	}
    	else
    	{
    		printf("arr1=arr2");
    	}
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    3. 长度受限制的字符串函数

    3.1 strncpy库函数

    char * strncpy ( char * destination, const char * source, size_t num );

    3.1.1 注意要点

    1. 拷贝num个字符从源头字符串到目标空间
    2. 如果源头字符串的长度小于num,则拷贝完源头字符串之后,在目标的后边追加’\0’,知道num个

    3.1.2 strncpy模拟实现

    #include 
    char* my_strncpy(char* dest,const char* source,size_t count)
    {
        char* start = dest;
        while (count && (*dest++ = *source++) != '\0')
        {
            count--;
        }
    
        if (count)
        {
            while (--count)
            {
                *dest++ = '\0';
            }
        }
        return start;
    }
    
    int main()
    {
    	char arr1[] = "xxxxxxxxxxx";
    	char arr2[] = "hello";
    	printf("%s\n", my_strncpy(arr1, arr2,3));
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    3.2 strncat库函数

    char * strncat ( char * destination, const char * source, size_t num );

    3.2.1 注意要点

    1. 可以实现自己给自己追加的情况,通常追加后后面加上一个’\0’来结束
    2. 目标空间必须足够大
    3. 目标空间必须可修改

    3.2.2 strncat模拟实现

    #include 
    char* my_strncat(char* front,const char* back,size_t count)
    {
        char* start = front;
        while (*front++)
        {
            ;
        }
        front--;
        while (count--)
        {
            if ((*front++ = *back++) == 0)
            {
                return start;
            }
        }
        *front = '\0';
        return start;
    }
    int main()
    {
    	char arr1[20] = "math ";
    	char arr2[] = "easy";
    	printf("%s\n",my_strncat(arr1, arr2,3));
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    3.3 strncmp库函数

    int strncmp ( const char * str1, const char * str2, size_t num );

    3.3.1 注意要点

    和strcmp需要注意的地方一样

    3.3.2 strncmp模拟实现

    #include 
    #include 
    int my_strncmp(const char* str1, const char* str2, size_t num)
    {
        assert(str1 && str2);
    
        if (!num)return 0;
    
        while (--num && *str1 && (*str1 == *str2))
        {
            str1++;
            str2++;
        }
    
        return *str1 - *str2;
    }
    int main()
    {
    	char arr1[] = "adegcongdwg";
    	char arr2[] = "adegavd";
    	int ret = my_strncmp(arr1, arr2,5);
    	if (ret > 0)
    	{
    		printf("arr1>arr2");
    	}
    	else if (ret < 0)
    	{
    		printf("arr1);
    	}
    	else
    	{
    		printf("arr1=arr2");
    	}
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    4. 字符串查找函数

    4.1 strstr库函数

    char * strstr ( const char *str1, const char * str2);

    4.1.1 注意要点

    在一个字符串中另外一个字符川是否存在。如果存在,则返回子串第一次出现的位置;如果不存在,则返回NULL

    4.1.2 strstr模拟实现

    #include 
    char* my_strstr(const char* s1, const char* s2)
    {
    	const char* str1 = s1;
    	const char* str2 = s2;
    	const char* p = s1;
    	while (*p)
    	{
    		str1 = p;
    		str2 = s2;
    		while (*str1 == *str2)
    		{
    			str1++;
    			str2++;
    		}
    		if (*str2 == '\0')
    		{
    			return (char*)p;
    		}
    		p++;
    	}
    	return NULL;
    }
    
    int main()
    {
    	char arr1[] = "adefghadefgh";
    	char arr2[] = "efg";
    	char* ret = my_strstr(arr1, arr2);
    	if (ret == NULL)
    	{
    		printf("不存在\n");
    	}
    	else
    	{
    		printf("%s\n", ret);
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    4.2 strtok库函数

    char * strtok ( char * str, const char * delimiters );

    4.2.1 注意要点

    1.delimiters参数上一个字符串,定义用作分隔符的字符集合
    2.第一个参数指定一个字符串,它包含了0个或者多个由delimiters字符串中一个或者多个分隔符分割的标记。
    3.strtok函数找到str中的下一个标记,并将其用\0结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
    4.strtok函数的第一个参数不为NULL,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
    5.strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
    6.如果字符串中不存在更多的标记,则返回 NULL 指针。

    4.2.2 strtok库函数的使用场景

    #include 
    #include 
    
    int main()
    {
    	char arr[] = "code-eye@qq.com";
    	char buff[200] = { 0 };
    	//strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改
    	strcpy(buff, arr);
    	const char* p = "-@.";
    
    	char* str = NULL;
    	for (str = strtok(buff, p); str != NULL; str = strtok(NULL, p))
    	{
    		printf("%s\n",str);
    	}
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    5. 错误信息报告

    5.1 strerror库函数

    char* strerror(int errnum);

    strerror库函数作用:返回错误码,所对应的错误信息。

    6. 字符操作函数

    1. iscntrl库函数:判断是否为任何控制字符
    2. isspace库函数:判断是否为空白字符:‘空格’,换页‘\f’,换行‘\n’,回车‘\r’,制表符‘\t’
    3. isdigit库函数;判断是否为十进制数字
    4. isxdigit库函数:判断是否为十六进制数字包括十进制数字
    5. islower库函数:判断是否为小写字母
    6. isupper库函数:判断是否为大写字母
    7. isalpha库函数:判断是否为字母az或者AZ
    8. isalnum库函数:判断是否为字母或者数字
    9. ispunct库函数:判断是否为标点符号,任何不属于数字或者字母的图形字符
    10. isgraph库函数;判断是否为任何图形字符
    11. isprint库函数:判断是否为任何可打印字符

    7.内存操作函数

    7.1 memcpy库函数

    void * memcpy ( void * destination, const void * source, size_t num );

    7.1.1 注意要点

    1. 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置
    2. 这个函数在遇到 ‘\0’ 的时候并不会停下来。
    3. 如果source和destination有任何的重叠,复制的结果都是未定义的

    7.1.2 模拟实现

    #include 
    #inlcude <assert.h>
    void* my_memcpy(void* dest, void* src, size_t num)
    {
    	void* ret = dest;
    	assert(dest && src);
    	while(num--)
    	{
    		*(char*)dest = *(char*)src;
    		dest = (char*)dest + 1;
    		src = (char*)src + 1;
    	}
    	return ret;
    }
    
    int main()
    {
    	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
    	int arr2[10] = { 0 };
    	my_memcpy(arr2, arr1, 20);
    
    	int i = 0;
    	for (i = 0; i < (20 / sizeof(int)); i++)
    	{
    		printf("%d ",arr2[i]);
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    7.2 memmove库函数

    void * memmove ( void * destination, const void * source, size_t num );

    7.2.1 注意要点

    1. 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的
    2. 如果源空间和目标空间出现重叠,就得使用memmove函数处理

    7.2.2 模拟实现

    #include 
    void* my_memmove(void* dest, void* src, size_t num)
    {
    	void* ret = dest;
    	assert(dest && src);
    	//从前往后覆盖
    	if (dest < src)
    	{
    		while(num--)
    		{
    			*(char*)dest = *(char*)src;
    			dest = (char*)dest + 1;
    			src = (char*)src + 1;
    		}
    	}
    	//从后往前覆盖
    	else 
    	{
    		while (num--)
    		{
    			*((char*)dest + num) = *((char*)src + num);
    		}
    	}
    	return ret;
    }
    
    print(int arr[],int sz)
    {
    	int i = 0;
    	for (i = 0; i < sz; i++)
    	{
    		printf("%d ", arr[i]);
    	}
    }
    int main()
    {
    	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
    	my_memmove(arr+3,arr,16);
    	int sz = sizeof(arr) / sizeof(arr[0]);
    	print(arr,sz);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    7.3 memset库函数

    void * memset ( void * ptr, int value, size_t num );

    7.3.1 注意要点

    1. memset是用来把ptr指针指向的内容后的num个字节全部改为value值

    7.3.2 使用场景

    7.4 memcmp库函数

    int memcmp ( const void * ptr1,const void * ptr2,size_t num );

    7.4.1 注意要点

    这里和strncpy很相似,但是memcpy针对各种类型,strncpy只能比较char类型的。
    这里的num单位是字节,所以比较的是从ptr1和ptr2指针开始的num个字节
    ptr1的字符ASCII码值大于ptr2就返回大于0的值,等于返回0,小于则返回小于0的值

  • 相关阅读:
    【专栏】核心篇07| Redis “jio”美的集群模式
    Redis 哨兵集群工作原理
    Oracle常用语句语法
    ORACLE逻辑存储结构
    Java项目:JSP网上在线酒类商城系统网站
    C++面向对象 _ 成绩单系统
    3561-24-8|荧光染料6-fam(Br4)|可作为成像剂
    用Python制作我的核酸检测日历
    Java计算机毕业设计电影院购票系统源码+系统+数据库+lw文档
    Kohana框架的安装及部署
  • 原文地址:https://blog.csdn.net/m0_46343224/article/details/126856147