部分标准库函数及源码
- 数据和宏定义
#define NULL ((void *)0)
#define TOLOWER(c) ((((c) > 'A') && ((c) < 'Z')) ? ((c) - 'A' + 'a') : (c))
typedef unsigned int size_t;
- 1、memcpy:从存储区 src 复制 n 个字符到存储区 dest
void *func_memcpy(void *dst, const void *src, size_t cnt)
{
void *ret = dst;
while(cnt--)
{
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
return ret;
}
- 2、memchr:在buff 所指向的字符串的前 n个字节中搜索第一次出现字符 chr
void *func_memchr(const void *buff, int chr, size_t cnt)
{
while(cnt && *(unsigned char *)buff != (unsigned char)chr)
{
buff = (unsigned char *)buff + 1;
cnt--;
}
return (cnt > 0 ? (void *)buff : NULL);
}
- 3、memcmp:把 buff1和 buff2的前 n 个字节进行比较
int func_memcmp(const void *buff1, const void *buff2, size_t cnt)
{
if(cnt == 0)
{
return 0;
}
while(cnt-- && *(char *)buff1 == *(char *)buff2)
{
buff1 = (char *)buff1 + 1;
buff2 = (char *)buff2 + 1;
}
return (*((unsigned char *)buff1) - *((unsigned char *)buff2));
}
- 4、memmove:另一个用于从 src 复制 n 个字符到 dest 的函数
/*如果目标区域和源区域有重叠的话,memmove() 能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,
复制后源区域的内容会被更改。如果目标区域与源区域没有重叠,则和 memcpy() 函数功能相同*/
void *func_memmove(void *dst, const void *src, size_t cnt)
{
void *ret = dst;
if(dst <= src || (char *)dst >= (char *)src + cnt)
{
while(cnt--)
{
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
}
else
{
/*地址存在重叠*/
dst = (char *)dst + cnt - 1;
src = (char *)src + cnt - 1;
while(cnt--)
{
*(char *)dst = *(char *)src;
dst = (char *)dst - 1;
src = (char *)src - 1;
}
}
return ret;
}
- 5、strcat:把 src 所指向的字符串追加到 dest 所指向的字符串的结尾
char *func_strcat(void *dst, const char *src)
{
void *cp = dst;
while(*cp)
{
cp++;
}
while(*src)
{
*cp++ = *src++;
}
return dst;
}
- 6、strchr:在string 所指向的字符串中搜索第一次出现字符 chr的位置
char *func_strchr(void *string, int chr)
{
while(*string && *string != (char)chr)
{
string++;
}
return ((*string == (char)chr) ? (char *)string : NULL;
}
- 7、strcpy:把 src 所指向的字符串复制到 dest
char *func_strcpy(char *dst, const char *src)
{
char *cp = dst;
while(*cp++ = *src++)
{
;
}
return dst;
}
- 8、strlen:计算字符串 string 的长度,直到空结束字符,但不包括空结束字符
size_t func_strlen(char *string)
{
int length = 0;
while(*string++ != '\0')
{
length++;
}
return length;
}
- 9、strstr:在字符串 str1中查找第一次出现字符串 str2的位置
char *func_strstr(const char *str1, const char *str2)
{
char *cp = str1;
char *s1;
char *s2;
if(!*str2)
{
return str1;
}
while(*cp)
{
s1 = cp;
s2 = str2;
while(*s1 && *s2 && !(*s1 - *s2))
{
s1++;
s2++;
}
if(!*s2)
{
return cp;
}
cp++;
}
return NULL;
}
- 10、strtok:分解字符串 string,control为分隔符
char *func_strtok(char *string, const char *control)
{
char *str;
const char *ctrl = control;
char map[32]; /*256个字符隐射到32个8bit的数组,一位可以代表一个字符*/
int cnt;
static char *nexttoken;
for(cnt = 0; cnt < 32; cnt++)
{
map[cnt] = 0;
}
do /*间隔符存储到map数组,可以是多个间隔符*/
{
/* *ctrl>>3 表示map中8个一组,8个字符同时隐射在map中一个位置,如 A:65 B:66等都隐射在map[8]中*/
/* *ctrl&7 表示取除8的余数,每一位代表一个字母,所以0x01左移对应的n位*/
map[*ctrl >> 3] |= (0x01<<(*ctrl & 7));
}while(*ctrl++);
if(NULL != string)
{
str = string;
}
else
{
str = nexttoken; /*如果string=null,从上次分隔后的位置开始*/
}
while((map[*str >> 3] & (0x01 << (*str & 7))) && *str)
{
str++;
}/*不是分隔符直接跳出循环*/
string = str;
while(*str)
{
if(map[*str >> 3] & (0x01 << (*str & 7)))
{
*str++ = '\0'; /*检测到是分隔符,直接替换为'\0'*/
break;
}
str++;
}
nexttoken = str; /*保存指向分隔符后面的一个位置*/
if(string == str)
{
return NULL; /*没有检索到,返回null*/
}
else
{
return string;
}
}
- 11、memccpy:从src所指内存区域复制n个字节到dest所指内存区域,遇到字符ch则停止复制
void *func_memccpy(void *dest, const void *src, int ch, unsigned int cnt)
{
while(cnt && (*((char *)dest = (char *)dest + 1) - 1) =
(*((char *)src = (char *)src + 1) - 1) != (char)ch )
{
cnt--;
}
/*while 中条件相当于
if(src != ch)
{
dest = src;
dest = dest + 1;
src = src + 1;
}
为什么要-1,可以理解从dest首位置开始
*/
return (cnt ? dest : NULL);
}
- 12、memicmp:比较内存区域buf1和buf2的前n个字节,不区分大小写
int func_memicmp(const void *str1, const void *str2, unsigned int cnt)
{
int string1;
int string2;
while(cnt--)
{
if((*(unsigned char *)str1 == *(unsigned char *)str2)
|| if((string1 = TOLOWER(*(unsigned char *)str1))
== (string2 = TOLOWER(*(unsigned char *)str2))))
{
str1 = (char *)str1 + 1;
str2 = (char *)str2 + 1;
}
else
{
break;
}
}
return string1 - string2;
}