算数转换的经典例题

目录

一.打印水仙花数

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

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

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

<think>好的,我现在需要详细回答用户关于C语言算术类型转换规则的问题。用户希望了解相关的规则和示例,并且我的回答需要结合提供的引用内容,同时符合系统级的格式要求。首先,我应该先回顾用户提供的引用内容,确保准确引用相关信息。 首先,用户提供的引用[1]到[5]中,引用[1]和[4]提到了隐式类型转换,尤其是算术运算中的自动转换,例如int和float相加时int转为float。引用[2]和[3]提到了强制类型转换的例子,比如将(a+b)的结果强制转换为float。引用[3]中的示例涉及char和unsigned long long相乘时的提升。引用[5]中的代码虽然主要关于位操作,但可能不直接相关,但需要确认是否有相关内容。 接下来,我需要整理C语言中的算术类型转换规则,分为隐式转换(自动)和显式转换(强制)。根据引用内容,隐式转换包括整型提升和寻常算术转换。例如,在运算时,较低精度的类型会转换为较高精度的类型,如int转float,char转int等。而显式转换则是通过(type)的方式强制转换。 需要给出具体的规则和示例,每个规则对应一个例子,并确保使用正确的LaTeX格式,行内公式用$...$,独立公式用$$...$$。同时,生成的相关问题要符合用户的要求,可能包括隐式和显式转换的区别、常见错误、强制转换的应用场景、混合类型运算中的转换顺序,以及如何避免类型转换带来的问题。 检查是否有遗漏的规则,比如在赋值时的转换,或者不同符号类型(如signed和unsigned)之间的转换,这在引用[3]的示例中可能涉及到char到unsigned long long的提升。此外,需要注意浮点数和整数之间的转换,如float转double,或者int转float时的精度损失。 确保每个引用正确标注,比如在提到隐式转换时引用[1]和[4],强制转换时引用[2]和[3]。示例代码需要用中文注释,并正确格式化。例如,隐式转换的例子可以引用[1]中的int和float相加,而强制转换的例子可以引用[2]中的(float)(a+b)/2。 最后,生成的相关问题需要围绕用户可能感兴趣的扩展点,比如性能影响、常见错误、应用场景等,确保问题具有针对性和实用性。同时,确保回答结构清晰,分点明确,符合用户可见层的格式要求。</think>### C语言算术类型转换规则解析 #### 一、隐式类型转换(自动转换) 1. **整型提升规则** 所有小于`int`的类型(如`char`、`short`)在参与运算时,**自动提升为`int`类型**;若`int`无法表示其范围(如`unsigned char`超出`int`表示范围),则提升为`unsigned int`[^3][^4]。 **示例**: ```c char a = 100; unsigned long long b = 300; unsigned long long result = a * b; // a先提升为int,再转换为unsigned long long参与运算[^3] ``` 2. **寻常算术转换规则** 若运算符两边的类型不同,按以下优先级转换: `int` → `unsigned int` → `long` → `unsigned long` → `long long` → `unsigned long long` → `float` → `double` → `long double` **较低精度类型向较高精度类型转换**[^1][^4]。 **示例**: ```c int a = 5; float b = 3.5; float c = a + b; // a自动转换为float[^1] ``` 3. **赋值时的类型转换** 右侧表达式结果自动转换为左侧变量的类型,可能导致精度丢失。 **示例**: ```c double d = 3.14; int i = d; // d被截断为int型3[^4] ``` #### 二、显式类型转换(强制转换) 通过`(目标类型)表达式`强制指定类型,优先级高于隐式转换[^2]。 **示例**: ```c int a = 3, b = 4; float c = (float)(a + b) / 2; // 将(a+b)的结果7强制转为float型7.0[^2] ``` #### 三、混合类型运算的优先级 1. 先进行整型提升 2. 再按算术转换规则统一类型[^4] **示例**: ```c char ch = 'A'; int i = 10; double d = 3.14; double result = ch + i * d; // i转为double参与乘法,ch提升为int后再转为double ``` #### 四、常见问题与注意事项 1. **符号扩展问题** ```c signed char c = -1; unsigned int u = c; // c先提升为int(-1),再转为unsigned int(0xFFFFFFFF)[^3] ``` 2. **浮点数精度丢失** ```c float f = 0.1f; double d = f; // float到double无精度丢失 int i = f; // f被截断为0 ``` 相关问题
评论 33
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值