第3章 控制流
3.6 do-while 循环
编写 itoa(), 使用 do-while 比较合适
void reverse(char *s, int n) { for (int ix = 0, jx = n -1; ix < jx; ix++, jx--) { int tmp = s[ix]; s[ix] = s[jx]; s[jx] = tmp; } } void itoa(int n, char *s) { int i = 0, sign = n; if (sign < 0) n = -n; // 使用for, n=0 会出问题 //for (; n > 0; n /= 10) s[i++] = n % 10 + '0'; do { s[i++] = n % 10 + '0'; } while ((n /= 10) > 0);
if (sign < 0) s[i++] = '-'; s[i] = '\0'; reverse(s, i); }
上述itoa() 有缺陷,不能处理INT_MIN, 所以进行如下修改,将n的个位取绝对值,就不会出现溢出问题
练习 3-4 优化itoa(), 让它可以处理最小的负数,即 int n = INT_MIN = -2147483648
#include <stdio.h> #include <string.h> #include <assert.h> // 因为x可能是表达式,所以 x要加() #define ABS(x) ((x) < 0 ? -(x) : (x)) void reverse(char *s, int n); void itoa(int n, char *s) { int i = 0, sign = n; do { s[i++] = ABS(n % 10) + '0'; // 将n的个位取绝对值,就不会出现溢出问题 } while ((n /= 10) != 0); if (sign < 0) s[i++] = '-'; s[i] = '\0'; reverse(s, i); } void main() { char s[20] = {}; itoa(-2147483648, s); assert(0 == strcmp("-2147483648", s)); }
练习3-5 编写函数itob(n, s, b), 将整数转化成以b为底的数。例如,itob(n, s, 16) 把整数n格式化成十六进制整数保存在 s 中
#include <stdio.h> #define ABS(x) ((x) < 0 ? -(x) : (x)) void reverse(char *s, int n); void itob(int n, char *s, int b) { int i = 0, j, sign = n; do { j = ABS(n % b); s[i++] = (j <= 9) ? j + '0' : j + 'a' - 10; } while ((n /= b) != 0); if (sign < 0) s[i++] = '-'; s[i] = '\0'; reverse(s, i); } void main() { int n, b; char s[30] = {}; while (scanf("%d %d", &n, &b) >= 0) { itob(n, s, b); printf("s=%s\n", s); } }
我看 答案中是这样写的,但是我觉得有问题,比如 iotb(-1, s, 16) 转化的结果是 -1,16进制数 不应该有 负号。
练习 3-6, itoa() 输入参数,指定宽度
void itoa(int n, char *s, int w) { int i = 0, sign = n; do { s[i++] = ABS(n % 10) + '0'; } while ((n /= 10) != 0); if (sign < 0) s[i++] = '-'; while (i < w) s[i++] = ' '; // 设置对应的宽度,如果满足了,就退出 s[i] = '\0'; reverse(s, i); }
 
                    
                     
                    
                 
                    
                
 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号