题
前面写过逆序的
最后一个数后面不要有空格
#include <stdio.h>int main()
{int x;scanf("%d",&x);int d;do{d=x%10;printf("%d",d);if(x>=10){printf(" ");}x/=10;}while(x>0);printf("\n");return 0;
}
现在这个是逆序的
x%10如果到只剩个位时 后面再取余就等于0了所以是最后一位 这时用if语句限制这个条件就可以做到最后一个数后面没有空格。
把他正序思路也很简单,就是先给他逆序过去 再逆序过来 逆逆得正
#include <stdio.h>int main()
{int x;scanf("%d",&x);int t=0;do{int d=x%10;t=t*10+d;x/=10;}while(x>0);printf("x=%d,t=%d\n", x, t);x=t;do{int d=x%10;printf("%d",d);if(x>=10){printf(" ");}x/=10;}while(x>0);printf("\n");return 0;
}
但这种逆序两次的方法不能适用于末位数为零的数字
如果末位为零就会这样 就得换种方法 太难了 不会。。。。。
#include <stdio.h>int main()
{int x;scanf("%d", &x);int mask = 1;int t = x;while(t>9){t /= 10;mask *=10;}printf("x=%d, mask=%d\n", x, mask);do {int d = x / mask;printf("%d", d);if (mask>9){printf(" ");}x %= mask;mask /=10;}while( mask > 0 );printf("\n");return 0;
}
这个就是最终改进的 下面一步一步来理解
思路1 x=12345
2 12345/10000 ->1
3 12345%10000 ->2345
4 10000/10 ->1000
5 2345/1000 ->2
6 2345%1000 ->345
7 1000/10 ->100
8 345/100 ->3
9 345%100 ->45
10 100/10 ->10
11 45/10 ->4
12 45%10 ->5
13 10/10 ->1
14 5/1 ->5
15 5%1 ->0
16 1/10 ->0此时第 2,5,8,11,14行的就是要求的结果
这就是一个循环 输出那几行的数就是答案
#include <stdio.h>int main()
{int x;
// scanf("%d", &x);x=12345;int mask=10000;do{int d = x / mask;x %= mask;mask /=10;printf("x=%d,mask=%d,d=%d\n", x, mask, d);}while(x>0);printf("\n");return 0;
}
这是第一步 求出每一位的数字 d就是要求的结果
但这个写法是错误的对一些边界就不能用了 上面这个写法是错的
错误原因以70000为例
70000/10000 ->7
70000%10000 ->0
这里第二个数就是0了下面就没法再算了
而while的条件是x>0 这时候就直接输出了
但这时候mask它并不是零 等到mask为零的时候就对了所以要把while的条件改为mask>0;
就会得到这样的答案。
这就是改过之后的结果 是符合的
下一步
#include <stdio.h>int main()
{int x;
// scanf("%d", &x);x=70000;int mask=10000;do{int d = x / mask;printf("%d", d);if(mask>0){printf(" ");}x %= mask;mask /=10;// printf("x=%d,mask=%d,d=%d\n", x, mask, d);}while(mask>0);printf("\n");return 0;
}
里面加了一个加空格的if语句 if语句的条件也和上面的那个一样 如果还是x>0的话那就只有第一个数后面有空格 这样就错了
下一步
现在程序的mask是一个固定的数值 输入的x不是固定的可以是任意位数 mask对应几位数就要为该位数的最小数10 100 1000.... 这时候就要找一个能根据x的不同让mask与他保持同位数的方法
计算整数的位数
#include <stdio.h>int main()
{int x;
// scanf("%d", &x);x=70010;int cnt = 0;do{x/=10;cnt++;}while(x>0);printf("cnt=%d\n", cnt);int mask = 10000;do{int d = x / mask;printf("%d", d);if(mask>0){printf(" ");}x %= mask;mask /=10;// printf("x=%d,mask=%d,d=%d\n", x, mask, d);}while(mask>0);printf("\n");return 0;
}
理解加入一个变量cnt 让他来表示位数
让x/=10来一次次减少他的位数 然后累加cnt就得到了x是几位数
表示mask 可以引入pow函数 但不建议用 #include <math.h>
pow
还没学
另外一种方法 思路清晰简单 就是让初始变量mask=1;然后让它加到上面那个算几位数的循环里
让他每循环一次乘于一次10就好了,
#include <stdio.h>int main()
{int x; scanf("%d", &x);
// x=70010;int cnt = 0;int mask = 1;do{x/=10;mask *=10;}while(x>0);printf("mask=%d\n", mask);
// int mask = 10000;do{int d = x / mask;printf("%d", d);if(mask>0){printf(" ");}x %= mask;mask /=10;// printf("x=%d,mask=%d,d=%d\n", x, mask, d);}while(mask>0);printf("\n");return 0;
}
就是上面这样 然后你会发现它多了一个0 .。。。。。。。。。。。。。。。。。。。
这样也是错的。。。。。。。。。。。。。。。 可以在循环后面给mask除去一个10 .。。/。。/
也可以把这个循环里面的条件x>0改为x>9这样是应为它一直除到只剩个位数的时候结果就小了不满足循环条件了 就少了一遍循环 位数就对了 但这种方法不能以偏概全 这种错误的由来自do-while循环本身的·特性 他是先执行一遍再判断循环 所以多了
这时候就要换while循环
#include <stdio.h>int main()
{int x; scanf("%d", &x);
// x=70010;int mask = 1;while(x>9){x /= 10;mask *=10;}printf("mask=%d\n", mask);
// int mask = 10000;do{int d = x / mask;printf("%d", d);if(mask>0){printf(" ");}x %= mask;mask /=10;// printf("x=%d,mask=%d,d=%d\n", x, mask, d);}while(mask>0);printf("\n");return 0;
}
这时候mask的值就能确保是正确的 但你发现 下面输出的结果已经错很久了
原因 在上面第一个循环输出x的值
你会发现此时的x的值已经被替换了,所以还要引入一个变量让他等于x 让这个新引入的变量代替第一个循环体中的x
#include <stdio.h>int main()
{int x; scanf("%d", &x);
// x=70010;int mask = 1;int t = x;while(t>9){t /= 10;mask *=10;}printf("t=%d,mask=%d\n", t, mask);
// int mask = 10000;do{int d = x / mask;printf("%d", d);if(mask>0){printf(" ");}x %= mask;mask /=10;// printf("x=%d,mask=%d,d=%d\n", x, mask, d);}while(mask>0);printf("\n");return 0;
}
至此 所有的问题就都解决了
最后再优化一下
#include <stdio.h>int main()
{int x; scanf("%d", &x);int mask = 1;int t = x;while(t>9){t /= 10;mask *=10;}do{int d = x / mask;printf("%d", d);if(mask>0){printf(" ");}x %= mask;mask /=10;}while(mask>0);printf("\n");return 0;
}
很多细节很重要 比如循环条件的选择 对一些语句特性的理解 某些多次要运用的变量在哪里被用过之后数额是否发生变化
最重要的是思维