学习使用库函数是我们学习c语言必须掌握的,不会灵活使用库函数是一个不太合格的码农。当然库函数也是函数,我们只需要了解怎么使用就行。但是总有人想要知道这些库函数是这么实现的。当然了接下来我就介绍几个有关字符串有关的库函数。希望对你们有帮助吧,
我要讲解字符串有关的库函数,说倒字符串大家都不会陌生的,那接看一下这两个代码
char arr1 = "happy new year";
char arr2 = "to you all "
大家看见这两个字符数组,不难发现怎么将两个字符数组元素组在一起尼,组在一起就是祝福大家快新的一年快乐,比较大家都放元旦假了,就我一个人这个时候不忘记分享一下知识给你们,好了废话都不多了。这个时候就要借助我们 好工具——库函数 (strcat);这个库函数作用是把arr2的数组元素追加倒arr1的屁股后面当“小弟”;当然也可以将arr1 变成arr2的小弟也不是不可以,这个时候就是你这个老大想怎么做了。只需要改变参数位置就ok了。当然了也不是谁都能让当小弟了,这个时候就有人会说这个是怎么讲的,这个函数还是有不足地方,比如我要arr2追加倒arr1后面,假如arr1只能装不下arr2的元素就会出现缓冲区溢出问题。所以说我们要注意追加(目标函数)能够存的下去,当然除了缓冲区溢出问题还有空指针啊,还有字符串终止符等;像我们字符串函数都会运用字符串这个隐藏终止符 ——“\0”;我们想要arr2当小弟,跟着大哥后面总要找到大哥最后一个位置吧,然后在进行拷贝替换,就会有人问既然是追加,为什么到这里就说成替换尼,我来解释一下因为假如arr1有三十个字节,arr1元素假设占了十个字节,那还有剩下字节我是通过调试知道剩下的都是以0占的,以“\0”做终止标志,所以说我们想arr2元素追加到arr2后面本质是替换。当然你们也可以调试试试看。假如我哪里说的不对,欢迎你们指出来;那接下来看一下这个代码吧
char* my_strcat(char* p1, const char* p2)
{
char* res = p1;//记录元素
assert(p1 && p2);
while (*p1)//找到arr1的/0的位置
{
p1++;//指针指向/0但是不需要解引用,只需要指向就行
}
while ((*p1++ = *p2++))//将p1的/0与p2的元素进行解引用替换,当p2遇见/0,同时p1也是0就会退出循环,同时res也记录下来并返回
{
;
}
return res;
}
int main()
{
char arr1[30] = "happy new year";
char arr2[] = "to you all";
my_strcat(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
这里我是运用指针的方法的,接下来我来简单分析一下这串代码吧my_strcat函数接收两个参数,这个时候有人看见为什么是 const 修饰第二个参数,因为第一个参数要发生改变不能用const修饰
但是我们不希望第二个参数发生改变,所以用const修饰一下,然后我们看到assert(p1 && p2)这个作用是使用?assert
?断言来确保?dest
?和?src
?均不为 NULL。然后第一个while循环(*p1)解引用p1然后在p1++这里只需要指针指向位置加1,不需要解引用,然后如此循环下去直到(*p1)解引用遇到“\0",然后退出循环同时指针p1指向arr的”\0“;然后进入第二个while循环(*p1++ = *p2++)等价于(*p1)++ = (*p2)++;先解引用在p1等于p2,然后指针加一,因为p1上面讲的一直是0,这个时候只要p2遇见”\0"就退出循环,while的括号里面逗好,即使不用也要加一个空语句。最后通过res记录,并返回,用arr1输出是因为执行了?my_strcat_recursive(arr1, arr2)
?后,arr1
?中的内容已经发生改变,变成了?"happy new year to you all"
,这是将?arr2
?的内容连接到?arr1
?后得到的结果。当然了这个只是其中一中方法模拟实现这一个函数。这里我就只介绍这一个指针方法。这里我就介绍这一中方法。
接下来就介绍第二个函数strcmp,续接上一个例子我们来看一下吧
char arr1 = "happy new year";
char arr2 = "to you all "
假如我们想要知道这两个字符数组谁大谁小尼,我们一看肯定有人会说arr1大啊,因为他的字符数比arr2多就大了。要是生活中可以怎么说,但是在这里我们不能怎么说,因为编译器在使用ASCII码进行字符比较的,相信学习编程人都听说过这个ASCll这个,所以说我们要把字符转化成ASCll的值进行比较,所以说两个字符数组一个一个上下对齐比较,相同就同时指向下一个字符进行比较。
这就是strcmp运行原理,接下来看代码吧,通过代码分析,这里我还是以指针的方法的
int my_strcmp(const char* p1, const char* p2)
{
assert(p1 && p2);
while (*p1 == *p2)
{
if (*p1 == '\0') {
return 0;
}
p1++;
p2++;
}
return *p1 - *p2;
}
int main()
{
char arr1[30] ="happy new year";
char arr2[] = "to you all";
int res = my_strcmp(arr1, arr2);
if (res > 0)
printf("arr1 > arr2");
else if (res < 0)
printf("arr1 < arr2");
else
printf("arr1 = arr2");
return 0;
}
这里我们就简单分析一下这个代码吧,通过my_strcmp接收参数,同时我们不希望这两个实参发生改变,我们保持一个好的习惯给用const修饰一下,同时给两个形参断言一下。,然后进入while判断*p1? 是否等于 *p2,假如等于就同时指针加一指向下一个在进行判断一下,假如遇见不相等,就两个解引用做差,并返回res接受判断大小,大于0就是arr1>arr2,反之小于0就是arr1<arr2 ,然后就是相等输出arr1 == arr2,if(*p1 == ”\0“)等价于if(*p1)这个作用是防止两个字符一直相等遇见”\0"都遇见”\0“;
好了这个两个函数就介绍到这了,当然了这两个函数都可以使用递归方法模拟实现,但是我这里就不简述递归过程了,你们看看一下就行了。我就在这个原来基础上稍微修该一下。看看就行了。
int my_strcmp(const char* p1, const char* p2)
{
assert(p1 && p2);
if (*p1 && *p2)
{
return 0;
}
if (*p1 == *p2) {
// 如果当前字符相等,则比较下一个字符
return my_strcmp(p1 + 1, p2 + 1);
} else {
// 如果当前字符不相等,则返回两个字符的差值
return *p1 - *p2;
}
}
int main()
{
char arr1[30] ="happy new year";
char arr2[] = "to you all";
int res = my_strcmp(arr1, arr2);
if (res > 0)
printf("arr1 > arr2");
else if (res < 0)
printf("arr1 < arr2");
else
printf("arr1 = arr2");
return 0;
}