前言
本文主要时对一些字符函数、字符串函数和内存函数进行模拟实现。
一、字符函数和字符串函数
1. 字符分类函数-islower
islower是用来判断是否是小写字母,如果是小写字母就返回非0的整数,如果不是小写字母就返回0。举一个简单的例子,写一个代码,将字符串中的小写字母转成大写,其他字符不变。
2. 字符转换函数
c语言中提供了两个字符转换函数:tolower(将大写字母转小写)和toupper(将小写字母转大写)。
3. strlen函数
strlen函数大家应该都不陌生,其返回字符串'\0'前面出现的字符个数(不包括'\0')。有两点需要注意,用strlen求字符串长度时候,所求字符串必须要以'\0'结尾且函数返回值是size_t(无符号整型)。接下里我们来看strlen的模拟实现。
#include<stdio.h>
#include<assert.h>
//创建临时变量count,计数器++实现
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(const char* start) {
assert(start);
char* end = start;
while (*end)
end++;
return end - start;
}
4. strcpy函数
strcpy函数实现将一个字符串拷贝到另一个字符串。其源字符串必须以'\0'结束,并且在拷贝过程中会将源字符串中的'\0'也拷贝到目标空间,最后返回目标字符串首元素地址。其函数声明如下:
char* strcpy(char * destination, const char * source );
模拟实现如下:
#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* dest, const char* src) {
char* ret = dest; //保存目标字符串起始地址
assert(dest && src);
while (*dest++ = *src++) {
;
}
return ret;
}
5. strcat函数
strcat函数实现拼接字符串,将一个字符串追加到另一个字符串的尾部。其源字符串和目标字符串均需要有'\0'以确定追加开始位置和结束,返回目标字符串首元素地址。其函数声明如下:
char* strcat(char* strDestination, const char* strSource);
模拟实现如下:
char* my_strcat(char* dest, const char* src) {
char* ret = dest;
assert(dest && src);
while (*dest)
dest++;
while (*dest++ = *src++) {
;
}
return ret;
}
6. strcmp函数
strcmp函数实现比较两个字符串大小,其比较的是两个字符串对应位置上的ASCII码值的大小。大于则返回大于0的数,等于则返回0,小于则返回小于0的数。例如:bc和abcdef,尽管bc字符串长度小于abcdef但bc的第一个字符b的ASCII值大于abcdef的第一个字符a的ASCII值,所以用strcmp函数比较这两个字符串得到的是大于0的数。其函数声明如下:
int strcmp(const char* string1, const char* string2);
模拟实现如下:
int my_strcmp(const char* str1, const char* str2) {
int ret = 0;
assert(str1 && str2);
while (*str1 == *str2) {
if (*str1 == '\0')
return 0;
str1++;
str2++;
}
return *str1 - *str2;
}
7. strncpy函数
strncpy函数与strcpy函数类似,都是实现字符串的拷贝,但strncpy可以指定拷贝的字符个数。有一点需要注意,如果源字符串长度小于要拷贝的字符个数,则在拷贝完源字符串后补0。其函数声明如下:
char * strncpy ( char * destination, const char * source, size_t num );
模拟实现如下:
char* my_strncpy(char* dest, const char* src, size_t num) {
assert(dest && src);
char* ret = dest;
while (num--) {
if (*src == '\0')
*dest++ = '\0';
else
*dest++ = *src++;
}
return ret;
}
8. strncat函数
strncat函数与strcat函数类似,都是实现字符串的拼接,但strncat可以指定拼接字符个数。有一点需要注意,源字符串长度小于要拼接字符个数时,仅将字符串中到'\0'的内容追加到目标字符的末尾。其函数声明如下:
char * strncat ( char * destination, const char * source, size_t num );
模拟实现如下:
char* strncat(char* dest, const char* src, size_t num) {
assert(dest && src);
char* ret = dest;
while (*dest)
dest++;
while (num--)
*dest++ = *src++;
return ret;
}
9. strstr函数
strstr函数用来寻找一个字符串是否包含另一个字符串,其返回要找字符串在另一个字符串中第一次出现的位置。其函数声明如下:
const char * strstr ( const char * str1, const char * str2);
模拟实现如下:
const char* my_strstr(const char* str1, const char* str2) {
assert(str1 && str2);
char* s1 = NULL;
char* s2 = NULL;
char* cur = str1;
if (*str2 == '\0')
return str1;
//用s1和s2遍历str1和str2字符串,cur存放s1遍历的起始位置
while (cur) {
s1 = cur;
s2 = str2;
//s1和s2指向的字符不为'\0'并且相等时,指针向后+1
while (*s1 && *s2 && *s1 == *s2) {
s1++;
s2++;
}
//str2遍历结束返回cur的地址,即str2在str1中的起始地址
if (*s2 == '\0')
return cur;
cur++;
}
return NULL;
}
二、 C语言内存函数
1. memcpy函数
memccpy函数声明如下:
void * memcpy ( void * destination, const void * source, size_t num );
该函数从source的位置开始向后复制num个字节的数据到destination指向的内存空间,在遇到'\0'的时候不会停止,且source和destination指向位置不能有重叠。
模拟实现如下:
void* memcpy(void* dest, const void* src, size_t num) {
void* ret = dest;
assert(dest && src);
//挨个字节拷贝
while (num--) {
*(char*)dest = *(char*)src;
//注意此时不能用(char*)dest++,强制类型转换时临时的,强转之后没有使用这时再++,dest已经变回void*类型
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return ret;
}
2. memmove函数
memmove函数与memcpy的差别就是,memmove处理的两个内存空间可以重叠。其函数声明如下:
void * memmove ( void * destination, const void * source, size_t num );
模拟实现如下:
void my_memmove(void* dest, const void* src, size_t num) {
assert(dest && src);
void* ret = dest;
//目标位置小于源位置,从前向后挨个拷贝
if (dest < src) {
while (num--) {
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
//目标位置大于等于源位置,从后向前挨个拷贝
else
while (num--)
*((char*)dest + num) = *((char*)src + num);
return ret;
}
结语
本文对一些c语言中的库函数进行了模拟实现。如本文对您的学习有所帮助,本人倍感荣幸。
吾尽吾心,终亦不悔,天道酬勤,何事难为。