redis中有許多工具函數(shù),在這里記錄并分析一下玻粪,以后如果要寫相關(guān)函數(shù)可以直接抄
字符串轉(zhuǎn)long long
// 把s轉(zhuǎn)為longlong型存在value
// 成功返回1,失敗返回0
int string2ll(const char *s, size_t slen, long long *value) {
const char *p = s;
size_t plen = 0;
int negative = 0;//是否負(fù)數(shù)
unsigned long long v;
// s長度為0拂玻,直接返回0
if (plen == slen)
return 0;
/****************************************這里開始解析第一位********************************/
/* 長度為1并且第一位為0互纯,直接返回0 */
if (slen == 1 && p[0] == '0') {
if (value != NULL) *value = 0;
return 1;
}
/* 第一位為- 汽馋,負(fù)數(shù),*/
if (p[0] == '-') {
negative = 1;
p++; plen++;
/*防止s就是一個(gè)減號(hào) */
if (plen == slen)
return 0;
}
/* 第一位是正常的數(shù)字粱年,向后解析 */
if (p[0] >= '1' && p[0] <= '9') {
v = p[0]-'0';
p++; plen++;
/* 第一位是其他奇怪的符號(hào)售滤,直接返回退出了 */
} else {
return 0;
}
/****************************************第一位解析完畢********************************/
// 此時(shí)p指向第二位,plen=1
while (plen < slen && p[0] >= '0' && p[0] <= '9') {
// 要對溢出敏感,每次增大的時(shí)候判斷是否溢出
if (v > (ULLONG_MAX / 10)) /* Overflow. */
return 0;
v *= 10;
if (v > (ULLONG_MAX - (p[0]-'0'))) /*同樣判斷是否溢出 */
return 0;
v += p[0]-'0';
p++; plen++;
}
/* 循環(huán)結(jié)束沒有遍歷道最后完箩,錯(cuò)誤 */
if (plen < slen)
return 0;
// 處理負(fù)數(shù)情況
if (negative) {
if (v > ((unsigned long long)(-(LLONG_MIN+1))+1)) /* Overflow. */
return 0;
if (value != NULL) *value = -v;
} else {
if (v > LLONG_MAX) /* Overflow. */
return 0;
if (value != NULL) *value = v;
}
return 1;
}