C语言学习笔记(13)字符串和内存函数1

Posted 小倪同学 -_-

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言学习笔记(13)字符串和内存函数1相关的知识,希望对你有一定的参考价值。

strlen

size_t strlen ( const char * str );

功能:
计算字符串长度

注意点:

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

观察下面代码,思考输出结果是什么?

#include<stdio.h>
#include<string.h>
int main()
{
	if (strlen("abc") - strlen("abcdef") > 0)
	{
		printf(">\\n");
	}
	else
	{
		printf("<=\\n");
	}
	return 0;
}

相信很多人都会认为输出为<=,那我们来运行一下:
在这里插入图片描述
很遗憾猜想是错误的,但这是为什么呢?

strlen函数的返回值是无符号的,因为strlen(str1) 与 strlen(str2)返回的结果都是无符号的,所以它们加减乘除的结果也是无符号整形,strlen(str1) - strlen(str2) 的结果是为 -4,补码是
11111111111111111111111111111100 转为十进制是一个很大的数,满足>0的条件。

下面来模拟实现strlen函数

#include<stdio.h>
#include<assert.h>
int my_strlen(const char* str)
{
	assert(str!=NULL);
	int count=0;
	while (*str != '\\0')
	{
		str++;
		count++;
	}
	return count;
}
int main()
{
	char arr[] = "abc";
	int len = my_strlen(arr);
	printf("%d\\n", len);
	return 0;
}

strcpy

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

功能:
将一个字符串的内容拷贝到另外一个字符串空间中

注意点:

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

应用实例:

int main()
{
	char str[] = "xxxxxxxxxxxxxxxxxxx";
	strcpy(str, "hello");
	printf("%s\\n", str);
	return 0;
}

在这里插入图片描述
模拟实现

#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* str1,const char* str2)
{
	assert(str1&&str2);
	char* start = str1;
	while (*str1++ = *str2++)
	{
		;
	}
	return start;
}
int main()
{
	char str[] = "xxxxxxxxxxxxxxxxxxx";
	my_strcpy(str, "hello");
	return 0;
}

strcat

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

功能:
将一个字符串的内容追加到另外一个字符串的末尾

注意点:

  1. 源字符串必须以’\\0’结束。
  2. 目标空间必须有足够的大,能容纳下源字符串的内容。
  3. 目标空间必须可修改。

int main()
{
	char str[20] = "hello ";
	strcat(str, "world");
	printf("%s\\n", str);
	return 0;
}

在这里插入图片描述
模拟实现strcat

#include<stdio.h>
#include<assert.h>
char* my_strcat(char* str, const char* str2)
{
	assert(str&&str2);
	char *start = str;
	while (*str)
	{
		str++;
	}
	while (*str++ = *str2++)
	{
		;
	}
	return start;
}
int main()
{
	char str[20] = "hello ";
	char str2[] = "world";
	printf("%s\\n",my_strcat(str, str2));
	return 0;
}

strcmp

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

功能:比较字符串大小,从头开始比较,如果它们彼此相等,则继续比较下一字符,直到字符不相等或到‘\\0’为止。

  1. 第一个字符串大于第二个字符串,则返回大于0的数字。
  2. 第一个字符串等于第二个字符串,则返回0。
  3. 第一个字符串小于第二个字符串,则返回小于0的数字。


在这里插入图片描述

模拟实现

#include<stdio.h>
#include<assert.h>
int my_strcmp(const char* p,const char* q)
{
	assert(p&&q);
	while (*p == *q)
	{
		if (*p == '\\0')
		{
			return 0;
		}
		p++;
		q++;
	}
	return *p - *q;
}
int main()
{
	char* p = "abcdef";
	char* q = "abcdef";
	int ret = my_strcmp(p, q);

	if (ret > 0)
	{
		printf("p > q\\n");
	}
	else if (ret < 0)
	{
		printf("p < q\\n");
	}
	else
	{
		printf("p == q\\n");
	}

	return 0;
}

