【C语言常错题型】

相信你是最棒哒!!!

目录


提示:以下是本篇文章正文内容,下面案例仅供参考

一、求位数并逆序输出

题目描述:

输入一个不多于5位的正整数,要求:  (1)求它是几位数;(2)逆序打印出各位数字。

样例输入:

9

样例输出:

1
9

注释版代码:

#include <stdio.h> 

int main()
{
    int x, wei=0, m=0; // 定义三个整型变量,x用于存储输入的整数,wei用于存储位数,m用于存储反转后的整数
    scanf("%d", &x); // 输入x

    while (x > 0) // 当x大于0时,执行循环
    {
        m = m * 10 + x % 10; // 将m乘以10,然后加上x的最低位(x % 10),实现数字的反转
        x = x / 10; // 将x除以10,去掉最低位
        wei = wei + 1; // 每次循环,位数加1

  //记不住就背下来吧呜呜呜 很重要哒!!!

    }

    printf("%d %d\n", wei, m);
    return 0; 
}

 简洁版:

#include <stdio.h>
int main()
{
	int x,wei=0,m=0;
	scanf("%d", &x);
	while (x > 0)
	{
		m = m * 10 + x % 10;
		x = x / 10;
		wei = wei + 1;
	}
	printf("%d\n%d\n", wei, m);
	return 0;
}

  


二、邮费计算

题目描述:

你去邮局给朋友寄礼物。发现邮局对邮寄包裹的费用是这样规定的:如果包裹长宽高任意一个尺寸超过1米,或重量超过30千克,不予邮寄;对可以邮寄的包裹每件收手续费 0.2 元,不同重量的邮资按下表计算:

重量(千克)

收费标准(元)

小于10

0 . 80

大于等于10但不超过20

0 . 75

大于20但不超过30

0 . 70

编写程序,输入包裹的长、宽、高尺寸和重量,输出所需的邮资(输出结果中包含两位小数即可),超出尺寸或重量的输出 "Error” 

输入描述:

包裹的长、宽、高尺寸和重量

输出描述

所需的邮资(输出结果中包含两位小数即可),超出尺寸或重量的输出 "Error”

样例输入:

0.2,0.3,0.8,25

样例输出:

17.70

错误代码:

#include <stdio.h>

int main() 
{
	double a,b,c,money,m;
	scanf("%lf,%lf,%lf,%lf",&a,&b,&c,&m);
	if(a>1||b>1||c>1||m>30)
	{
		printf("Error");  
	}
	else if(m<10)  //如果前边出现Error应该跳出判断,不考虑以下情况,也不用输出money的值
	{
		money=0.8*m+0.2;
	}
	else if(m>=10&&m<=20)
	{
		money=0.75*m+0.2;
	}
	else if(m>20&&m<=30)
	{
		money=0.7*m+0.2;
	}
	printf("%.2f",money);	//money在使用前未初始化	
	
	return 0;
}

注意,如果用户在输入时不使用逗号分隔值,那么scanf可能无法正确地从标准输入中读取值。 

正确代码(注释版):

方法一:

#include <stdio.h> 

int main() 
{
    double a, b, c, money = 0, m; //初始化money为0

    scanf("%lf,%lf,%lf,%lf", &a, &b, &c, &m);
    if (a > 1 || b > 1 || c > 1 || m > 30)
        printf("Error"); // 输出"Error"表示输入错误
    else // 如果输入合法,则继续执行
    {
        if (m < 10) 
            money = 0.8 * m + 0.2; 
        else if (m >= 10 && m <= 20) 
            money = 0.75 * m + 0.2; 
        else if (m >= 20 && m <= 30) 
            money = 0.7 * m + 0.2; 
        printf("%.2f", money); // 输出money,保留两位小数
    } // 结束if-else结构
    return 0; 
}

 方法二:

#include <stdio.h> 

int main()
{
    double a, b, c, money, m;

    scanf("%lf,%lf,%lf,%lf", &a, &b, &c, &m);

    // 检查输入值是否在有效范围内
    if (a > 1 || b > 1 || c > 1 || m > 30) 
    {
        printf("Error"); // 输出"Error"表示输入错误
        return 1; // 返回1表示程序因为错误而结束
    }
    else // 如果输入合法,则继续执行
    {
        if (m < 10) 
        {
            money = 0.8 * m + 0.2; 
        }
        else if (m >= 10 && m <= 20)
        {
            money = 0.75 * m + 0.2; 
        }
        else if (m > 20 && m <= 30) 
        {
            money = 0.7 * m + 0.2; 
        }
        printf("%.2f", money); // 输出money,保留两位小数
    }

    return 0; 
}

在第一个if后边的 return 1;  换成 return 0;  答案也正确,但是它违反了返回值的常规约定。正确的做法是,在检测到错误时返回一个非零值(如 return 1;),这样调用者可以知道程序没有正常结束。如果你的程序是被其他程序调用的,或者你希望在脚本中使用程序的返回值来判断程序是否成功执行,那么遵循这个约定是很重要的嘻嘻。 

简洁版:

方法一: 

