对下面代码的一些细节,解释下为什么那么做。
1.
char buf[sizeof(int) * 8 + 1] = "";
这个buf的作用是缓存中间结果,长度没有写死。好处是不同的平台上这段代码都可以执行。
2.
if (base < 2 || base > 36)
该判断检查用户传入的进制数是否合法。base < 2 主要过滤负数和0和1。base > 36的意义是在超过10进制的数里,是用字母a表示10的。以此类推z可以表示36。在只使用ascii字符表示大于10的数时,最大的表示值是36,超过这个值就不能表示。
3.
uval = -val;
这各写法可以避免一个潜在的坑。当val为int值为INT_MIN时 -val会溢出。表象为-val 的值还是INT_MIN,还是个负数
4.至于为什么用一个无符号整数与一个>0的int进行整除与取余
uval % base uval /= base
因为c语言的标准里没有规定x / y当有一个值为负数时,结果该向x坐标轴的左侧靠近(向0取整) 还是向侧靠近(负无穷)
它只规定了 (x / y) * y + (x % y) = x
-14 /5 的结果可以是 -2 或者 -3
至为正数为啥没有两个结果。本人只是用了几个值进行了验证。。
好了贴代码:
#include <stdio.h> #include <limits.h> #include <assert.h> #include <string.h> char *int2str(int val, char *str, int base) { static char tab[] = "0123456789abcdefghijklmnopqrstuvwxyz"; char buf[sizeof(int) * 8 + 1 + 1] = ""; char *p = buf; char *p2 = str; unsigned uval = val; //检查base的范围 if (base < 2 || base > 36) { *str = ‘\0‘; return str; } //负数 uval = val; if (val < 0 && base == 10) { uval = -val; } do { *p++ = tab[uval % base]; //printf("%d:%d:%d\n", uval, uval % base, base); } while (uval /= base); if (val < 0 && base == 10) { *p++ = ‘-‘; } p--; while (p >= buf && (*p2++ = *p) != ‘\0‘) p--; *p2 = ‘\0‘; return str; } void tst_max_2() { char buf_int2str[34] = ""; printf("max 2#%s\n", int2str(CHAR_MAX, buf_int2str, 2)); printf("max 2#%s\n", int2str(SHRT_MAX, buf_int2str, 2)); printf("max 2#%s\n", int2str(INT_MAX, buf_int2str, 2)); } void tst_max_8() { char buf_int2str[34] = ""; printf("max 8#%s\n", int2str(CHAR_MAX, buf_int2str, 8)); printf("max 8#%s\n", int2str(SHRT_MAX, buf_int2str, 8)); printf("max 8#%s\n", int2str(INT_MAX, buf_int2str, 8)); } void tst_max_10() { char buf_int2str[34] = ""; char buf_snprintf[34] = ""; snprintf(buf_snprintf, sizeof(buf_snprintf), "%d", CHAR_MAX); assert(!strcmp(int2str(CHAR_MAX, buf_int2str, 10), buf_snprintf)); printf("max 10#%d:%s:%s\n", CHAR_MAX, buf_int2str, buf_snprintf); snprintf(buf_snprintf, sizeof(buf_snprintf), "%d", SHRT_MAX); assert(!strcmp(int2str(SHRT_MAX, buf_int2str, 10), buf_snprintf)); printf("max 10#%d:%s:%s\n", SHRT_MAX, buf_int2str, buf_snprintf); snprintf(buf_snprintf, sizeof(buf_snprintf), "%d", INT_MAX); assert(!strcmp(int2str(INT_MAX, buf_int2str, 10), buf_snprintf)); printf("max 10#%d:%s:%s\n", INT_MAX, buf_int2str, buf_snprintf); } void tst_max_16() { char buf_int2str[34] = ""; char buf_snprintf[34] = ""; snprintf(buf_snprintf, sizeof(buf_snprintf), "%x", CHAR_MAX); assert(!strcmp(int2str(CHAR_MAX, buf_int2str, 16), buf_snprintf)); printf("max 16#%d:%s:%s\n", CHAR_MAX, buf_int2str, buf_snprintf); snprintf(buf_snprintf, sizeof(buf_snprintf), "%x", SHRT_MAX); assert(!strcmp(int2str(SHRT_MAX, buf_int2str, 16), buf_snprintf)); printf("max 16#%d:%s:%s\n", SHRT_MAX, buf_int2str, buf_snprintf); snprintf(buf_snprintf, sizeof(buf_snprintf), "%x", INT_MAX); assert(!strcmp(int2str(INT_MAX, buf_int2str, 16), buf_snprintf)); printf("max 16#%d:%s:%s\n", INT_MAX, buf_int2str, buf_snprintf); } void tst_min_2() { char buf_int2str[34] = ""; printf("min 2#%s\n", int2str(CHAR_MIN, buf_int2str, 2)); printf("min 2#%s\n", int2str(SHRT_MIN, buf_int2str, 2)); printf("min 2#%s\n", int2str(INT_MIN, buf_int2str, 2)); } void tst_min_8() { char buf_int2str[34] = ""; printf("min 8#%s\n", int2str(CHAR_MIN, buf_int2str, 8)); printf("min 8#%s\n", int2str(SHRT_MIN, buf_int2str, 8)); printf("min 8#%s\n", int2str(INT_MIN, buf_int2str, 8)); } void tst_min_10() { char buf_int2str[34] = ""; char buf_snprintf[34] = ""; snprintf(buf_snprintf, sizeof(buf_snprintf), "%d", CHAR_MIN); assert(!strcmp(int2str(CHAR_MIN, buf_int2str, 10), buf_snprintf)); printf("min 10#%d:%s:%s\n", CHAR_MIN, buf_int2str, buf_snprintf); snprintf(buf_snprintf, sizeof(buf_snprintf), "%d", SHRT_MIN); assert(!strcmp(int2str(SHRT_MIN, buf_int2str, 10), buf_snprintf)); printf("min 10#%d:%s:%s\n", SHRT_MIN, buf_int2str, buf_snprintf); snprintf(buf_snprintf, sizeof(buf_snprintf), "%d", INT_MIN); assert(!strcmp(int2str(INT_MIN, buf_int2str, 10), buf_snprintf)); printf("min 10#%d:%s:%s\n", INT_MIN, buf_int2str, buf_snprintf); } void tst_min_16() { char buf_int2str[34] = ""; char buf_snprintf[34] = ""; snprintf(buf_snprintf, sizeof(buf_snprintf), "%x", CHAR_MIN); assert(!strcmp(int2str(CHAR_MIN, buf_int2str, 16), buf_snprintf)); printf("min 16#%d:%s:%s\n", CHAR_MIN, buf_int2str, buf_snprintf); snprintf(buf_snprintf, sizeof(buf_snprintf), "%x", SHRT_MIN); assert(!strcmp(int2str(SHRT_MIN, buf_int2str, 16), buf_snprintf)); printf("min 16#%d:%s:%s\n", SHRT_MIN, buf_int2str, buf_snprintf); snprintf(buf_snprintf, sizeof(buf_snprintf), "%x", INT_MIN); assert(!strcmp(int2str(INT_MIN, buf_int2str, 16), buf_snprintf)); printf("min 16#%d:%s:%s\n", INT_MIN, buf_int2str, buf_snprintf); } void tst_0() { char buf_int2str[34] = ""; int2str(0, buf_int2str, 16); printf("0 #%s\n", buf_int2str); } int main() { tst_max_2(); tst_max_8(); tst_max_10(); tst_max_16(); tst_min_2(); tst_min_8(); tst_min_10(); tst_min_16(); tst_0(); #if 0 int val = INT_MIN; printf("##%d:%d:%u\n", val, -val, -val); //printf("%d:%d:%u\n", INT_MIN, -INT_MIN, -INT_MIN); #endif return 0; }
时间: 2024-10-28 11:12:18