长度不限制:
深入解析C语言strlen函数的三种实现方式
使用字符串函数函数之前要引入头文件<string,h>
strlen函数
size_t strlen( const char*str )
功能:统计‘\0’之前的字符个数;
参数: str 指针,指向要统计长度的字符串,本质是要统计的字符串的首字符的的地址,参数是地址,所以类型为char* ,但是要传的字符串是常量,因为常量不可变,所以这里加上了const,赋予常属性;
返回值:size_t (无符号整型),意味着计算结果不可能是负数。
对于返回值,举个例子:
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[] = 'abc';
char arr2[] = 'abcdef';
if((strlen(arr1)-strlen(arr2))>0) //strlen返回值是size_t,所以这里运算的结果-3会变为更大的正数;
{
printf(">0");
}
else
{
printf(“<=0”);
}
}
运行结果: >0 .
//《strlen函数的模拟》//:
第一种(利用计数器
):
#include<stdio.h>
#include<stdlib.h>
size_t my_strlen(const char* str)
{
int count = 0;
while (*str)
{
count++; //因为进入循环,说明首字符不是‘\0’,所以字符串长度至少为1,所以count++放前;
str++;
}
return count;
}
int main()
{
char arr[] = "abcdef";
size_t sz = my_strlen(arr);
printf("%d", sz);
return 0;
}
第二种(利用指针-指针):
#include<stdio.h>
#include<stdlib.h>
size_t my_strlen(const char* str)
{
char* start = str; //把str这个指针赋值给start这个指针,相当于把str内存储的地址赋给start这个指针;
while (*str)
{
str++;
}
return str - start; | 指针-指针| 结果是两个指针之间的元素个数;
}
int main()
{
char arr[] = "abcdef";
size_t sz = my_strlen(arr);
printf("%d", sz);
return 0;
}
第三种(递归):
思路: *str 得到的是首元素,如果首元素不为‘\0’,那就返回1,剩下"bcdef";然后让首元素地址+1,来到b,因为 b!='\0',所以再次加1,然后依次调用;
关系网:
1+ 'bcdef' 1+1+1+1+1+1+0
1+'cdef' 1+1+1+1+1+0
1+'def' 1+1+1+1+0
1+'ef' 1+1+1+0
1+'f' 1+1+0
1+'\0' 1+0
#include<stdio.h>
#include<stdlib.h>
size_t my_strlen(const char* str)
{
if (*str)
{
return 1 + my_strlen(str + 1);
}
else
{
return 0;
}
}
int main()
{
char arr[] = "abcdef";
size_t sz = my_strlen(arr);
printf("%d", sz);
return 0;
}
深入解析strcpy函数的实现原理
使用前要引入头文件<string.h>
char* strcpy(char*destination,const char*source)
功能:拷贝source所指向的字符串里到‘\0’而且包括‘\0’的部分;
参数: source指向拷贝数据,destination指向目标空间;
两个参数本质是接收首字符的地址;
源头仅起提供数据作用,所以不可变,所以是 const char*, 目标空间要能被修改所以无const;
返回值:最终返回目标空间的起始地址;
#include<stdio.h>
#include<string.h>
int main()
{
char source[] = "abc";
char dest[20] = "------------";
strcpy(dest, source);
printf("%s", dest); //%s 打印字符串,这里这个语句表示从dest这个起始地址向后打印直至‘\0’;
}
注意:
源头字符串必须含有‘\0’;
目标空间要足够大,并且可以修改;
《strcpy的模拟实现》
第一种:
#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strcpy(char* dest, const char* source)
{
char* start = dest;
assert(dest && source);//因为循环里使用了*,一旦*一个空指针,程序就会崩溃,所以用assert
while (*source!='\0') // 来检查是否为空指针,防止程序崩溃;
{
*dest = *source;
dest++;
source++;
}
*dest = *source; //这里dest不在起始位置不能直接返回,因为要返回目标空间的起始地址, 所 // 以开局先加个存档;
return start;
}
int main()
{
char source[] = "abc";
char dest[20] = "------------"; //这里为了方便调试时看出‘\0’是否是source里的加入‘-----------’
//结果为“abc'\0'--------剩下的均为‘\0’”;
char* r = my_strcpy(dest, source);
printf("%s\n", dest); //有返回值,可用也可以不用;
printf("%s",r);
}
第二种:
#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strcpy(char* dest, const char* source)
{
char* start = dest;
assert(dest && source);
while (*dest++ = *source++) //先用后++
{
; //*dest = * source;右边先计算得到source所指向的值;
} // 左边再计算,得到的是dest所指向的空间;
/*while(*source!= '\0')
{
*dest++ = *source++;
}*/
return start;
}
int main()
{
char source[] = "abc";
char dest[20] = "------------";
char* r = my_strcpy(dest, source);
printf("%s\n", dest);
printf("%s",r);
}
深入解析strcat函数实现原理
使用前引入头文件<string.h>
char* strcat(char*destination,const char*source)
功能: 字符串追加,把source指向的源字符串追加到destination指向的空间中;
参数:
destination: 指针,指向目标空间;
source: 指针,指向源头数据;
返回值:
目标空间的起始地址;
注意:
目标空间中必须有‘\0’,不然不知道从哪里开始追加;
目标空间必须可以被修改;
源头数据中也必须有‘\0’;
例子:
#include<stdio.h>
#include<string.h>
#include<assert.h>
int main()
{
char dest[20] = "hello";
char src[] = "world";
char*p = strcat(dest, src);
printf("%s\n",dest);
printf("%s",p);
return 0;
}
《strcat的模拟实现》:
#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strcat(char* dest, const char* src)
{
char* start = dest;
assert(*dest&&*src); //防止*NULL导致程序崩溃;
while (*dest)
{
dest++; // 追加从‘\0’开始覆盖;
}
while (*dest++ = *src++)
{
;
}
return start;
}
int main()
{
char dest[20] = "hello";
char src[] = "world";
char*p = my_strcat(dest, src);
printf("%s\n",dest);
printf("%s",p);
return 0;
}
深入解析strcmp函数实现原理
int strcmp(const char* str1,const char* str2)
功能:比较两个字符串的大小;
参数:
两个字符指针;
返回值:
标准规定:
1.第一个字符串大于第二个字符串,返回一个大于0的数字;
2.第一个字符串等于第二个字符串,返回0;
3.第一个字符串小于第二个字符串,返回一个小于0的数字;
比较思路:
按照字典序来比,字典序越靠后越大,从第一个字符开始比,如第一个字符相同就比较下一个字符,直至两个字符不同或者都是‘\0’结束;
举个例子:
#include<stdio.h>
#include<string.h>
#include<assert.h>
int main()
{
char str1[] = "abcdef";
char str2[] = "abq";
int r = strcmp(str1,str2);
printf("%d\n",r);
if (r > 0)
{
printf(">\n");
}
else if (r == 0)
{
printf("<\n");
}
else
{
printf("==\n");
}
return 0;
}
《strcmp的模拟实现》:
#include<stdio.h>
#include<string.h>
#include<assert.h>
int my_strcmp(const char*str1,const char*str2)
{
assert(*str1 && *str2);//防止*NULL导致程序崩溃
while (*str1 == *str2)
{
if (*str1 == '\0')
return 0;
str1++;
str2++;
}
if (*str1 > *str2)
return 1;
else
return -1;
//可以把if语句换成如下:
//return *str1 - *str2;
}
int main()
{
char str1[] = "abcdef";
char str2[] = "abq";
int r = my_strcmp(str1,str2);
printf("%d\n",r);
if (r > 0)
{
printf(">\n");
}
else if (r == 0)
{
printf("<\n");
}
else
{
printf("==\n");
}
return 0;
}
长度限制:
strn 比str 更加灵活更加安全;
char* strncpy(char* destination,const char* source,size_t num);
功能:和strcoy一样,但是最多拷贝num个字符;
与strcpy相比,strncpy的不同:
源头字符串可以不用必须有‘\0’;
size_t num 这个参数让这个函数有了思考:目标空间是否够大;
举例:
int main()
{
char dest[20] = "--------------";
char src[] = "abcd";
// strncpy(dest, src, 3); //限制不超过源头字符串长度,只会拷贝num个,不会在拷贝字符串后加
// ‘\0’ ;
char* p = strncpy(dest,src,8);//如果超过源头字符串长度,超出的部分会自动补‘\0’;
printf("%s\n",dest);
printf("%s\n",p);
//通过以下代码可以逐行打印直观管观察;
int sz = sizeof(dest) / sizeof(dest[0]);
int i = 0;
for (i = 0; i <sz ; i++)
{
printf("%c\n", dest[i]);
}
return 0;
}
char* strncat(char* destination,const char*source ,size_t num)
功能:和strcat一样,但是 最多追加num个字符;
举个例子:
int main()
{
char dest[20] = "-\0-------------";
char src[] = "abcd";
strncat(dest, src, 3);//如果num<源头字符串长度,会自动补‘\0’; //如果大于则有几个追加几个 , //并不补‘\0’;
printf("%s\n",dest);
int sz = sizeof(dest) / sizeof(dest[0]);
int i = 0;
for (i = 0; i <sz ; i++)
{
printf("%c\n", dest[i]);
}
return 0;
}
int strncmp(const char* str1,const char*str2,size_t)
功能:和strcmp一样,但是最后限制num个字符串进行比较;
举个例子:
int main()
{
char str1[] = "abcdef";
char str2[] = "abc";
int r = strncmp(str1, str2, 4);
printf("%d", r);
return 0;
}