算数转换的经典例题

目录

一.打印水仙花数

1.思路 + 分步代码:

(1)统计位数:

(2)求各位数n次方之和:

2.整体代码实现:

二.选择运行结果

1.错解:

2.正解:注意算数转换

补充:

三.进制转换(十 —— 六)

1.思路:%6  /6  倒序打印

2.代码:

四.删除序列中指定数字

1.思路:用2个变量做下标,扫数组

2.代码:

3.可能的疑问


一.打印水仙花数

求出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 来限制打印的位置,而不是作为初始化和调整部分。

本篇的分享就到这里了,感谢观看,如果对你有帮助,别忘了点赞+收藏+关注

小编会以自己学习过程中遇到的问题为素材,持续为您推送文章

评论 36
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值