库函数的实现
(1)字符串拷贝函数strcpy()
/***********************************
实现strcpy函数
输入:char* dest,char* src
输出:dest
***********************************/
char* strcpy(char* dest, char* src)
{
if(dest == NULL || src == NULL)
return NULL;
char* tmp = dest; //因为最后要返回目标首地址,所以dest是不能改变的
while(*src != '\0'){
*tmp = *src;
tmp++;
src++;
}
*tmp = '\0';
return dest;
}
(2)指定数量的字符串拷贝函数strncpy()
/***********************************
实现strncpy函数
输入:char* dest,char* src,复制字符个数n
输出:dest
***********************************/
char* strncpy(char* dest, char* src, int n)
{
if(dest == NULL || src == NULL || n <= 0)
return NULL;
char* tmp = dest; //因为最后要返回目标首地址,所以dest是不能改变的
while(n != 0){
if(src!='\0'){
*tmp = *src;
tmp++;
src++;
n--;
}else{
*tmp = '\0'; //如果n大于源字符串的长度,需要补'\0'
tmp++;
n--;
}
}
*tmp = '\0';
return dest;
}
(3)字符串比较函数strcmp()
/***********************************
实现strcmp函数
输入:char* str1,char* str2
输出:int
若两个字符串相等,则返回0;
否则返回第一个不相等字符的差值
***********************************/
int strcmp(char* str1, char* str2)
{
if(str1 == NULL && str2 == NULL)
return 0;
if(str1 == NULL && str2 != NULL)
return -(int)(*str2);
if(str1 != NULL && str2 == NULL)
return (int)(*str1);
while(*str1 == *str2 && *str1 != '\0' && *str2 != '\0'){
str1++;
str2++;
}
//相等则为'\0'-'\0' = 0;
//不相等则为第一个不相等的字符之差
return *str1 - *str2;
}
(4)字符串衔接函数strcat()
/***********************************
实现strcat函数
输入:char* dest,char* src
输出:dest
***********************************/
char* strcat(char* dest, char* src)
{
if(dest == NULL )
return src;
if(src == NULL)
return dest;
char* tmp = dest;
while(*tmp != '\0')
tmp++;
while(*src != '\0'){ //覆盖源字符串最后的'\0'
*tmp = *src;
tmp++;
src++;
}
*tmp = '\0'; //最后需要添加'\0'
return dest;
}
(5)字符串长度
/***********************************
实现strlen函数
输入:char* str
输出:int 长度
***********************************/
int strlen(char* str)
{
if(str == NULL)
return 0;
int count = 0;
while(*str != '\0'){
count++;
str++;
}
return count; //不包括最后的'\0'
}
(6)atoi函数
重点在于:空指针判断、正负号检测、空串、非法字符、溢出
因为非法返回0,为了和值为0 的输入区分开,可以使用一个全局变量
//全局变量用来判断结果0是否为非法输入
bool validInput = false;
int atoi(char* str)
{
//空指针或者是空串为非法输入
if(str == NULL || !strcmp(str,"")){
validInput = true;
return 0;
}
//记录正负号
bool minu = false;
if(str[0] == '+')
str++;
else if(str[0] == '-'){
str++;
minu = true;
}
//只有一个正负号的时候,也是非法输入
if(*str == '\0'){
validInput = true;
return 0;
}
long result = 0; //用long保存int,这样更好判断溢出
while(*str != '\0'){
if( *str < '0' || *str >'9'){
validInput = true;
return 0;
}
result = result * 10 + (*str - '0');
str++;
if(( !minu && result > 0x7FFFFFFF) ||( minu && (-result) < 0x80000000)){
validInput = true;
return 0;
}
}
if(minu){
return -(int)result;
}else
return (int)result;
}
(7)pow函数
实现double Power(double base, int exponent);
需要考虑的问题:
-------exponent为负数的情况:取绝对值进行计算,最后去倒数即可
-------base为0,exponent为负数:设置全局变量同时返回0
-------效率:n为偶数:a^n = a^(n/2) * a^(n/2);n为奇数:a^n = a*a^((n-1)/2) * a^((n-1)/2);
bool invalid_input = false ;
//小数之间不能用==判断
bool equals(double num1, double num2)
{
if(abs(num1-num2)<0.0000001)
return true;
else
return false;
}
//优化效率
double powerCore(double base, int n)
{
if(n == 1)
return base;
double res = powerCore(base, n>>1);
res *= res;
if( n%2 == 1)
res *= base;
return res;
}
double power(double base, int exponent)
{
bool minu = false;
if(equals(base, 0.0) && exponent < 0){
invalid_input = true;
return 0.0;
}
if(exponent == 0){
return 1.0;
}
if(exponent < 0){
exponent = -exponent;
minu = true;
}
double result = 1.0;
result = powerCore(base, exponent);
if(minu == true)
return 1.0 / result;
else
return result;
}
(8)求平方根函数(leetcode69)
利用二分法查找
int mySqrt(int x) {
if(x <= 0)return 0;
int start = 0;
int end = INT_MAX;
while(start <= end){
int mid = start + (end - start) / 2;
if(mid == x / mid)return mid;
else if(mid < x / mid && (mid+1) > x / (mid+1))return mid;
else if(mid < x / mid )start = mid+1;
else end = mid-1;
}
}