👑个人主页:啊Q闻
🎇收录专栏:《C语言》
🎉道阻且长,行则将至
前言
这篇博客是字符串函数上篇,主要是关于长度不受限制的字符串函数(strlen,strcpy,strcat,strcmp)的使用和模拟实现。
字符串函数的头文件都是string.h
一.strlen
1.使用
1.字符串是以'\0'结尾,strlen函数是返回字符串中位于'\0'前的出现的字符的个数
2.参数指向的函数必须以'\0'结尾。
3.strlen函数的返回值是size_t,是无符号的(因为字符的个数不可能为负数)。
运行结果:
在内存中存储为:
关于第三点(strlen函数的返回值是size_t,是无符号的),我们可以写个代码验证一下
在代码中:s1的长度为6,s2的长度为3,应该是s1>s2。但是结果却是s2>s1,这是因为3-6=-3,而返回的是无符号整型,就变成了一个很大的整数。
2.模拟实现
方式一
int my_strlen(const char* s1)
{
int count = 0;
assert(s1);
while (*s1)//'\0'的ASCII码值为0
{
count++;//统计字符个数
s1++;//指针后移
}
return count;
}
int main()
{
char* s1 = "asdfgh";
int ret = my_strlen(s1);
printf("%d", ret);
return 0;
}
方式二 (递归方式)
int my_strlen(const char* s1)
{
assert(s1);
if (*s1 == '\0')
{
return 0;
}
else
{
return 1 + my_strlen(s1 + 1);//详解1
}
}
详解1:采用递归的方式,就不用创建临时变量,递归过程:
1+my_strlen("bcdef")
1+1+my_strlen("cdef")
1+1+1+my_strlen("def")
……
方式三(指针减指针的方式)
int my_strlen(const char* s1)
{
assert(s1);
char*p=s1;//保留指针初始位置
while (*p != '\0')
{
p++;
}
return p - s1;
}
二.strcpy
1.使用
1.源字符串必须以’\0’结尾
2.会将源字符串的'\0'拷贝到目标空间
3.目标空间必须足够大并且可以修改
运行结果:
2.模拟实现
char* my_strcpy(char* dest, const char* src)
{
char* ret = dest;//存留目的指针,便于后续返回
assert(dest);
assert(src);
while (*src)
{
*dest = *src;
dest++;
src++;
}
*dest = *src;//最后把'\0'赋给字符串
return ret;
}
int main()
{
char s1[20] = { 0 };
char* s2 = "asdfgh";
my_strcpy(s1, s2);
printf("%s", s1);
return 0;
}
三.strcat
1.使用
1.源字符串必须以'\0'结尾
2.字符串也必须要有'\0',否则不知道从哪里开始追加。
3.目标空间足够大并且可以修改。
运行结果:
内存存储:
2.模拟实现
char* my_strcat(char* dest, const char* src)
{
char* ret = dest;
assert(dest);
assert(src);
while (*dest)//遍历找到目标字符串的\0
{
dest++;
}
while (*src)
{
*dest = *src;
dest++;
src++;
}
*dest = *src;
return ret;
}
四.strcmp
1.使用
1.比较字符串,是比较两个字符串对应位置上的ASCII码值
当第一个字符串长度大于第二个字符串,则返回大于0的数字。
当第一个字符串长度小于第二个字符串,则返回小于0的数字。
当第一个字符串长度等于第二个字符串,则返回0。
运行结果:
详解:因为f的ASCII码值大于c的ASCII码值,所以s2>s1,返回值小于0
2.模拟实现
int my_strcmp(const char* p1, const char* p2)
{
int ret = 0;
assert(p1);
assert(p2);
while (*p1 == *p2)
{
if (*p1 == "\0")//遍历完后所有都相等
{
return 0;
}
p1++;
p2++;
}
return *p1 - *p2;
}
谢谢你的阅读,如果对你有帮助的,三连么么么