目录
一.打印水仙花数
求出0~100000之间的所有“水仙花数”并输出。
“水仙花数”是指一个n位数,其各位数字的n次方之和确好等于该数本身,如:153=1^3+5^3+3^3,则153是一个“水仙花数”。
1.思路 + 分步代码:
(1)统计位数:
(153%10=3 153/10=15) (15%10=5 15/10=1) (1%10=1 1/10=0)
int main()
{
int i = 0;
for (i = 0; i <= 100000; i++)
{
int n = 0;
//1.统计位数
while (n) // n!=0 为真,进来
{
i = i / 10;
n++;
}
//2.求和判断
}
return 0;
}
但是我们发现2个问题:
- 这样写就把 i 改了,在第二步时,i 不是循环产生的0-100000之间的数字
- i = 0 进入循环,位数也 n = 0 ,这显然有 bug,我们对代码进行优化
总结:尽量不要在循环内部改变循环变量
初始位数定为1,如果 > 9,我们再进入循环,来统计多的位数
int main()
{
int i = 0;
for (i = 0; i <= 100000; i++)
{
int tmp = i;
int n = 1;
//1.统计位数
while (tmp>9)
{
tmp = tmp / 10;
n++;
}
//2.求和判断
}
return 0;
}
(2)求各位数n次方之和:
求次方:库函数 pow( 底数 ,几次方 ); 头文件:#include<math.h>
发现 pow 的返回类型为 double ,而我们统计求和结果的变量是 int num = 0; 所以要强制类型转换
2.整体代码实现:
#include <math.h>
int main()
{
int i = 0;
for (i = 0; i <= 100000; i++)
{
int tmp = i;
int n = 1;
//1.统计位数
while (tmp>9)
{
tmp = tmp / 10;
n++;
}
//2.求和
int sum = 0;
tmp = i;
while (tmp)
{
sum += (int)pow(tmp % 10, n);
tmp = tmp / 10;
}
if (sum == i)
printf("%d ", i);
}
return 0;
}
二.选择运行结果
int main()
{
int i;
i--;
if (i > sizeof(i))
{
printf(">\n");
}
else
{
printf("<\n");
}
return 0;
}
A. > B. < C.不输出 D.程序有问题
1.错解:
全局变量不初始化,结果默认是0。i--变成 -1。 sizeof(i) 整型为4。 -1 < 4 ,输出 “ < ”
2.正解:注意算数转换
sizeof的计算结果是unsigned int 。 size_t —— 是 sizeof 计算结果的类型 。size_t 就是 unsigned int
而 int i ,所以要算数转换 (就高不就低),转换为unsigned int类型
-1的原码:10000000000000000000000000000001
反码:11111111111111111111111111111110
补码:11111111111111111111111111111111 (内存中的存储方式)
而 unsigned int 将 -1反码的符号位忽略,被编译器编译成2^32-1 ,显然 > 4,输出 “ > ”
补充:
- char 到底是 signed char 还是 unsigned char 取决于编译器,大多数是 signed char
- short - 默认是 signed short
- int - 默认是 signed int
- long - 默认是 signed long
三.进制转换(十 —— 六)
1.思路:%6 /6 倒序打印
a = 320( arr [ 0 ]=320%6 a = 320/6)( arr [ 2 ]=a%6 a = a/6 )......( a/6==0)。倒序打印arr
2.代码:
int main()
{
int a = 0;
scanf("%d", &a);
int arr[50];
int i = 0;
while (a)
{
arr[i++] = a % 6;
a = a / 6;
}
int m = 0;
for (m = i - 1; m >= 0; m--)
{
printf("%d", arr[m]);
}
return 0;
}
四.删除序列中指定数字
第一行输入一个整数 n [1-50]。第二行输入 n个整数,空格隔开。第三行输入要删除的数字。
第四行输出删除后的序列。
1.思路:用2个变量做下标,扫数组
2.代码:
int main()
{
int n = 0;
scanf("%d", &n);
int arr[n];//不能初始化!
//int arr[20];//不支持C99变长数组
int i = 0;
for (i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
}
int del = 0;
scanf("%d", &del);
int j = 0;//j作为下标锁定的位置就是用来存放不删除的数据的
for (i = 0; i < n; i++)
{
if (arr[i] != del)
{
arr[j] = arr[i];
j++;
}
}
for (i = 0; i < j; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
3.可能的疑问
如果你不能理解为什么打印时循环 i 的坐标,而不是 j 的,不妨调试起来:
输入:
可见,i 是用来扫数组,j 是用来存值,所以要用 j 来限制打印的位置,而不是作为初始化和调整部分。
本篇的分享就到这里了,感谢观看,如果对你有帮助,别忘了点赞+收藏+关注。
小编会以自己学习过程中遇到的问题为素材,持续为您推送文章