C语言字符函数,字符串函数以及内存函数
那么博主写这一片博客的目的就是为下一篇c++的string类做铺垫,那么下面就请期待博主的下一篇文章吧。
目录
1.字符函数
2.字符串函数(均在string.h头文件中)
strlen的使用和模拟实现
strcpy 的使用和模拟实现
strcat 的使用和模拟实现
strcmp的使用和模拟实现
strncpy 函数的使用
strncat 函数的使用
strncmp函数的使用
strstr 的使用和模拟实现
strtok函数的使用
strerror 函数的使用
3.C语言内存函数
memcpy使用和模拟实现
memmove使用和模拟实现(可以实现自己给自己追加)
memset函数的使用
memcmp函数的使用
1.字符函数
C语言标准库中的字符处理函数主要是在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;//小写字母与大写字母之间的ASCII值相差32。
putchar(c);
i++;
}
return 0;
}
那么字符函数咱们就不过多的阐述了。下面看字符串函数。
2.字符串函数(均在string.h头文件中)
strlen的使用和模拟实现
size_t strlen (const char*str)
1. 字符串以 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含'\0')
2. 参数指向的字符串必须要以 '\0' 结束。
3. 注意函数的返回值为size_t,是无符号的
4.strlen的使用需要包含头文件
那么下面咱们来看strlen的模拟实现,下面我提供了三种实现方式:
int my_strlen(const char * str)
{
int count = 0;
assert(str);
while(*str)
{
count++;
str++;
}
return count;
}//这个得引入一个新变量
int my_strlen(const char * str)
{
assert(str);
if(*str == '\0')
return 0;
else
return 1+my_strlen(str+1);
}//采用递归的方式
int my_strlen(char *s)
{
assert(str);
char *p = s;
while(*p != '\0' )
{
p++;
}
return p-s;
}//采用指针减指针的方式,这个方法在C语言指针这一篇博客有讲解
OK,下面进入六个函数的讲解
strcpy 的使用和模拟实现
char *strcpy (char*destination,const char*source)
1.源字符串必须以 '\0' 结束。
2.会将源字符串中的 '\0' 拷贝到目标空间。
3.目标空间必须足够大,以确保能存放源字符串。
4. 目标空间必须可修改
5.从源头开始拷贝。
但是这样你打印的话,只能打印出来“xxx”,因为,打印自动到'\0'停止,所以你打印不出完整的拷贝后的字符串,不过可以通过调试观察。
以上也是strcpy函数的模拟实现。
思路:
1.由于返回起始空间的地址,所以要先保存起始空间的地址,防止后面++后,找不到起始空间的地址了。
2.接着断言,防止p与p1指针传的是无效地址。
3.然后把p1指向的字符串中的字符挨个拷贝到p指向的字符串中,之后p1指向的字符串中的字符位置与p指向的字符串中的位置都往后挪动一位。依次重复。
strcat 的使用和模拟实现
char*strcat (char*destination,const char*source)
1.源字符串必须以 '\0' 结束。
2.目标字符串中也得有 \0 ,否则没办法知道追加从哪里开始。
3. 目标空间必须有足够的大,能容纳下源字符串的内容。
4. 目标空间必须可修改。
5.destination中的'\0'也会被覆盖。
以上是strcat的模拟实现,需要注意的是这里不可以自己给自己追加,否则会导致未定义。
思路:
1.首先先断言一下,由于这里传的是起始空间的地址,所以还要创建一个变量,用来存储起始地址。
2.之后先去找destination中的'\0',找到之后,就从这开始拷贝即可,需要注意的是,source中的'\0'也会别拷贝到目标字符串中。
strcmp的使用和模拟实现
int strcmp (const char*str1,const char*str2)
其实这个函数就是一个用于比较字符串大小的工具。
1.第⼀个字符串大于第二个字符串,则返回大于0的数字 ◦
2.第⼀个字符串等于第二个字符串,则返回0 ◦
3.第⼀个字符串小于第二个字符串,则返回小于0的数字 ◦
4.那么如何判断两个字符串?比较两个字符串中对应位置上字符ASCII码值的大小。
下面看strcmp函数的模拟实现:
不过要注意的是这里博主用的编译器是vs,并且返不返回1,-1,0,纯看编译器,有的编译器就是不返回这几个数字。
模拟实现代码思路:
1.还是老样子先断言,之后从第一个字符的ASCII值开始比较。
2.如果第一个字符相等,那么++,继续往后比较,如果比较完了,直到最后一个标识字符'\0'都相等,那么就返回0.
3.如果第一个字符串的第一个字符比第二个字符串的第一个字符大,那么就返回1(vs下),否则返回-1.
以上三个函数都是长度不受限制的,那么下面看3个长度受限制的。
strncpy 函数的使用
char * strncpy ( char * destination, const char * source, size_t num );
1.拷贝num个字符(不是字节)从源字符串到目标空间。
2.如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加'\0'(可通过调试观察),直到num个 。
该函数就是strcpy函数的减缩版,模拟实现方式差不多,这里就不做演示了。
strncat 函数的使用
char * strncat ( char * destination, const char * source, size_t num );
1.将source指向字符串的前num个字符追加到destination指向的字符串末尾,再追加⼀个'\0'字符。
很细节,方便打印
2.如果source 指向的字符串的长度小于num的时候,它不会像strncpy一样,在后面追加'\0',而是直接不管,直接在destination的字符串末尾加一个'\0'即可。
strncmp函数的使用
int strncmp ( const char * str1, const char * str2, size_t num );
比较str1和str2的前num个字符,如果相等就继续往后比较,最多比较num个字母,如果提前发现不⼀ 样,就提前结束,大的字符所在的字符串大于另外⼀个。如果num个字符都相等,就是相等返回0。 (就是比strcmp函数多了个限制条件)
strstr 的使用和模拟实现
strstr的作用是用来查找子串的。
char * strstr ( const char * str1, const char * str2);
1.函数返回字符串str2在字符串str1中第一次出现的位置。
2.字符串的比较匹配不包含 '\0' 字符,以 '\0 '作为结束标志。
来看它的模拟实现吧。
思路:
1.首先先断言一下,因为要返回起始空间的地址,所以说要创建一个变量存放起始地址。
2.先来一个循环,条件是找的时候第一个字符串!='\0',之后,将指向第一个字符串的指针再赋值给s1,指向第二个字符串的指针再赋值给s2,之后便可以开始比较了。
3.如果说找到了s1跟s2相等的字符,那么各自++,继续往后比较,但凡有一个字符不相等了,直接退出循环,cur++,(即返回第一个字符串的起始地址,并且加一,让它从第一个字符串的第二个字符开始比较)。
4.如果说,比较完了,而且正好发现了第一个字符串中藏了第二个字符串,就是到了if阶段,那么这时候,s2就到了'\0'的位置,这时候直接返回当时找的第一个字符串的起始地址即可。
5.不过这里需要注意的是,你打印的时候,是会遇到'\0'才会停止的,所以说,比如,第一个字符串“abcdef”,第二个字符串“cde”,那么可以打印出cdef。
strtok函数的使用
1.sep参数指向⼀个字符串,定义了用作分隔符的字符集合
2.第⼀个参数指定⼀个字符串,它包含了0个或者多个由sep字符串中⼀个或者多个分隔符分割的标 记。
3.strtok函数找到str中的下⼀个标记,并将其用 \0 结尾,返回⼀个指向这个标记的指针。
(注: strtok函数会改变被操作的字符串,所以被strtok函数切分的字符串⼀般都是临时拷贝的内容并且可修改。)
4.strtok函数的第⼀个参数不为 中的位置。 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串
5.strtok函数的第⼀个参数为 NULL ,函数将在同⼀个字符串中被保存的位置开始,查找下⼀个标 记。
6.如果字符串中不存在更多的标记,则返回 NULL 指针
strerror 函数的使用
char* strerror ( int errnum );
strerror 函数可以把参数部分错误码对应的错误信息的字符串地址返回来。 在不同的系统和C语言标准库的实现中都规定了⼀些错误码,⼀般是放在 errno.h 这个头文件中说明 的,C语言程序启动的时候就会使用⼀个全局的变量errno来记录程序的当前错误码,只不过程序启动 的时候errno是0,表示没有错误,当我们在使用标准库中的函数的时候发⽣了某种错误,就会将对应 的错误码,存放在errno中,而⼀个错误码的数字是整数很难理解是什么意思,所以每⼀个错误码都 是有对应的错误信息的。strerror函数就可以将错误对应的错误信息字符串的地址返回 。
3.C语言内存函数(也在string.h头文件中)
memcpy使用和模拟实现(覆盖原理)
void * memcpy ( void * destination, const void * source, size_t num );
1.函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置。
2. 这个函数在遇到 '\0' 的时候并不会停下来。
3.如果source和destination有任何的重叠,复制的结果都是未定义的 。
4.对于重叠的内存,交给memmove来处理。
来看它的模拟实现
思路:
1.由于也是返回起始空间的地址,所以说先定义一个临时变量,用来存储起始空间的地址,之后再断言。
2.以count--为循环条件,决定了要拷贝的次数,并且让source中的字符拷贝到destination中,一个字符拷贝完之后,++,直到count被减完,才停止赋值。
memmove使用和模拟实现(可以实现自己给自己追加)
void * memmove ( void * destination, const void * source, size_t num );
其实memmove的用法与memcpy基本一样,就以下不同点:
1.和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
2.如果源空间和目标空间出现重叠,就得使用memmove函数处理。
来看它的模拟实现:
memset函数的使用
void * memset ( void * ptr, int value, size_t num );
memset是用来设置内存的,将内存中的值以字节为单位设置成想要的内容。
memcmp函数的使用
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
比较从ptr1和ptr2指针指向的位置开始,向后的num个字节 ,这个其实也是比较类的函数,与strcmp,strncmp差不多。
下面来看它的返回值:
再来看一个例子:
相信大家对这个函数也已经理解了吧。
以上内容是我个人理解,若有不对,还请指出!谢谢!
本篇完...............