通常要考虑这几个方面
参数中的源数据,目标空间
返回值
空间是否足够
源数据与目标空间是否有重叠
以下是自己写的,有些没验证,估计有BUG
strlen
size_t strlen(char const *str)
{
int len=0;
while(*str++!='\0')// strlen不计算\0,sizeof则需要计算//\0可以省去
len++;
return len;
}
strcpy
char* strcpy(char *dst,char const *src)
{
char *r=dst;
while((*d++=*s++)!='\0');//\0可以省去
return r;
}
strncpy
char* strncpy(char *dst,char const *src,size_t n)
{
char *r=dst;
int i=0;
while(i++<n&&(*dst++=*src)!='\0');// strncpy如果COPY数目到n则终止,末尾可能不是\0(返回的值可能不算是字符串了)
while(i++<n)// 如果在n前已经遇到\0,则后续继续用\0填充
{
*dst++='\0';
}
return r;
}
strcat
char* strcat(char *dst,char const *src)
{
char *r=dst;
while(*dst)// 找到\0位置
{
*dst++;
}
while(*dst++=*src++);
return r;
}
strncat
char* strncat(char *dst,char const *src,size_t n)
{
char *r=dst;
while(*dst)// 找到\0位置
{
dst++;
}
int i=0;
while(i++<n&&*dst=*src++)
{
if(*dst=='\0')break;// 保证dst指向需要追加的\0位置
dst++;
}
*dst='\0';// 如果是到n则最后添加\0,如果是遇到\0 break,再覆盖一次
return r;
}
strcmp
int strcmp(char const *s1, char const *s2)
{
while (*s1==*s2)
{
if(*s1=='\0')
return 0;
s1++;
s2++;
}
// return *s1-*s2;// 不同编译器可能不一样
return *s1<*s2?-1:1;
}
strncmp
int strncmp(char const *s1, char const *s2,size_t n)
{
int i=0;
while(i++<n)
{
if(*s1!=*s2)
return *s1-*s2;
s1++;
s2++;
}
return 0;
}
strchr
char* strchr(char const *s,char c)
{
while(*s != '\0' && *s != c)
{
s++;
}
return *s == c ?s:NULL;
}
strpbrk
char * strpbrk(const char * cs,const char * ct)
{
const char *sc1,*sc2;
for( sc1 = cs; *sc1 != '\0'; ++sc1) {
for( sc2 = ct; *sc2 != '\0'; ++sc2) {
if (*sc1 == *sc2)
return (char *) sc1;
}
}
return NULL;
}
strstr
char * strstr (const char * str1, const char * str2)// 朴素字符串匹配算法
{
char *cp = (char *) str1;
char *s1, *s2;
if ( !*str2 )
return((char *)str1);
while (*cp)
{
s1 = cp;
s2 = (char *) str2;
while ( *s1 && *s2 && !(*s1-*s2) )
s1++, s2++;
if (!*s2)
return(cp);
cp++;
}
return NULL;
}
strspn返回字符串中第一个不在指定字符串中出现的字符下标
size_t strspn (const char *s,const char * accept);
strcspn返回字符串s1中第一个在s2中出现的字符的下标值
size_t strcspn(const char *s1,const char *s2);
strtok分解字符串为一组字符串。s为要分解的字符串,delim为分隔符字符串
char *strtok(char s[], const char *delim);// strtok会修改源数据
memcpy
void * memcpy(void *dst, const void *src, size_t n)
{
void *ret=dst;
while (n--) {
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
return ret;
}
memset
void * memset(void *s, int ch, size_t n)
{
void *ret=s;
while(n--)
{
*(char*)s=(char)ch;
s=(char*)s+1;
}
return ret;
}
memmove
memcmp
memchr
atoi
atol
strtol
strtoul
assert是<assert.h>中的宏,当定义了#define NDEBUG后会关闭assert调试
void *malloc(size_t size);
void free(void* ptr);
void *calloc(size_t num_elements,size_t element_size);//分配的同时会将元素置0,参数设定的方式不同
void *realloc(void*ptr,size_t new_size);// 可以调整原来申请的空间大小 ,如果原内存不能修改大小,则会分配新的内存,第一个参数置为NULL,即malloc的作用
常量区的使用,指针操作,数组操作都可以
putchar("0123456789ABCDEF"[value%16]);// 转换16进制数输出的一行代码搞定