上文都是长度不受限制的字符串函数,下面讲长度受限制的字符串函数

strncpy

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

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

int main()
{
	char arr1[20] = "abcdefghi";
	char arr2[] = "qwer";
	strncpy(arr1, arr2, 6);
	printf("%s\\n", arr1);
	return 0;
}

在这里插入图片描述
模拟实现:

#include<stdio.h>
#include<assert.h>
char* my_strncpy(char* str1, char* str2, size_t num)
{
	assert(str1&&str2);
	char* start = str1;
	while ((*str1++ = *str2++) && num)
	{
		num--;
	}
	while (--num)
	{
		*str1++ = '\\0';
	}
	return start;
}
int main()
{
	char arr1[20] = "abcdefghi";
	char arr2[] = "qwer";
	my_strncpy(arr1, arr2, 6);
	printf("%s\\n", arr1);
	return 0;
}

strncat

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

  1. 将源的前num个字符附加到目标,再加上一个终止的空字符。
  2. 如果source中的C字符串长度小于num,则只复制到终止空字符之前的内容。

int  main()
{
	char arr1[20] = "hello\\0#############";
	char arr2[] = "world";
	strncat(arr1, arr2, 8);
	printf("%s\\n", arr1);

	return 0;
}

在这里插入图片描述
模拟实现

#include<stdio.h>
#include<assert.h>
char* my_strncat(char* str1,const char* str2, int num)
{
	assert(str1&&str2);
	char* start = str1;
	while (*str1)
	{
		str1++;
	}
	while (num--)
	{
		if ((*str1++ = *str2++) == 0)
		{
			return start;
		}
	}
	*str1 = '\\0';
	return start;
}
int  main()
{
	char arr1[20] = "hello\\0#############";
	char arr2[] = "world";
	my_strncat(arr1, arr2, 8);
	printf("%s\\n", arr1);

	return 0;
}

strncmp

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

比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完。


在这里插入图片描述

strstr

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

返回指向str1中第一个出现的str2的指针,如果str2不是str1的一部分,则返回空指针。

int main()
{
	char arr1[] = "abbbcdef";
	char arr2[] = "bbc";

	//在arr1中查找是否包含arr2数组
	char* ret = strstr(arr1, arr2);
	if (ret == NULL)
	{
		printf("没找到\\n");
	}
	else
	{
		printf("找到了:%s\\n", ret);
	}
	return 0;
}

在这里插入图片描述

模拟实现

#include<stdio.h>
#include<assert.h>
char* my_strstr(const char* str1, const char* str2)
{
	assert(str1 && str2);
	const char* s1 = NULL;
	const char* s2 = NULL;
	const char* cp = str1;

	if (*str2 == '\\0')
	{
		return (char*)str1;
	}

	while (*cp)
	{
		s1 = cp;
		s2 = str2;
		while (*s1 && *s2 && (*s1 == *s2))
		{
			s1++;
			s2++;
		}
		if (*s2 == '\\0')
		{
			return (char*)cp;
		}
		cp++;
	}

	return NULL;
}
//
int main()
{
	char arr1[] = "abbbcdef";
	char arr2[] = "bbc";

	//在arr1中查找是否包含arr2数组
	char* ret = my_strstr(arr1, arr2);
	if (ret == NULL)
	{
		printf("没找到\\n");
	}
	else
	{
		printf("找到了:%s\\n", ret);
	}
	return 0;
}

以上是关于C语言学习笔记(13)字符串和内存函数1的主要内容,如果未能解决你的问题,请参考以下文章

C语言学习笔记整理

C语言学习笔记(14)字符串和内存函数2

C语言笔记进阶篇第二章:字符串函数和内存函数

C语言笔记进阶篇第二章:字符串函数和内存函数

C学习笔记 知识集锦

2017/03/13学习笔记