#include <stdio.h>
int main() 
{
	double a,b,c,money=0,m;
	scanf("%lf,%lf,%lf,%lf",&a,&b,&c,&m);
	if(a>1||b>1||c>1||m>30)
		printf("Error");
	else 
	{
	if(m<10)
		money=0.8*m+0.2;
	else if(m>=10&&m<=20)
			money=0.75*m+0.2;
	
	else if(m>=20&&m<=30)
			money=0.7*m+0.2;
	printf("%.2f",money);		
	}
	return 0;
}

方法二: 

#include <stdio.h>

int main()
{
	double a, b, c, money, m;
	scanf("%lf,%lf,%lf,%lf", &a, &b, &c, &m);
	if (a > 1 || b > 1 || c > 1 || m > 30)
	{
		printf("Error");
		return 1;
	}
	else if (m < 10)
	{
		money = 0.8 * m + 0.2;
	}
	else if (m >= 10 && m <= 20)
	{
		money = 0.75 * m + 0.2;
	}
	else if (m > 20 && m <= 30)
	{
		money = 0.7 * m + 0.2;
	}
	printf("%.2f", money);

	return 0;
}

 


三、输出所有素数

题目描述

求出1-N中的所有素数
 

输入描述

大于1的正整数N

输出描述

1-N中的所有素数,(以从小到大的格式输出)

样例输入

9

样例输出

2 3 5 7 

正确代码(注释版):

#include <stdio.h> 

int main() 
{
    int n, i, flag, j; //flag(小旗子)用于标记素数

    scanf("%d", &n); 

    for (i = 2; i <= n; i++) // 外层循环,从2开始遍历到n(包括n)
    {
        flag = 1; // 初始化flag为1,表示假设当前数字i是素数。

        for (j = 2; j * j <= i; j++) // 内层循环,从2遍历到i的平方根。如果i不是素数,那么它必定有一个因子不大于它的平方根。
        {
            if (i % j == 0) // 如果i能被j整除,那么i不是素数。
            {
                flag = 0; // 将flag设置为0,表示i不是素数。
                break; // 跳出内层循环,因为已经确定i不是素数。
            }
        }

        if (flag == 1) // 如果flag仍然为1,说明i是素数。
        {
            printf("%d ", i); // 打印素数i,并在其后加一个空格。
        }   
    }

    return 0;
}

简洁版:

#include <stdio.h>

int main() 
{
	int n,i,flag,j;
	scanf("%d",&n);
	for(i=2;i<=n;i++)
	{
		flag=1;
		for(j=2;j*j<=i;j++)  //important !
		{
			if(i%j==0)
			{
				flag=0;
				break;
			}
		}
	
		if(flag==1)
		{
			printf("%d ",i);		
		}	
	}
	return 0;
}

为什么只需要检查到 i 的平方根呢?这是因为:

  1. 因子成对出现:如果 i 有一个因子 jj > 1),那么必定存在另一个因子 i/j。这两个因子的乘积等于 i

  2. 平方根的界限:如果 i 有一个因子 j 大于它的平方根(j > sqrt(i)),那么对应的另一个因子 i/j 必定小于平方根(i/j < sqrt(i))。因为如果两个因子都大于平方根,它们的乘积就会大于 i,这与它们是 i 的因子相矛盾。

  3. 效率:检查到平方根可以显著减少需要检查的因子数量,特别是对于较大的数,这可以大幅提高效率。

因此,如果 i 不是素数,它必定有一个小于或等于其平方根的因子。如果内层循环完成而没有找到任何因子(即 flag 保持为1),那么 i 就是素数。这就是为什么只需要检查到 i 的平方根的原因。


四、输出平行四边形

题目描述:

输入图形的每行有n个星号,高 n ,输出对应的图形 .

输入描述:

整数n例如 5

输出描述:

每行由5个*组成的,高为5的平行四边形

样例输入:

5

样例输出:

*****
 *****
  *****
   *****
    *****

正确代码(注释版):

#include <stdio.h> 

int main() 
{
    int n, i, j, k; // i、j、k用于循环

    scanf("%d", &n); // 从标准输入读取一个整数,存储到变量n中,这个整数表示将要打印的星号行数

   
    for (i = 1; i <= n; i++)   // 外层循环,控制打印的行数
    {
       
        for (j = 1; j < i; j++)   // 内层循环1,用于打印每行前面的空格
        {
            printf(" "); 
        }

       
        for (k = 1; k <= n; k++)
        {
            printf("*"); // 打印n个星号
        }

        printf("\n"); // 换行
    }

    return 0;
}

 简洁版:

#include <stdio.h>
int main()
{
	int n, i, j, k;
	scanf("%d", &n);
	for (i = 1; i <= n; i++)
	{
		for (j = 1; j < i; j++)
		{
			printf(" ");
		}
		for (k = 1; k <= n; k++)
		{
			printf("*");
		}
		printf("\n");
	}
	return 0;
}

总结

1. x>0时, m = m * 10 + x % 10 和 x = x / 10 的循环可以实现倒序输出的功能。

 2. return 1;通常表示程序或函数执行失败,或者发生了某种错误;

     return 0;通常表示程序或函数执行成功,没有错误发生。

3. 要运用嵌套正确使用内外层循环。

4.检查一个数是否为素数时,只需检查到他的算术平方根就可以啦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值