我要好offer之 str/mem系列手写代码

1. str*系列手写代码

a. 一定要注意末尾‘\0‘的处理,切记切记

b. 一定要对输入做有效性判断,多用断言就是了

int Strlen(const char* str) {
    assert(str != NULL);
    const char* tmp = str;
    while (*tmp != ‘\0‘) {
        ++tmp;
    }
    return tmp - str;
}

char* Strcpy(char* dst, const char* src) {
    assert(dst != NULL && src != NULL);
    char* tmp = dst;
    while (*src != ‘\0‘) {
        *tmp++ = *src++;
    }
    *tmp = ‘\0‘;
    return dst;
}

char* Strncpy(char* dst, const char* src, int len) {
    assert(dst != NULL && src != NULL && len >= 0);
    char* tmp = dst;
    for (; len > 0 && *src != ‘\0‘; --len) {
        *tmp++ = *src++;
    }
    for (; len > 0; --len) {
        *tmp ++ = ‘\0‘;
    }
    return dst;
}

char* Strcat(char* dst, const char* src) {
    assert(dst != NULL && src != NULL);
    char* tmp = dst;
    while (*tmp != ‘\0‘) {
        ++tmp;
    }
    while (*src != ‘\0‘) {
        *tmp++ = *src++;
    }
    *tmp = ‘\0‘;
    return dst;
}

char* Strncat(char* dst, const char* src, int len) {
    assert(dst != NULL && src != NULL && n >= 0);
    char* tmp = dst;
    while (*tmp != ‘\0‘) {
        ++tmp;
    }
    for (; len > 0 && *src != ‘\0‘; --len) {
        *tmp++ = *src++;
    }
    *tmp = ‘\0‘;
    return dst;
}

int Strcmp(const char* str1, const char* str2) {
    assert(str1 != NULL && str2 != NULL);
    for (; *str1 == *str2; ++str1, ++str2) {
        if (*str1 == ‘\0‘) {
            return 0;
        }
    }
    if (*(unsigned char*)str1 < *(unsigned char*)str2) {
        return -1;
    } else {
        return 1;
    }
}

int Strncmp(const char* str1, const char* str2, int len) {
    assert(str1 != NULL && str2 != NULL && len >= 0);
    for (; len > 0; ++str1, ++str2) {
        if (*str1 != *str2) {
            return ((*(unsigned char*)str1) < (*(unsigned char*)str2) ? -1 : 1);
        } else if (*str1 == ‘\0‘) {
            return 0;
        }
    }
    return 0;
}

char* Strchr(const char* str, int c) {
    assert(str != NULL);
    const char* tmp = str;
    const char ch = (const char)c;
    for (; *tmp != ch; ++tmp) {
        if (*tmp == ‘\0‘) {
            return NULL;
        }
    }
    return (char*)tmp;
}

char* Strstr(const char* str1, const char* str2) {
    assert(str1 != NULL && str2 != NULL);
    if (*str2 == ‘\0‘) return str1;
    const char* tmp1 = str1;
    const char* tmp2 = str2;
    int len1 = Strlen(str1);
    int len2 = Strlen(str2);
    int i = 0;
    for (tmp1 = str1; i <= len1 - len2 && *tmp1 != ‘\0‘; ++tmp1, ++i) {
        if (*tmp1 != *tmp2)
            continue;
        const char* cur1 = tmp1;
        const char* cur2 = tmp2;

        while (*cur1 == *cur2) {
            ++cur1;
            ++cur2;
            if (*cur2 == ‘\0‘) {
                return (char*)tmp1;
            }
        }
    }
    return NULL;
}

2. mem系列手写代码

一定要对输入做有效性判断,多用断言就是了

void* Memchr(const void* src, int c, int len) {
    assert(src != NULL && len >= 0);
    const unsigned char ch = c;
    const unsigned char* tmp = (const unsigned char*)src;
    for (; len > 0; --len, ++tmp) {
        if (*tmp == ch) {
            return (void*)tmp;
        }
    }
    return NULL;
}

int Memcmp(const void* s1, const void* s2, int len) {
    assert(s1 != NULL && s2 != NULL);
    const unsigned char* tmp1 = (const unsigned char*)s1;
    const unsigned char* tmp2 = (const unsigned char*)s2;
    for (; len > 0; --len, tmp1++, tmp2++) {
        if (*tmp1 != *tmp2) {
            return ((*tmp1 < *tmp2) ? -1 : 1);
        }
    }
    return 0;
}

void* Memcpy(void* dst, const void* src, int len) {
    assert(dst != NULL && src != NULL && len >= 0);
    char* dstTmp = (char*)dst;
    const char* srcTmp = (const char*)src;
    for (; len > 0; --len, ++dstTmp, ++srcTmp) {
        *dstTmp = *srcTmp;
    }
    return dst;
}

void* Memmove(void* dst, const void* src, int len) {
    assert(dst != NULL && src != NULL && len >= 0);
    char* dstTmp = (char*)dst;
    const char* srcTmp = (const char*)src;
    if (dstTmp > srcTmp && dstTmp < srcTmp + len) {
        for (srcTmp += n, dstTmp += n; len > 0 ; --len, --srcTmp, --dstTmp) {
            *dstTmp = *srcTmp;
        }
    } else {
        for (; len > 0; --len, ++srcTmp, ++dstTmp) {
            *dstTmp = *srcTmp;
        }
    }
    return dst;
}

3. atoi函数

http://www.cnblogs.com/wwwjieo0/p/3687534.html

