在论坛中经常看到询问常用库函数的C实现的问题。其实这些实现在VC的安装目录下都能找到。如果安装了VS2005,那么它应该在Microsoft Visual Studio 2005/VC/crt/src下面。
这里是一些常见的库函数的实现示例:
long __cdecl _atol_(const char *nptr)
{
int c;
long total;
int sign; /* if '-', then negative, otherwise positive */
/* skip whitespace */
while (isspace((int)(unsigned char)*nptr)) ++nptr;
// 这是由于用到了 int = char 这种赋值,由于int 和char 的占用空间不同,
// 在char赋值int时,要进行扩充,假设int是4个字节,
// 那么需要在char前面填充3个字节然后赋值给int,然而这3个字节填充什么呢??
// 想当然的肯定是填0了,但char是有符号的,一般最高位为1表示负数,
// 如果简单的扩充,那么变成int后就成了正数了。。。
// 所以这个填充可能有不同的方式,有的编译器是看最高位吧,
// 如果为1,就全填充1,如果为0就全填充0,或者有其他的方式。
// 但对于unsigned char赋值却只用填充0就行。
c = (int)(unsigned char)*nptr++;
sign = c;
if (c == '-' || c == '+') c = (int)(unsigned char)*nptr++; /* skip sign */
total = 0;
while (isdigit(c))
{
total = 10 * total + (c - '0');
c = (int)(unsigned char)*nptr++;
}
return (sign == '-') ? -total : total;
}
int __cdecl _strcmp_(const char *src, const char *dst)
{
int ret = 0;
while (!(ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
++src, ++dst;
if (ret < 0) ret = -1;
else if (ret > 0) ret = 1;
return(ret);
}
char* __cdecl _strcpy_(char* dst, const char* src)
{
char* tmp = dst;
while ((*tmp++ = *src++) != '/0');
return dst;
}
char* __cdecl _strcat_(char *dst, const char *src)
{
char* tmp = dst;
while (*tmp++);
for (--tmp; *tmp++ = *src++;);
return dst;
}
char* __cdecl _strrev_(char *string)
{
char *start = string;
char *left = string;
while (*string++);
string -= 2;
while (left < string)
{
char ch = *left;
*left++ = *string;
*string-- = ch;
}
return(start);
}
char* __cdecl _strchr_(char *string, int ch)
{
while (string != '/0' && *string == ch) string++;
return *string == ch ? string : (char*) 0;
}
char * __cdecl _strrchr_(const char * string, int ch)
{
char *start = (char *)string;
/* find end of string */
while (*string++);
/* search towards front */
while (--string != start && *string != (char)ch);
/* char found ? */
if (*string == (char)ch) return( (char *)string );
return(NULL);
}
int __cdecl _stricmp_ (const char *dst, const char *src)
{
int f, l;
do
{
if (((f = (unsigned char)(*(dst++))) >= 'A') && (f <= 'Z'))
f -= 'A' - 'a';
if (((l = (unsigned char)(*(src++))) >= 'A') && (l <= 'Z'))
l -= 'A' - 'a';
}
while (f && (f == l));
return(f - l);
}
size_t __cdecl _strlen_(const char *str)
{
const char *eos = str;
while(*eos++);
return(eos - str - 1);
}
char * __cdecl _strstr_(const char * str1, const char * str2)
{
char *cp = (char *)str1;
char *s1 = NULL, *s2 = NULL;
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);
}
char * __cdecl _strset_(char * string, int val)
{
char *start = string;
while (*string) *string++ = (char)val;
return(start);
}
void * __cdecl _memchr_(const void * buf, int chr, size_t cnt)
{
while (cnt && (*(unsigned char *)buf != (unsigned char)chr))
{
buf = (unsigned char *)buf + 1;
cnt--;
}
return(cnt ? (void *)buf : NULL);
}
int __cdecl _memcmp_(const void * buf1, const void * buf2, size_t count)
{
if (!count) return(0);
while ( --count && *(char *)buf1 == *(char *)buf2 )
{
buf1 = (char *)buf1 + 1;
buf2 = (char *)buf2 + 1;
}
return( *((unsigned char *)buf1) - *((unsigned char *)buf2) );
}
void * __cdecl _memcpy_(void * dst, const void * src, size_t count)
{
void * ret = dst;
while (count--)
{
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
return(ret);
}
int __cdecl _memicmp_(const void * first, const void * last, size_t count)
{
int f = 0;
int l = 0;
while ( count-- )
{
if ((*(unsigned char *)first == *(unsigned char *)last) ||
((f = tolower( *(unsigned char *)first )) ==
(l = tolower( *(unsigned char *)last ))))
{
first = (char *)first + 1;
last = (char *)last + 1;
}
else
break;
}
return (f - l);
}
void * __cdecl _memmove_(void * dst, const void * src, size_t count)
{
void * ret = dst;
if (dst <= src || (char *)dst >= ((char *)src + count))
{ // copy from lower addresses to higher addresses
while (count--)
{
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
}
else
{ // copy from higher addresses to lower addresses
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);
}
void * __cdecl _memset_(void *dst, int val, size_t count)
{
void *start = dst;
while (count--)
{
*(char *)dst = (char)val;
dst = (char *)dst + 1;
}
return(start);
}