出处http://blog.csdn.net/jiange_zh
前言
在面试中,常常会被问到几个库函数的实现,虽然代码很短,涉及的细节却特别多,因此特别受面试官青睐,所以要把他们熟记于心,方能应对自如。
strcpy()
原型声明:char strcpy(char dest, const char *src);
功能:把从src地址开始且含有NULL结束符的字符串复制到以dest开始的地址空间
说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
返回指向dest的指针。
#include <assert.h>
char *strcpy(char* dest, const char *src)
{
assert(NULL != dest && NULL != src);
char * temp = dest;
while ((*temp++ = *src++) != '\0');
return dest;
}
链式的例子:
int length = strlen(strcpy(strA, strB));
strncpy()
strcpy()是一个高危函数,因为没有指定复制的大小,当dest的空间比src小时,就会出错,而我们没法进行控制。于是有了比较安全的strncpy():
#include <assert.h>
char *strncpy(char* dest, const char *src, unsigned int n)
{
assert(NULL != dest && NULL != src);
char * temp = dest;
while (n-- > 0 && (*temp++ = *src++) != '\0');
while (n-- > 0) *temp++ = '\0';
return dest;
}
strcmp()
比较两个字符串
设这两个字符串为str1,str2,
若str1==str2,则返回零;
若str1>str2,则返回正数;
若str1
#include <assert.h>
int strcmp(const char *str1, const char *str2)
{
assert(NULL != str1 && NULL != str2);
while(*str1 && *str2 && *str1 == *str2)
{
str1++;
str2++;
}
return *str1 - *str2;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
strcat()
把src所指字符串添加到dest结尾处(覆盖dest结尾处的’\0’)。
char *strcat(char *dest,const char *src)
{
assert(NULL != dest && NULL != src);
char *temp = dest;
while ('\0' != *temp)
++temp;
while ((*temp++ = *src++) != '\0');
return dest;
}
strlen()
功能:计算给定字符串的(unsigned int型)长度,不包括’\0’在内
说明:返回s的长度,不包括结束符NULL。
unsigned int strlen(const char *s)
{
assert(NULL != s);
unsigned int len = 0;
while (*s++ != '\0')
++len;
return len;
}
memset()
void *memset(void *s, int ch, size_t n);
函数解释:将s中前n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s 。
memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法。
注意,memset是以【字节】为单位进行赋值的,因此下面用法将导致错误:
int arr[5];
memset(array,1,sizeof(arr));
arr指向5个字节的空间,每个都用ASCII为1的字符去填充,转为二进制后,1就是00000001,占一个字节。一个INT元素是4字节,合一起就是00000001000000010000000100000001,就等于16843009,就完成了对一个INT元素的赋值了。所以上面结果不是1而是16843009!
void *memset(void *s,int c,unsigned int n)
{
assert(NULL != s);
void *temp = s;
while (n--)
{
*(char *temp) = (char)c;
temp = (char *)temp + 1;
}
return s;
}
memcpy()
内存拷贝函数,memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。
void *memcpy(void *dest, const void *src, size_t n)
{
assert(NULL != dest && NULL != src);
int i = 0;
void *temp = dest;
while (i < n)
{
*((char *)temp + i) = *((char *)src + i);
++i;
}
return dest;
}
atoi()
这个函数就比较经典了,面试常常出现,因为可以考察各种特殊情况:空指针、空串、正负号、非法字符、溢出等等。
最大的int:0x7FFF FFFF;
最小的int:0x8000 0000;
enum = {Invalid = 0, Valid};
bool errno = Invalid;
int atoi(const char * str)
{
long long num = 0;
errno = Invalid;
if (NULL != str && *str != '\0')
{
bool minus = false;
if (*str == '+')
{
++str;
}
else if (*str == '-')
{
++str;
minus = true;
}
if ('\0' != *str)
atoiCore(str, minus, num);
}
return (int)num;
}
void atoiCore(const char *str, bool minus, long long &num)
{
while ('\0' != *str)
{
if (*str >= '0' && *str <= '9')
{
num = num*10 + (*str) - '0';
++str;
if ((!minus && num > 0x7FFFFFFF)||(minus && (-num) < (signed int)0x80000000))
{
errno = Invalid;
num = 0;
return;
}
}
else
{
errno = Invalid;
num = 0;
return;
}
}
if (minus)
num = -num;
errno = Valid;
}