乐趣区

关于c:跟着Redis学编程之字符串转长整数

前言

作为 C 语言根底,在面试的时候,常常会被要求实现数值到字符串、或者字符串到数值的转换函数。尽管难度不大,然而很容易在一些细节上呈现纰漏。刚好最近在深度剖析 Redis7.0 源代码。空闲之余,顺带把这部分代码摘录进去,进行剖析、注解。
作为一个学习记录的同时也不便后来者疾速理解 Redis 外部是如何实现的。日后面试兴许能用的上。

Redis 实现形式

代码片段正文


int string2ll(const char *s, size_t slen, long long *value) {
    const char *p = s; // 指向 s 开始地位
    size_t plen = 0;   //
    int negative = 0;  // 正数
    unsigned long long v;

    /* 如果传递示意字符串长度参数为 0,则无需转换,间接返回 0 */
    if (plen == slen)
        return 0;

    /* 非凡状况,只有一个字符,并且是 0 字母 */
    if (slen == 1 && p[0] == '0') {if (value != NULL) *value = 0;
        return 1;
    }

    /* 字符串可能是示意带符号的整数,那么须要先解决符号。*/
    /* 解决正数:仅仅是设置负号,而后就相似负数的解决形式进行解决 . 结束后转换成正数 */
    if (p[0] == '-') {
        negative = 1;
        p++; plen++;

        /* 只有负号,即字符串是这样:"-", 这种字符串间接,异样退出 */
        if (plen == slen)
            return 0;
    }

    /* 第一个字符必须是 1 -9,否则字符串应该是 0 */
    if (p[0] >= '1' && p[0] <= '9') {v = p[0]-'0';// 转成整数
        p++; plen++;
    } else {return 0;}

    /* 剖析剩下的所有字符,并且每一个步都查看是否溢出。如果遇到非字符,则循环退出:p[0] <'0' || p[0] > '9'
       字符串剖析结束,则循环退出:plen >= slen  */
    while (plen < slen && p[0] >= '0' && p[0] <= '9') {if (v > (ULLONG_MAX / 10)) /* 先判断溢出,在累加。如果计算后再判断,这时候曾经溢出掉了. */
            return 0;
        v *= 10;

        if (v > (ULLONG_MAX - (p[0]-'0'))) /* 情理同上,这里咱们能够借鉴:判断溢出的形式. */
            return 0;
        v += p[0]-'0';

        p++; plen++;
    }

    /* 还有字符没有解决完,到这里其实就是下面的 while 循环条件,p[0] 不是 0 - 9 的数字 */
    if (plen < slen)
        return 0;

    /* 转换为正数,并且要查看溢出 */
    /* 整个转换都是应用 unsigned long long 作为长期值,最初保留的后果是有符号的,须要转换为
     * long long,这样在赋值和正数转变时候须要做溢出判断。*/
    if (negative) {if (v > ((unsigned long long)(-(LLONG_MIN+1))+1)) /* 溢出检查 */
            return 0;
        if (value != NULL) *value = -v;
    } else {if (v > LLONG_MAX) /* 溢出检查. */
            return 0;
        if (value != NULL) *value = v;
    }
    return 1;
}

代码逻辑剖析小结

string2ll 整体思路是:解决符号,而后一一字符进行转换,从第一个字符开始转换,每一次转换都判断本次转换后的后果是否溢出,如果溢出就返回转换失败,否则就转换胜利,持续遍历下一个字符。

疑难 & 思考

这个函数在 Redis 外部作为工具函数,用的挺好的,然而如果用来应酬找工作面试,预计是不合格的了。
为什么?您晓得么?

这里就无妨提出几个问题,抛砖引玉:
1,指针参数,肯定是无效的么?
2,字符串带空格怎么办?这个函数间接是转换失败,然而如果容许前后带空格呢?怎么批改?
3,是否存在优化空间?第一个字符须要独自判断么?是否一个循环间接解决?
还有么?留给读者本人思考下 ^_^。

退出移动版