面试常考小函数

 

在程序员面试的时候,面试官通常会让你实现一个或几个C语言里的库函数,以此来检查你的编程功底。类似的函数实现有atoi.itoa.atof.strcmp.strcpy.memset.memcpy等等。

 

————————————————————————————strcpy---------------------------------------------------------------------

/**

 * strcpy - Copy a %NUL terminated string

 * @dest: Where to copy the string to

 * @src: Where to copy the string from

 */

char *strcpy(char *dest, const char *src)

{

assert((dest != NULL) && (src != NULL));

char *tmp = dest;

 

while ((*dest++ = *src++) != '/0')

/* nothing */;

return tmp;

}

————————————————————————————strcmp---------------------------------------------------------------------

/**

 * strcmp - Compare two strings

 * @cs: One string

 * @ct: Another string

 */

int strcmp(const char *cs, const char *ct)

{

signed char __res;

 

while (1) {

if ((__res = *cs - *ct++) != 0 || !*cs++)

break;

}

return __res;

}

 

int strcmp(const char* src,const char* dst) 

    int ret = 0; 

    if (src == dst) 

    { 

        return 0; 

    } 

    assert(NULL != src);//期待源字符串不为空 

    if (dst == NULL) 

    { 

        return -1; 

    } 

    while (!(ret = *(unsigned char*)src - *(unsigned char*)dst)&& *dst) 

    { 

        ++src,++dst; 

    } 

    if (ret < 0) 

    { 

        ret = -1; 

    } 

    else if (ret > 0) 

    { 

        ret = 1; 

    } 

    return ret; 

}

————————————————————————————memcpy---------------------------------------------------------------------

/**

 * memcpy - Copy one area of memory to another

 * @dest: Where to copy to

 * @src: Where to copy from

 * @count: The size of the area.

 *

 * You should not use this function to access IO space, use memcpy_toio()

 * or memcpy_fromio() instead.

 */

void *memcpy(void *dest, const void *src, size_t count)

{

char *tmp = dest;

const char *s = src;

 

while (count--)

*tmp++ = *s++;

return dest;

}

 

void* memcpy(void* dst,const void* src,size_t count) 

    char* pbTo = (char*)dst; //防止改变dst的地址

    char* pbFrom = (char*)src; 

    assert(dst!= NULL && src != NULL); 

    assert(pbTo >= pbFrom+count || pbFrom >= pbTo + count);//防止内存重叠(overlap) 

    while (count-- > 0) 

    { 

        *pbTo++ = *pbFrom++; 

    } 

    return dst; 

}

 

------------------------------------------------------memmove---------------------------------------------------------------------

 

void* memmove(void* dst,const void* src,size_t count) 

    char* pbTo = (char*)dst; 

    char* pbFrom = (char*)src; 

    assert(dst != NULL && src != NULL); 

    if (dst <= src || pbTo >= pbFrom + count)//没有overlap的情况,直接拷贝 

    { 

        while (count-- > 0) 

        { 

            *pbTo++ = *pbFrom++; 

        } 

    } 

    else 

    { 

        pbTo = pbTo + count -1;//overlap的情况,从高位地址向低位拷贝 

        pbFrom = pbFrom + count -1; 

        while (count-- > 0) 

        { 

            *pbTo-- = *pbFrom--; 

        } 

    } 

    return dst; 

}

 

----------------------------------------------------memset-------------------------------------------------------------------------

 

void* memset(void* buf,int c,size_t count) 

    char* pvTo = (char*)buf; 

    assert(buf != NULL); 

    while (count-- >0) 

    { 

        *pvTo++ = (char)c; 

    } 

    return buf; 

}

 

—————————————————————————————atoi---------------------------------------------------------------------

int atoi(const char *src)

{

unsigned int temp = 0;

int sign = 0;

assert(src != NULL);

 

for(;*src==' ';src++); /* 跳过空白字符 */

 

sign= (*src == '-') ? -1 : 1;

if ('-' == *src || '+' == *src) 

src++; 

 

if(*src == '0' && *++src == 'x')

{

while(*src++ != '/0')

{

if(*src - '0' >= 0 && *src - '0' <= 9)

temp = temp*16 + (*src - '0');

else if(*src - 'a' >=0 && *src - 'a' <= 5)

temp = temp*16 + 10 + (*src - 'a');

}

return sign*temp;

}

 

else if(*src - '0' > 0 && *src - '0' <= 9)

{

while(*src != '/0')

{

if(*src - '0' >= 0 && *src - '0' <= 9)

temp = temp*10 + *src - '0';

src++;

}

return sign*temp;

}

else

return sign*temp;

 

}

—————————————————————————————atof---------------------------------------------------------------------

double atof(const char* str) 

    double val = 0.0,power = 0.0; 

    int sign = 0; 

    assert(NULL != str); 

    while (*str == ' ') 

    { 

        str++; 

    } 

    sign = (*str == '-')? -1 : 1; 

    if ('-' == *str || '+' == *str) 

    { 

        str++; 

    } 

    while ((*str >= '0')&&(*str <= '9')) 

    { 

        val = val* 10.0 + (*str - '0'); str++; 

    } 

    if ('.' == *str) 

    { 

        str++; 

    } 

    power = 1.0; 

    while ((*str >= '0')&&(*str <= '9')) 

    { 

        val = val* 10.0 + (*str - '0'); 

        power *= 10; str++; 

    } 

    return sign*val/power; 

}

 

—————————————————————————————itoa---------------------------------------------------------------------

#define abs(x) ((x) < 0 ? -(x) : (x))

void reverse(char s[])

{

int c,i,j;

for (i=0,j = strlen(s)-1; i<j; i++,j--){

c = s[i];

s[i] = s[j];

s[j] = c;

}

}

void itoa(int n, char s[])

{

int i,sign;

void reverse(char s[]);

 

assert(s != NULL);

sign=n; /* record sign */

i=0;

do{

s[i++] = abs(n % 10) + '0';

}while ((n /= 10) != 0);

if (sign < 0)

s[i++] = '-';

s[i] = '/0';

reverse(s);

}

—————————————————————————————printf----------------------------------------------------------------------

#include <stdio.h>

#include <stdarg.h>

 

void myprintf(const char *format,...)

{

va_list ap;

char c;

 

va_start(ap,format);

while(c = *format++)

switch(c)

{

case 'c':

{

/* char is promoted to int when passed through */

char ch = va_arg(ap, int);

putchar(ch);

break;

}

case 's':

{

char *p = va_arg(ap, char *);

fputs(p,stdout);

break;

}

default:

putchar(c);

}

va_end(ap);

}

 

int main()

{

myprintf("c/ts/n",'l',"hello");

return 0;

}

—————————————————————————————end-------------------------------------------------------------------------

 

参考书籍:

1. c语言程序设计(K&R)

2.《高质量C/C++编程指南》,是林锐编的。

3. 程序员面试宝典

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值