阿林说:先点赞,后观看,养成习惯!
“点赞收藏加关注,下次更新不迷路!”
在c语言中,字符可以是电脑上可以显示的各种符号:字母、数字、中文;也包含一些无法显示的符号 :换行符、回车符等等
1.字符分类
就像整形分为长整型、短整型、整形 ,字符也有划分
为了方便操作字符和字符串,C语言使用了一系列函数来判断字符类型,这些函数需要使用的头文件是 ctype.h
(函数) (如果他的参数符合下列条件就返回真)
iscntrl : 任何控制字符
isspace : 空白字符:空格换页“f’,换行"n',回车'\r’制表符"t'或者垂直制表符'v'
isdigit : 十进制数字 0~9
isxdigit : 十六进制数字,包括所有十进制数字,小写字母a~f,大写字母A~F
islower : 小写字母a~z
isupper : 大写字母A~Z
isalpha : 字母a~z或A~Z
isalnum : 字母或者数字,a~z,A~Z,0~9
ispunct : 标点符号,任何不属于数字或者字母的图形字符(可打印)
isgraph :任何图形字符
isprint :任何可打印字符,包括图形字符和空白字符
使用这些函数的用法几乎一样:
int islower ( int c );
1.2 strlen
strlen是库函数,简单来说,这个函数就是计算字符串的长度,而这个函数的实现我们可以将它模拟出来
我们首先需要知道这个函数的返回值,函数参数
size_t strlen ( const char * str );
返回的是字符或字符串中‘\0'前的字符个数
接下来就是模拟了:
int my_strlen(const char* str)
{
int count = 0;
assert(str);
while (*str)
{
count++;
str++;
}
return count;
}
当然,模拟实现的方法很多,可以自行探索
1.3 strcpy
strcpy是字符串拷贝函数,strcpy(arr1, arr2),可以将字符型字符或字符串arr2,拷贝到arr1中,需要注意的是:
这两个字符或字符串都要是char类型的
源字符串必须以 '\0' 结束
会将源字符串中的 '\0' 拷⻉到⽬标空间
⽬标空间必须⾜够⼤,以确保能存放源字符串
⽬标空间必须可修改
学会模拟实现
将这个函数模拟出来:
char* my_strcpy(char* dest, const char* src)
{
char* ret = dest;
assert(dest != NULL);
assert(src != NULL);
while ((*dest++ = *src++))
{
;
}
return ret;
}
1.4 strcat
简单来说,strcat是 字符拼接函数,strcat(arr1, arr2)可以将char类型的字符或字符串,拼接到char类型的字符或字符串的后面
如:
char arr1[20] = "abcd";
char arr2[] = "efgh";
strcat(arr1, arr2);
// 此时的arr1就是"abcdefgh"
模拟一下这个函数:
源字符串必须以 '\0' 结束
⽬标字符串中也得有 \0 ,否则没办法知道追加从哪⾥开始
⽬标空间必须有⾜够的⼤,能容纳下源字符串的内容
⽬标空间必须可修改
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;
}
1.5 strcmp
strcmp这个函数,是用来比较两个字符串大小的,字符能比较大小?字符串能比较大小吗?答案是:能!字符有其asscii码值,并且都是唯一的,如a的ascii码值是97,字符串如何比较大小呢?每个字符一个一个去比较
如“abcd”和“accd”这两个字符串,先比较各自的第一个字符,两个都是a,再比较下一个第一个字符串的是b,而第二个字符串的是c,b的ascii码是98,c的asscii码是99,所以,第二个字符串大于第一个字符串
再来说说strcmp的返回值
char arr1 = "abcd";
char arr2 = "accd";
int ret = strcmp(arr1, arr2);
函数的用法如上所示 ,这个函数的返回值,是由arr1和arr2,决定的,如果arr1大于arr2,函数的返回值大于零,如果arr1等于arr2,函数返回值等于零,如果arr1小于arr2,函数返回值小于零
模拟strcmp:
int my_strcmp(const char* str1, const char* str2)
{
int ret = 0;
assert(src != NULL);
assert(dest != NULL);
while (*str1 == *str2)
{
if (*str1 == '\0')
return 0;
str1++;
str2++;
}
return *str1 - *str2;
}
2.strncpy 系列函数
strncpy,strncat这两个函数与上面所述的函数非常相似,只是多一个个字母n,其实,它的功能变化也是如此,这两个函数与strcpy,strncat相比,多了一个参数,用于决定:复制过去的字节数;拼接过去的字节数,由于这两个函数针对char类型,所以一个字节就是一个字符
char arr1[20] = "abcdef";
char arr2 = "abcd";
strncpy(arr1, arr2, 3);
( , ,3)这个3就是这个参数,在这里代表复制arr2的前三个字符给arr1
模拟实现这个函数和上面的类似,可以思考一下
3.内存函数
3.1 mencpy
memcpy是内存拷贝函数,不再限定什么类型,只要合法使用,可以将整形、字符型的数据拷贝,
这个函数有三个参数
memcpy(arr1, arr2, 4);
像上面的写法,说的其实是将arr2中的四个字节的内容,拷贝到arr1中
实现这个函数的各参数的类型的要求是:
void* memcpy(void* destination, const void* source, size_t num);
模拟需要注意的是:
函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置
这个函数在遇到 '\0' 的时候并不会停下来
如果source和destination有任何的重叠,复制的结果都是未定义的
模拟代码如下:
void* memcpy(void* dst, const void* src, size_t count)
{
void* ret = dst;
assert(dst);
assert(src);
while (count--) {
*(char*)dst = *(char*)src;
dst = (char*)dst + 1;
src = (char*)src + 1;
}
return(ret);
}
3.2memmove
这个函数与上面的memcpy函数非常相似,很多情况下,这两个函数的使用结果是一样的,不一样的地方在于更深层次的理解:
用以下的代码示范一下:
int arr1 = { 1,2,3,4,5,6 };
memcpy(arr1 + 1, arr1, 3);
memmove(arr1 + 1, arr1, 3);
以上需要完成我们写的代码时,c语言规定的memcpy是无法完成任务的
因为 memcpy的设定就是不能对重叠部分进行处理(如果成功处理,那就是恰好符合实现函数的代码的逻辑,或者使用的环境支持这种处理(如VS2022))
就是因为将内存拷贝划分为有重叠拷贝和无重叠拷贝,设计时将 内存拷贝函数分成了memcpy和memcpy
函数的参数和类型和上述一模一样,只是功能略有变化
模拟实现代码如下:
void* memmove(void* dst, const void* src, size_t count)
{
void* ret = dst;
if (dst <= src || (char*)dst >= ((char*)src + count)) {while (count--)
{
*(char*)dst = *(char*)src;
dst = (char*)dst + 1;
src = (char*)src + 1;
}
}
else
{
dst = (char*)dst + count - 1;
src = (char*)src + count - 1;
while (count--)
{
*(char*)dst = *(char*)src;
dst = (char*)dst - 1;
src = (char*)src - 1;
}
}
return(ret);
}
3.3memset
memset函数其实就是它字面意思,设置内存的值,以字节为单位设置需要存储的值
用法如下:
#include <stdio.h>
#include <string.h>
int main()
{
char str[] = "hello world";
memset(str, 'x', 6);
printf(str);
return 0;
}
上述代码的以上是:从str开始,向后6个字节的内容换成‘x'
运行结果:xxxxxxworld
3.4memcmp
想必大家也发现了,memcmp这个 函数以cmp结尾,是比较的意思,和上面的strcmp类似,实际上确实如此,只是memcmp这个函数是对内存进行比较,单位是字节
函数的写法如下:
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
既然是内存比较函数,参数就可以是整形,也可以是字符型了,但是第一个参数的类型要与第二个参数类型相同
函数的返回值与 strcmp一样
char arr1 = "abcd";
char arr2 = "accd";
int ret = memcmp(arr1, arr2);
这个函数的返回值,是由arr1和arr2,决定的,如果arr1大于arr2,函数的返回值大于零,如果arr1等于arr2,函数返回值等于零,如果arr1小于arr2,函数返回值小于零
阿林说:“这里 是一些与字符,字符串,以及与内存有关的函数,理解后其实不容易混淆”
“各位大佬记得点赞哦”