请c语言大神帮忙! 255
【第3问:应用变化/重组程序/函数+数据驱动+规范化】
应用变化:由于用电持续增长,该地增加了第四档,年用量超过7000度时,电价在第三档基础上再增加0.30元/度。
程序要求:编写程序eCost3.c,完成以下要求。
(1)为了应对未来对于电价的各种可能调整,程序应该具有最大的灵活性。电量范围及价格设定以“数据”方式表达,如下所示:
{4, 0,0.6, 3000,0.1, 5000,0.2, 7000,0.3 };
数据理解为:第一个4表示共有4档计费,电量超过0度,每度0.6元,电量超过3000度部分,每度再增加0.1元,电量超过5000度部分,每度再增加0.2元,电量超过7000度部分,每度再增加0.3元。
(2)设计函数ecost,用于计算年用电量对应的电费,程序代码具有如下框架。
#include <stdio.h>
float ecost(float amount)
{ //年电费计算函数,根据电量amount计算并返回对应的电费
定义关于存放收费标准的变量//收费标准
//修改上表相当于修改收费标准
… return …; //本函数只计算并返回,不能直接输入输出
} //边界检查,年用电量小于0时,电费统一为0元。
int main(void)
{ //主函数,输入电量,调用函数计算电费并输出
… = ecost(…); //主函数:输入电量、调用函数计算、输出结果
} //电费输出精确到分(保留2位小数)
测试用例:
年用电量为(度):-10,0.123,3000.123,5000.123,7000.123
则年电费为(元):0.00,0.07,1800.09,3200.11,5000.15
求大神帮忙写些代码,看蒙了...自己写的总报错 展开
这个题目要点。
1、收费标准必须为可操作修改。
2、收费标准档位是不确定的,需要动态数组。(当然用常量,每次手改源代码就不需要了)
3、收费标准的输入除第一个阀值,其他要求增量(较上一个阀值),不能直接用于运算。
4、输入范围需要有验证。
最简易做法是将标准定义成常量,然后需要时修改代码常量,但这样对用户够不友好,所以我这里把标准定义成结构,定义函数动态申请数组,修改收费标准。
#include<stdio.h>
#include<malloc.h>
typedef struct eq
{
int tn;//表示共有几档
float **fb;//表示各档计费标准的二维数组
}EQ;
int newFb(int tn);//构建收费标准数组地址空间,成功返回1,失败返回2。(成功自动释放旧地址,无需单独释放)
EQ *init();//初始化计费标准
void showEQ();//打印当前收费标准
int setEQ();//修改收费标准,成功返回1,失败返回0
float ecost(float amount);//计算电费
EQ *eq=NULL;
int main()
{
int n=0;
float at;
eq=init();
if(!eq)
{
printf("异常终止!\n");
return 1;
}
while(1)
{
printf("1、打印收费标准;2、修改收费标准;3、计算电费\n");
n=0;
while(n!=1 && n!=2 && n!=3)
scanf("%d",&n);
switch(n)
{
case 1:showEQ();break;
case 2:
if(!setEQ())
printf("异常!修改失败!\n\n");
else
printf("修改成功!\n\n");
break;
case 3:printf("请输入年度用电量:");
scanf("%f",&at);
printf("年度用电费用:%.2f\n\n",ecost(at));
break;
}
}
return 0;
}
float ecost(float amount)//计算电费
{
int i;
float sum=0;
if(amount<=eq->fb[0][0])
return 0;
for(i=eq->tn-1;i>=0;i--)
if(amount>eq->fb[i][0])
{
sum+=(amount-eq->fb[i][0])*eq->fb[i][1];
amount=eq->fb[i][0];
}
return sum;
}
EQ *init()//初始化计费标准,
{
if(eq)
return eq;
eq=(EQ *)malloc(sizeof(EQ));
if(!eq)
return NULL;
eq->tn=4;
eq->fb=NULL;
if(!newFb(4))
{
free(eq);
return NULL;
}
eq->fb[0][0]=0,eq->fb[0][1]=0.6;
eq->fb[1][0]=3000,eq->fb[1][1]=0.7;
eq->fb[2][0]=5000,eq->fb[2][1]=0.9;
eq->fb[3][0]=7000,eq->fb[3][1]=1.2;
return eq;
}
int newFb(int tn)//构建收费标准数组地址空间,成功返回1,失败返回0。(成功自动释放旧地址,无需单独释放)
{
int i,flag=1;
float **fbSave=NULL;
if(!eq)
return 0;
eq->tn=tn;
if(!eq->fb)//如果有旧地址,保存该地址,用于还原
fbSave=eq->fb;
eq->fb=(float **)malloc(sizeof(float *)*tn);
if(!eq->fb)
flag=2;
for(i=0;flag && i<tn;i++)
{
eq->fb[i]=(float *)malloc(sizeof(float)*2);
if(!eq->fb)
flag=3;
}
if(flag==3)//内存申请失败,释放已申请的新地址,还原旧地址
{
for(i=0;i<tn;i++)
free(eq->fb[i]);
free(eq->fb);
eq->fb=fbSave;
return 0;
}
if(flag==2)
{
eq->fb=fbSave;
return 0;
}
return 1;
}
void showEQ()//打印当前收费标准
{
int i;
printf("当前共计%d档计费标准:\n",eq->tn);
for(i=0;i<eq->tn;i++)
printf("电量超过%.0f,%s%.1f(实际金额%.1f)\n",eq->fb[i][0],i>0?"每度再增加":"每度",i>0?eq->fb[i][1]-eq->fb[i-1][1]:eq->fb[i][1],eq->fb[i][1]);
printf("\n");
}
int setEQ()//修改收费标准,成功返回1,失败返回0
{
int i,tn;
float money;
printf("请输入新的计费档数(输入0退出修改):");
scanf("%d",&tn);
if(!tn)
return 0;
if(newFb(tn))
{
for(i=0;i<eq->tn;i++)
{
printf("请输入第%d档电量阀值(%s%.0f),及%s(单位元)",i+1,i>0?"必须大于":"大于等于",i>0?eq->fb[i-1][0]:0,i>0?"每度增加收费":"每度收费");
scanf("%f%f",&eq->fb[i][0],&money);
if(i==0 && eq->fb[i][0]<0)
{
printf("输入错误!起始阀值不能小于0!请重新输入\n");
i--;
continue;
}
if(i>0 && eq->fb[i][0]<=eq->fb[i-1][0])
{
printf("输入错误!当前阀值不能小于上一次的阀值!请重新输入\n");
i--;
continue;
}
if(i==0)
eq->fb[i][1]=money;
else
eq->fb[i][1]=eq->fb[i-1][1]+money;
}
}
return 1;
}
//PS:你说你代码运算不对,看看是否把增量当金额来用了。