欢迎来到白刘的领域 Miracle_86.-CSDN博客
系列专栏 C语言知识
先赞后看,已成习惯
创作不易,多多支持!
在编程的过程中,我们经常要处理字符以及字符串,为了方便操作这些字符和字符串,C语言标准库中提供了一系列库函数,接下来我们就一起来学习这些函数,帮助字符和字符串完成它们的舞会之梦。
目录
一、字符分类函数
二、字符转换函数
三、strlen函数的使用以及模拟实现
方法1
方法2
方法3
四、strcpy函数的使用以及模拟实现
五、strcat函数的使用以及模拟实现
六、strcmp函数的使用以及模拟实现
一、字符分类函数
在C语言中,有一系列函数是专门用来做字符分类的,也就是一个字符是属于什么类型的字符。这些函数都包含在一个头文件:<ctype.h>。
其实上述的函数的使用方法都是非常类似的,所以我们就仅拿其中一个来举例说明。
int islower(int c);
islower函数可以判断一个字符是不是小写字母。
通过返回值来说明是否为小写字母,如果是则返回非0的整数,如果不是则返回0。
我们来举例练习一下:
//写⼀个代码,将字符串中的⼩写字⺟转⼤写,其他字符不变。
#include <stdio.h>
#include <ctype.h>
int main()
{
int i = 0;
char str[] = "Test String.\n";
char c;
while (str[i])
{
c = str[i];
if (islower(c))
c -= 32;
putchar(c);
i++;
}
return 0;
}
因为'A'的ASCII码值是65,'a'的ASCII码值为97,97-65=32,故转换仅需减32即可。
来看运行结果:
二、字符转换函数
C语言中提供了两个字符转换函数:
int tolower(int c); //将参数传进去的⼤写字⺟转⼩写
int toupper(int c); //将参数传进去的⼩写字⺟转⼤写
刚刚的代码我们是将字符-32来完成效果,这回我们有了字符转换函数,就可以之间上函数了。
#include <stdio.h>
#include <ctype.h>
int main()
{
int i = 0;
char str[] = "Test String.\n";
char c;
while (str[i])
{
c = str[i];
if (islower(c))
c = toupper(c);
putchar(c);
i++;
}
return 0;
}
运行结果是一样的:
三、strlen函数的使用以及模拟实现
我们先来看看strlen函数的原型:
size_t strlen(const char* str);
str我们很熟悉了,是string(字符串)的缩写,len其实是length的意思,所以这个函数大概我就能知道字面意思,它是用来求字符串长度的。
我们知道字符串是以'\0'结尾的,而strlen函数返回的就是在字符串在'\0'之前出现的字符的个数(不包含'\0')。
这里要注意几个点:
1.参数指向的字符串必须是以'\0'结尾。
2.参数的返回值是size_t类型的,是无符号的(易错)。
3.strlen函数是需要头文件的,它的头文件是<string.h>。
那了解完strlen的基本知识,接下来我们来看看它的实战使用:
#include <stdio.h>
#include <string.h>
int main()
{
const char* str1 = "abcdef";
const char* str2 = "bbb";
if (strlen(str2) - strlen(str1) > 0)
{
printf("str2>str1\n");
}
else
{
printf("srt1>str2\n");
}
return 0;
}
接下来看模拟实现:
方法1
//计数器⽅式
int my_strlen(const char* str)
{
int count = 0;
assert(str);
while (*str)
{
count++;
str++;
}
return count;
}
法1创建了个临时变量来计数,还使用了指针运算,由于'\0'为假,指针指到它时,也就意味着字符串结束,循环也就结束。我们还用到了assert断言,严谨一些,养成良好的习惯。
方法2
//不能创建临时变量计数器
int my_strlen(const char* str)
{
assert(str);
if (*str == '\0')
return 0;
else
return 1 + my_strlen(str + 1);
}
法2中我们使用了递归,由于每次我们都是+1,所以很容易想到使用递归来完成代码的实现。这里不会递归的兄弟们,传送门放在下面了:
C语言中的套娃——函数递归_俄罗斯套娃可以用递归实现吗-CSDN博客
方法3
//指针-指针的⽅式
int my_strlen(char* s)
{
assert(s);
char* p = s;
while (*p != '\0')
p++;
return p - s;
}
这种方法也使用了指针运算,可见指针运算有多好用:
灵魂指针,教给(一)-CSDN博客
这篇文章详细地讲述了指针的运算。
首先由于传进来的是字符串的首元素地址,然后我们再创建一个指针来移动,最后指针指向字符串末尾,首尾相减,便能知晓中间长度,也就是字符串的长度。
四、strcpy函数的使用以及模拟实现
char* strcpy(char* destination, const char* source);
首先我们认识两个单词:destination n.目的地,source n.源头。
然后我们再来拆分一下strcpy的字面意思,str还是字符串,cpy其实是copy的意思,那我们可以知道了,strcpy是用来拷贝字符串的。
这里说明几点细节:
1.原理:将 source 指向的 C 字符串复制到destination指向的数组中,包括终止 null 字符(并在该点停止)
2.源字符串必须以'\0'结尾。
3.目标空间必须足够大,确保能放下源字符串。
4.目标空间必须是可修改的。
接下来我们来看它的使用:
#include <stdio.h>
#include <string.h>
int main()
{
char src[40];
char dest[40];
strcpy(src, "Hello World");
strcpy(dest, src);
printf("最终的目标字符串:%s\n", dest);
return 0;
}
来看运行结果:
接下来我们来学习strcpy的模拟实现:
我们可以用两个指针分别指向目的地和源头,然后通过赋值即可完成拷贝。
//1.参数顺序
//2.函数的功能,停⽌条件
//3.assert
//4.const修饰指针
//5.函数返回值
//6.题⽬出⾃《⾼质量C/C++编程》书籍最后的试题部分
#include <stdio.h>
char* my_strcpy(char* dest, const char* src)
{
char* ret = dest;
assert(dest != NULL);
assert(src != NULL);
while (*src != '\0')
{
*dest = *src;
dest++;
src++;
}
*dest = *src; //拷贝'\0'
return ret;
}
上述代码已经可以完成效果了,但是我们还可以有更巧妙的代码:
#include<stdio.h>
char* my_strcpy(char* dest, const char* src)
{
char* ret = dest;
assert(dest != NULL);
assert(src != NULL);
while ((*dest++ = *src++))
{
;
}
return ret;
}
虽然++的优先级比*高,但是是后置++,先操作后++,所以先解引用,完成赋值后再++,最后到'\0',退出循环,是不是很巧妙。
五、strcat函数的使用以及模拟实现
char *strcat(char *dest, const char *src)
老规矩还是字面分析,str字符串,这个cat可不是小猫的那个cat,而是catenate的缩写,意思是连成一串。
1.原理:将源字符串的副本追加到目标字符串。终止 null 字符在 destination 中被 source 的第一个字符覆盖,并包含一个 null 字符在由两者在目的地的串联形成的新字符串的末尾。
2.源字符串必须以'\0'结尾。
3.目标字符串也需要有'\0',否则不知道从哪开始追加。
4.目标空间足够大。
5.目标空间可修改。
#include <stdio.h>
#include <string.h>
int main()
{
char src[50];
char dest[50];
strcpy(src, "World");
strcpy(dest, "Hello ");
strcat(dest, src);
printf("最终的目标字符串:%s", dest);
return 0;
}
运行结果:
之后我们学习strcat的模拟,这个其实很简单,刚刚我们学到了strcpy的模拟,那这个无非就是先找到destination中的'\0'再copy,代码如下:
#include<stdio.h>
#include<assert.h>
char* my_strcat(char* dest, const char* src)
{
char* ret = dest;
assert(dest != NULL);
assert(src != NULL);
while (*dest)
{
dest++;
}
while ((*dest++ = *src++))
{
;
}
return ret;
}
六、strcmp函数的使用以及模拟实现
int strcmp(const char *str1, const char *str2)
cmp是compare的缩写,是比较,顾名思义strcmp是比较字符串的。
1.原理:此函数开始比较每个字符串的第一个字符。如果它们等于彼此,它继续往下比较,直到字符不同或终止达到 null-character。
2.返回值:
- 如果返回值小于 0,则表示 str1 小于 str2。
- 如果返回值大于 0,则表示 str1 大于 str2。
- 如果返回值等于 0,则表示 str1 等于 str2。
3.比较的是两个字符的ASCII码值的大小。
#include <stdio.h>
#include <string.h>
int main ()
{
char str1[15];
char str2[15];
int ret;
strcpy(str1, "abcdef");
strcpy(str2, "ABCDEF");
ret = strcmp(str1, str2);
if(ret < 0)
{
printf("str1 小于 str2");
}
else if(ret > 0)
{
printf("str1 大于 str2");
}
else
{
printf("str1 等于 str2");
}
return(0);
}
strcmp的模拟实现,这个其实很简单,直接上代码:
int my_strcmp(const char* str1, const char* str2)
{
int ret = 0;
assert(str1 != NULL);
assert(str2 != NULL);
while (*str1 == *str2)
{
if (*str1 == '\0')
return 0;
str1++;
str2++;
}
return *str1 - *str2;
}
未完待续......