class Solution {
public:
    int atoi(const char *str) {
        assert(str != NULL);
        const char* curr = str;
        const int maxRange = 10;
        int tmp = 0;
        int num = 0;
        while(isspace(*curr)) {
            ++curr;
        }
        const char* start = nullptr;
        char sign;
        if (*curr == ‘-‘ || *curr == ‘+‘) {
            sign = *curr;
            ++curr;
            start = curr;
        }  else {
            start = curr;
        }

        while (isdigit(*curr)) {
            tmp = num;
            num = num * 10 + (*curr - ‘0‘);
            ++curr;
        }
        int len = 0;
        if (!isdigit(*curr)) {
            len = curr - start;
        }
        --curr;
        if (len > maxRange || num < num - *curr) {
            if (sign == ‘-‘) {
                return INT_MIN;
            } else {
                return INT_MAX;
            }
        }
        if (sign == ‘-‘)  num = -num;
        return num;
    }
};

我要好offer之 str/mem系列手写代码,布布扣,bubuko.com

时间: 2024-10-03 14:45:12

我要好offer之 str/mem系列手写代码的相关文章

UI到底应该用xib/storyboard完成,还是用手写代码来完成?

UI到底应该用xib/storyboard完成,还是用手写代码来完成? 文章来源:http://blog.csdn.net/libaineu2004/article/details/45488665 参考文章: <关于代码手写UI,xib和StoryBoard> http://blog.csdn.net/likendsl/article/details/38731333 <代码手写UI,xib和StoryBoard间的博弈,以及Interface Builder的一些小技巧> ht

如果选择构建ui界面方式,手写代码,xib和StoryBoard间的博弈

代码手写UI这种方法经常被学院派的极客或者依赖多人合作的大型项目大规模使用. 大型多人合作项目使用代码构建UI,主要是看中纯代码在版本管理时的优势,检查追踪改动以及进行代码合并相对容易一些. 另外,代码UI可以说具有最好的代码重用性.如果你的目的是写一些可以高度重用的控件提供给其他开发者使用,那毫无疑问最好的选择应该是使用代码来完成UIView的子类.这样进一步的修改和其他开发者在使用时,都会方便不少.使用代码也是最为强大的,会有xib或者StoryBoard做不了的事情,但是使用代码最终一定能

手写代码UI,xib和StoryBoard间的的优劣比较

在UI制作方面,逐渐分化三种主要流派:使用代码手写UI:使用单个xib文件组织viewController或者view:使用StoryBoard来通过单个或很少的几个文件构建UI.三种方式各有优劣,也各有自己最适用的场合. 一.手写代码UI 1.优势 √  适合大型项目大规模使用,利于版本管理.追踪改动以及代码合并 √  最好的代码重用性 2.遗憾 √  慢,开发周期长,维护代码复杂 √  自动布局AutoLayout困难 二.xib文件组织viewController或者view 1.优势 √

.netER的未来路,关于基础是否重要和应该自己手写代码吗?

http://www.cnblogs.com/onepiece_wang/p/5558341.html#!comments 引用"基础知识的学习,一开始可能是背书,但是在后续若干年的工作过程中,在写代码时有没有想过为什么代码要写成这样子." 谁没有去想过呢?我深究过,但后来放弃了,原因很简单,因为我深究后发现,1+1等于2 苹果就是叫苹果.我去思考1+1为什么等于2 苹果为什么叫苹果.研究透后才发现只是多此一举,很浪费时间也没有实质性的作用.因为他就叫那个苹果名字,1+1就是等于2,我

iOS UICollectionView手写代码实现步骤

// //  ViewController.h //  collectionView手写代码 // //  Created by yangxiuying on 14/11/28. //  Copyright (c) 2014年 lanjiying. All rights reserved. // #import <UIKit/UIKit.h> @interface ViewController : UIViewController<UICollectionViewDataSource,U

手写代码自动实现自动布局,即Auto Layout的使用

手写代码自动实现自动布局,即Auto Layout的使用,有需要的朋友可以参考下. 这里要注意几点: 对子视图的约束,若是基于父视图,要通过父视图去添加约束. 对子视图进行自动布局调整,首先对UIView的一个属性设置,这是因为如果我们用Interface Builder,勾选Ues Autolayout,这时autoresizingMask就会被Auto Layout 取代,在手写代码时,我们就需要手动控制,代码如下 [_shadow setTranslatesAutoresizingMask

Appium初始化设置:手写代码连接手机、appium-desktop连接手机

一.包名获取的三种方式 1)找开发要2)mac使用命令:adb logcat | grep START win使用命令:adb logcat | findstr START 查看包名和入口如下: 3)通过aapt命令查看 cmd到你的android-sdk-windows\build-tools\28.0.3路径下,可以看到aapt 注意:mac使用ls,win使用dir命令 win使用命令  aapt dump badging C:\Users\Yangfan\Desktop\mobileqq

2019秋招复习笔试--手写代码

1. 手写一个单例模式 2. 手写一个生产者消费者模式 3. 手写一个LRU算法的实现: 4. 手写快排 5. 手写堆排 6. 手写树的遍历(先序.中序.后序.层序) 7. 手写一个二分查找 #. 剑指OFFER #. LeetCode 原文地址:https://www.cnblogs.com/greatLong/p/11505100.html

【前端面试】同学,你会手写代码吗?

CSS 部分 两栏布局 要求:垂直两栏,左边固定右边自适应. 查看代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-e