【编程题2.1】
#include <stdio.h>
int main(void)
{
printf(" *\n");
printf(" *\n");
printf(" *\n");
printf("* *\n");
printf(" * *\n");
printf(" *\n");
return 0;
}
【编程题2.2】
#include <stdio.h>
int main(void)
{
float r=10,volume;
const float PI=3.1415926;
printf("When the r is equal to 10,\n");
volume=4.0f/3.0f*PI*r*r*r;
printf("The volume of the sphere is equal to:%.2f\n",volume);
return 0;
}
【编程题2.3】
【方法一】
#include <stdio.h>
#define PI 3.1415926
int main(void)
{
float r,volume;
printf("Enter the value of r:");
scanf("%f",&r);
volume=4.0f/3.0f*PI*r*r*r;
printf("The volume of the sphere:%.2f\n",volume);
return 0;
}
【方法二】
#include <stdio.h>
int main(void)
{
float r,volume;
const float PI=3.1415926;
printf("Enter the value of r:");
scanf("%f",&r);
volume=4.0f/3.0f*PI*r*r*r;
printf("The volume of the sphere:%.2f\n",volume);
return 0;
}
【总结】标准的C语言中没有π这个符号及常量,一般在开发过程中是通过开发人员自己定义这个常量的,最常见的方式是使用宏定义:#definePI3.141592。
或者定义常量:const float PI=3.1415926;
还可以直接普通变量定义,如:double pi=3.141592;
C语言中,并不支持希腊字符π,而且,也不存在系统自带的π(圆周率值)。
【编程题2.4】
#include <stdio.h>
int main(void)
{
float amount,answer;
printf("Enter an amount:");
scanf("%f",&amount);
answer=amount*1.05f;
printf("With tax added:$%.2f\n",answer);
return 0;
}
【总结】scanf("%.1f"); 错的,编译运行显示结果0.00
scanf("%f"); 正确
在printf时,可以设置输出的精度,但是scanf是不能设置精度的,也就是不能出现任何%.xf这样的格式,但是却可以写成scanf("%2f");这是设置域宽,是正确的格式。
在这里把域宽和精度两个概念混淆了,导致输出结果有问题,却又很难发现错误,因为对于精度这是的问题,一般编译器不报错的。
【编程题2.5】
#include <stdio.h>
int main(void)
{
float x;
printf("Enter the value of x:");
scanf("%f",&x);
printf("The polynomial is evaluated to be:%.2f\n",3*x*x*x*x*x+2*x*x*x*x-5*x*x*x-x*x+7*x-6);
return 0;
}
【编程题2.6】
【方法一】
#include <stdio.h>
int main(void)
{
float x;
printf("Enter the value of x:");
scanf("%f",&x);
printf("The polynomial is evaluated to be:%.2f\n",(((((3*x+2)*x-5)*x-1)*x+7)*x-6));
return 0;
}
【方法二】
#include <stdio.h>
int main(void)
{
float x,answer;
printf("Enter the value of x:");
scanf("%f",&x);
answer=(((((3*x+2)*x-5)*x-1)*x+7)*x-6);
printf("The polynomial is evaluated to be:%.2f\n",answer);
return 0;
}
【总结】实际编程时,为了简便,我先写的方法一,后因报错,改成方法二,找到报错原因是少写了x-6)这个括号。
因为多项式括号多,容易出错,所以尽可能把多项式单独写一行,不把多项式写在printf中,避免书写不当导致报错。
【编程题2.7】
#include <stdio.h>
int main(void)
{
int amount,a,b,c,d;
printf("Enter a dollar amount:");
scanf("%d",&amount);
a=amount/20;
b=(amount-a*20)/10;
c=(amount-a*20-b*10)/5;
d=(amount-a*20-b*10-c*5);
printf("20 bills:%d\n",a);
printf("10 bills:%d\n",b);
printf("5 bills:%d\n",c);
printf("1 bills:%d\n",d);
return 0;
}
【编程题2.8】
#include <stdio.h>
int main(void)
{
Float amount_of_loan,interest_rate,monthly_payment,first_payment,
second_patment,third_payment;
printf("Enter amount_of_loan:");
scanf("%f",&amount_of_loan);
printf("Enter interest_rate:");
scanf("%f",&interest_rate);
printf("Enter monthly_payment:");
scanf("%f",&monthly_payment);
first_payment=amount_of_loan*(1+interest_rate*0.01/12)-monthly_payment;
second_patment=first_payment*(1+interest_rate*0.01/12)-monthly_payment;
third_payment=second_patment*(1+interest_rate*0.01/12)-monthly_payment;
printf("Balance remaining after first_payment:$%.2f\n",first_payment);
printf("Balance remaining after second_patment:$%.2f\n",second_patment);
printf("Balance remaining after third_payment:$%.2f\n",third_payment);
return 0;
}
【编程题3.1】
#include <stdio.h>
int main(void)
{
int mm,dd,yyyy;
printf("Enter a date(mm/dd/yyyy):");
scanf("%2d/%2d/%4d",&mm,&dd,&yyyy);
printf("You enterd the date:%04d%02d%02d",yyyy,mm,dd);
return 0;
}
【总结】C语言中要用0补充空白,在%和d中间加0,也就是写成%0xd,需要多宽,x就写几。
【编程题3.2】
#include <stdio.h>
int main(void)
{
int item_number,mm,dd,yyyy;
float unit_price;
printf("Enter item number:");
scanf("%d",&item_number);
printf("Enter unit price:");
scanf("%f",&unit_price);
printf("Enter purchase date(mm/dd/yyyy):");
scanf("%d/%d/%d",&mm,&dd,&yyyy);
printf("Item Unit Purchase\n");
printf(" Price Date\n");
printf("%-10d$ %-8.2f",item_number,unit_price);
printf("%d/%d/%d",mm,dd,yyyy);
return 0;
}
【总结】右对齐,%和d之间加上数字宽度,例如%10d,说明这个数占十个格,在十个格的最右边显示,其余位置用空格补齐,例如·······345
左对齐,%和d之间加上负的数字宽度,例如%-10d,显示在十个格最左边,如1234······
【编程题3.3】
#include <stdio.h>
int main(void)
{
int GS1_prefix,Group_identifier,Publisher_code,Item_number,Check_digit;
printf("Enter ISBN:");
scanf("%d-%d-%d-%d-%d",&GS1_prefix,&Group_identifier,&Publisher_code,&Item_number,&Check_digit);
printf("GS1 prefix:%d\n",GS1_prefix);
printf("Group identifier:%d\n",Group_identifier);
printf("Publishercode:%d\n",Publisher_code);
printf("Item number:%d\n",Item_number);
printf("Check digit:%d\n",Check_digit);
return 0;
}
【编程题3.4】
[正确程序]
#include <stdio.h>
int main(void)
{
int aaa,bbb,cccc;
printf("Enter phone number[(aaa) bbb-cccc]:");
scanf("(%d)%d-%d",&aaa,&bbb,&cccc);
printf("You entered:%03d.%03d.%04d\n",aaa,bbb,cccc);
return 0;
}
[第一次尝试(我写的),失败]
#include <stdio.h>
int main(void)
{
int aaa,bbb,cccc;
printf("Enter phone number[(aaa) bbb-cccc]:");
scanf("(%d)%d-%d",&aaa,&bbb,&cccc);
printf("You entered:%3d.%3d.%4d\n",aaa,bbb,cccc);
return 0;
}
[第二次尝试(网上答案),失败]
#include <stdio.h>
void phone_num(void);
int main(void)
{
int xxx, yyy, zzzz;
phone_num();
scanf("(%d) %d-%d", &xxx, &yyy, &zzzz);
printf("You entered %d.%d.%d ", xxx, yyy, zzzz);
return 0;
}
void phone_num(void)
{
printf("Enter phone number [(xxx) xxx-xxxx]: ");
}
【总结】两次尝试得到一样的错误,后因分辨不清楚是不是因为(xxx) xxx-xxxx之间空格的原因导致断开,下一次重读,取消空格之后还是一样的错误。
我意识到,程序运行后,输入法自动切换到中文输入,可能是因为输入内容含有(),而中英括号不同,可能是这个原因导致无法识别,在程序编译运行后,切换到英文输入,问题解决,但是出现了新的小问题。
当我输入010这种以0开头的区号,程序自动把开头的0视为无效,跳过,输出10.123.1234,为了解决这个问题
在程序最后一个printf区号处,改成%03d,这样,区号显示完全正确。
我认为后面的电话号码也可能出现这种情况,因为在XXXX处也是单独用一个指针,当出现292-0091这种号码,显示如下。
所以要把所有指针对应的printf处都加上%0xd,且这样不会对非零开头的号码产生影响。
【编程题3.5】
#include <stdio.h>
int main(void)
{
int a[4][4],i,j,Row_sums,Column_sums,Diagonal_sums1,Diagonal_sums2;
printf("Enter the number from 1 to 16 in any order:");
for (i = 0; i < 4; i ++)
{
for (j = 0; j < 4; j ++)
{
scanf("%d", &a[i][j]);
printf("%5d", a[i][j]);
}
printf("\n");
}
printf("\nRow sums:");
for (i = 0; i < 4; i ++)
{
for (j = 0; j < 4; j ++)
{
Row_sums += a[i][j];
}
printf("%d ", Row_sums);
Row_sums = 0;
}
printf("\nColumn sums:");
for (j = 0; j < 4; j ++)
{
for (i = 0; i < 4; i ++)
{
Column_sums += a[i][j];
}
printf("%d ", Column_sums);
Column_sums = 0;
}
printf("\nDiagonal sums:");
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j ++)
{
if (i==j)
Diagonal_sums1 += a[i][j];
if (i+j==5)
Diagonal_sums2 += a[i][j];
}
}
/*不清楚为什么Diagonal_sums2的显示值始终比我计算的值大31*/
printf("%d %d", Diagonal_sums1,Diagonal_sums2);
return 0;
}
问题1:在计算矩阵对角线时,程序运行得出的副对角线的值比实际总是大31,我在程序末尾把副对角线对应的变量Diagonal_sums2减去31,程序运行结果就完全正确了。
问题2:计算每列之和时,第一列的值始终不正确,且每次运行显示的值都不一样,想请问这是什么原因。
[解决问题]
在请教很多大神之后,他们都指出:没有初始化变量,导致这些变量的值默认是不确定的,因而会导致列之和错乱等问题。
在听从建议,在程序前加上初值为0后,问题解决。
#include <stdio.h>
int main(void)
{
int a[4][4],i,j,Row_sums,Column_sums,Diagonal_sums1,Diagonal_sums2;
Row_sums=0;
Column_sums=0;
Diagonal_sums1=0;
Diagonal_sums2=0;
printf("Enter the number from 1 to 16 in any order:");
for (i = 0; i < 4; i ++)
{
for (j = 0; j < 4; j ++)
{
scanf("%d", &a[i][j]);
printf("%5d", a[i][j]);
}
printf("\n");
}
printf("\nRow sums:");
for (i = 0; i < 4; i ++)
{
for (j = 0; j < 4; j ++)
{
Row_sums += a[i][j];
}
printf("%d ", Row_sums);
Row_sums = 0;
}
printf("\nColumn sums:");
for (j = 0; j < 4; j ++)
{
for (i = 0; i < 4; i ++)
{
Column_sums += a[i][j];
}
printf("%d ", Column_sums);
Column_sums = 0;
}
printf("\nDiagonal sums:");
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j ++)
{
if (i==j)
Diagonal_sums1 += a[i][j];
if (i+j==3)
Diagonal_sums2 += a[i][j];
}
}
printf("%d %d", Diagonal_sums1,Diagonal_sums2);
return 0;
}
【总结】定义变量后先赋初值!!!
【编程题3.6】
[原程序]
#include <stdio.h>
int main(void)
{
int num1,denom1,num2,denom2,result_num,result_denom;
printf("Enter first fractinon:");
scanf("%d/%d",&num1,&denom1);
printf("Enter second fractinon:");
scanf("%d/%d",&num2,&denom2);
result_num=num1*denom2+num2*denom1;
result_denom=denom1*denom2;
printf("The sum is %d/%d\n",result_num,result_denom);
return 0;
}
[改进后]
#include <stdio.h>
int main(void)
{
int num1,denom1,num2,denom2,result_num,result_denom;
printf("Enter two fractinons separated by a plus sign:");
scanf("%d/%d+%d/%d",&num1,&denom1,&num2,&denom2);
result_num=num1*denom2+num2*denom1;
result_denom=denom1*denom2;
printf("The sum is %d/%d\n",result_num,result_denom);
return 0;
}
【编程题4.1】
#include <stdio.h>
int main(void)
{
int num1,num2;
printf("Enter a two-digit number:");
scanf("%d%d",&num1,&num2);
printf("The reversal is:%d%d\n",num2,num1);
return 0;
}
[解决方法见编程题4.3]
[问题]尝试运行,当输入数字28,回车,没有任何反应,因为%d%d为需要我输入两个数字,当我输入一个数字且两位中间没有空格时,它只读到一个数,默认没有结束,还在继续等待我输入。
[改进后]
#include <stdio.h>
int main(void)
{
int num,a,b;
printf("Enter a two-digit number:");
scanf("%d",&num);
a=num/10;
b=num-a*10;
printf("The reversal is:%d\n",b*10+a);
return 0;
}
【总结】一个%d为输入一个整数,如果这个整数有不止一位,那么以这个数中间是否有空格来判断这个数是否结束,有空格说明是下一个数了,所以在scanf时,其实输入“%d%d”与“%d %d”是没有什么区别的。
【编程题4.2】
#include <stdio.h>
int main(void)
{
int num,a,b,c;
printf("Enter a three-digit number:");
scanf("%d",&num);
a=num/100;
b=(num-a*100)/10;
c=num-a*100-b*10;
printf("The reversal is:0%d\n",c*100+b*10+a);
return 0;
}
【总结】最后一个printf写0%d,就是为了当输入280这种个位为零时,能够在输出时不省略第一个0,如果直接写成%d,那么,当输入280,输出为82。
【编程题4.3】
#include <stdio.h>
int main(void)
{
int num1,num2;
printf("Enter a two-digit number:");
scanf("%1d%1d",&num1,&num2);
printf("The reversal is:%d%d\n",num2,num1);
return 0;
}
【总结】为了读取连续输入的单个数字,也就是当输入一个多位的数,我们一位数字一位数字地去读,需要使用带有转换说明%1d的scanf函数,其中%1d匹配只有一位的整数。
【编程题4.4】
【方法一】
#include <stdio.h>
int main(void)
{
int num,a,b,c,d,e;
a=0,b=0,c=0,d=0,e=0;
printf("Enter a two-digit number:");
scanf("%d",&num);
a=num-(num/8)*8;
b=num/8-((num/8)/8)*8;
c=(num/8)/8-(((num/8)/8)/8)*8;
d=((num/8)/8)/8-((((num/8)/8)/8)/8)*8;
e=(((num/8)/8)/8)/8-(((((num/8)/8)/8)/8)/8)*8;
printf("In octal, your number is:%1d%1d%1d%1d%1d\n",e,d,c,b,a);
return 0;
}
【方法二】
#include <stdio.h>
int main(void)
{
int num,a,b,c,d,e,num1,num2,num3,num4,num5;
a=0,b=0,c=0,d=0,e=0,num1=0,num2=0,num3=0,num4=0,num5=0;
printf("Enter a two-digit number:");
scanf("%d",&num);
num1=num/8;
a=num-num1*8;
num2=num1/8;
b=num1-num2*8;
num3=num2/8;
c=num2-num3*8;
num4=num3/8;
d=num3-num4*8;
num5=num4/8;
e=num4-num5*8;
printf("In octal, your number is:%1d%1d%1d%1d%1d\n",e,d,c,b,a);
return 0;
}
【总结】很明显,方法一公式复杂,变量少,方法二变量很多但是公式相对简单容易理解,相较差不多,但是我个人更偏向方法二,想起来容易理解。
【编程题4.5】
#include <stdio.h>
int main(void)
{
int d,i1,i2,i3,i4,i5,j1,j2,j3,j4,j5,first_sum,second_sum,total;
printf("Enter the digit:");
scanf("%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d",&d,&i1,&i2,&i3,&i4,&i5,&j1,&j2,&j3,&j4,&j5);
first_sum=d+i2+i4+j1+j3+j5;
second_sum=i1+i3+i5+j2+j4;
total=3*first_sum+second_sum;
printf("Check digit:%d\n",9-((total-1)%10));
return 0;
}
【总结】公式中x%10就是x除以十取余数,这样的话,编程题4.3可以进一步简化。
【编程题4.6】
#include <stdio.h>
int main(void)
{
int i1,i2,i3,i4,i5,i6,i7,i8,i9,i10,i11,i12,first_sum,second_sum,total;
printf("Enter the digit:");
scanf("%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d",&i1,&i2,&i3,&i4,&i5,&i6,&i7,&i8,&i9,&i10,&i11,&i12);
first_sum=i2+i4+i6+i8+i10+i12;
second_sum=i1+i3+i5+i7+i9+i11;
total=3*first_sum+second_sum;
printf("Check digit:%d\n",9-((total-1)%10));
return 0;
}
【编程题5.1】
#include <stdio.h>
int main(void)
{
int num,digits=0;
printf("Enter a number:");
scanf("%d",&num);
if (0<num<9)
printf("The number %d has 1 digit.",num);
else
printf("The number %d has %d digits.",num,digits);
{
if (10<num<99)
digits=2;
else
{
if(100<num<999)
digits=3;
else
{
digits=4;
}
}
}
return 0;
}
[错误]表达式0<num<10这种形式在C语言中合法,但是表达的意思不是num大于0且小于10,因为运算符<是左结合的,所以这个式子等价于(0<num)<10,也就是说,会先判断num和0的大小,如果num大于0,则为真,这个式子为1,此时,用1和10比较,这个比较结果作为if语句的判断条件。
[改正后]
#include <stdio.h>
int main(void)
{
int num,digits=0;
printf("Enter a number:");
scanf("%d",&num);
if (num>9999)
{
printf("The number %d has more than 4 digits.",num);
}
else if (num<9)
{
printf("The number %d has 1 digit.",num);
}
else
{
if (num<99)
digits=2;
else if(num<999)
digits=3;
else digits=4;
printf("The number %d has %d digits.",num,digits);
}
return 0;
}
【编程题5.2】
#include <stdio.h>
int main(void)
{
int hour,minute;
printf("Enter a 24-hour time:");
scanf("%d:%d",&hour,&minute);
if (hour<13)
{
printf("Equizalent 12-hour time:%d:%02d AM",hour,minute);
}
else
{
hour-=12;
printf("Equizalent 12-hour time:%d:%02d PM",hour,minute);
}
return 0;
}
【总结】还是要注意当程序运行后输入法自动切换为中文的情况,中英文:是不同的,无法识别会导致错误。
【编程题5.3】
#include <stdio.h>
int main(void)
{
float number,price,commission,value,opponent;
printf("Enter the number of shares:");
scanf("%f",&number);
printf("Enter the price of each stock:");
scanf("%f",&price);
value=number*price;
if (value<2500.00f)
commission=30.00f+.017f*value;
else if (value<6250.00f)
commission=56.00f+.0066f*value;
else if (value<20000.00f)
commission=76.00f+.0034f*value;
else if (value<50000.00f)
commission=100.00f+.0022f*value;
else if (value<500000.00f)
commission=155.00f+.0011f*value;
else
commission=255.00f+.0009f*value;
if (commission<39.00f)
commission=39.00f;
printf("Your commissions:$%.2f\n",commission);
if (value<2000.00f)
opponent=33.03f*number;
else
opponent=33.02f*number;
printf("opponent's commissions:$%.2f\n",opponent);
return 0;
}
【编程题5.4】
#include <stdio.h>
int main(void)
{
int speed,describe;
printf("Enter the speed of wind :");
scanf("%d",&speed);
if (speed<1)
printf("The wind can be described as: Calm ( 无风 )");
else if (speed<3)
printf("The wind can be described as: Light air ( 轻风 )");
else if (speed<27)
printf("The wind can be described as: Breeze ( 微风 )");
else if (speed<47)
printf("The wind can be described as: Gale ( 大风 )");
else if (speed<63)
printf("The wind can be described as: Storm ( 暴风 )");
else
printf("The wind can be described as: Hurricane ( 飓风 )");
return 0;
}
[问题]中文乱码问题待解决。
【编程题5.5】
#include <stdio.h>
int main(void)
{
float income,tax;
printf("Please enter your income : $ ");
scanf("%f",&income);
if (income<750.00f)
tax=income*.01f;
else if (income<2250.00f)
tax=7.50f+(income-750.00f)*.02f;
else if (income<3750.00f)
tax=37.50f+(income-2250.00f)*.03f;
else if (income<5250.00f)
tax=82.50f+(income-3750.00f)*.04f;
else if (income<7000.00f)
tax=142.50f+(income-5250.00f)*.05f;
else
tax=230.00f+(income-7000.00f)*.06f;
printf("The tax you need to pay is : $ %.2f ",tax);
return 0;
}
【编程题5.6】
#include <stdio.h>
int main(void)
{
int d,i1,i2,i3,i4,i5,j1,j2,j3,j4,j5,check,first_sum,second_sum,total,digit;
printf("Enter the digit:");
scanf("%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d",&d,&i1,&i2,&i3,&i4,&i5,&j1,&j2,&j3,&j4,&j5,&check);
first_sum=d+i2+i4+j1+j3+j5;
second_sum=i1+i3+i5+j2+j4;
total=3*first_sum+second_sum;
digit=9-((total-1)%10);
printf("Check digit = %d\n",digit);
if (check==digit)
printf("Your product code is VALID.");
else
printf("Your product code is NOT VALID.");
return 0;
}
【编程题5.7】
#include <stdio.h>
int main(void)
{
int a,b,c,d;
printf("Enter four integers:");
scanf("%d%d%d%d",&a,&b,&c,&d);
if (a>b)
{
if(b>c)
{
if(c>d)
{
printf("Largest: %d\n",a);
printf("Smallest: %d",d);
}
else if(a>d)
{
printf("Largest: %d\n",a);
printf("Smallest: %d",c);
}
else
{
printf("Largest: %d\n",d);
printf("Smallest: %d",c);
}
}
else if(b>d)
{
if(a>c)
{
printf("Largest: %d\n",a);
printf("Smallest: %d",d);
}
else
{
printf("Largest: %d\n",c);
printf("Smallest: %d",d);
}
}
else if(a>c)
{
if(a>d)
{
printf("Largest: %d\n",a);
printf("Smallest: %d",b);
}
else
{
printf("Largest: %d\n",d);
printf("Smallest: %d",b);
}
}
else if(c>d)
{
printf("Largest: %d\n",c);
printf("Smallest: %d",b);
}
else
{
printf("Largest: %d\n",d);
printf("Smallest: %d",b);
}
}
else if(a>c)
{
if(c>d)
{
printf("Largest: %d\n",b);
printf("Smallest: %d",d);
}
else if(b>d)
{
printf("Largest: %d\n",b);
printf("Smallest: %d",c);
}
else
{
printf("Largest: %d\n",d);
printf("Smallest: %d",c);
}
}
else if(a>d)
{
if(b>c)
{
printf("Largest: %d\n",b);
printf("Smallest: %d",d);
}
else
{
printf("Largest: %d\n",c);
printf("Smallest: %d",d);
}
}
else
{
if(b>c)
{
if(b>d)
{
printf("Largest: %d\n",b);
printf("Smallest: %d",a);
}
else
{
printf("Largest: %d\n",d);
printf("Smallest: %d",a);
}
}
else if(c>d)
{
printf("Largest: %d\n",c);
printf("Smallest: %d",a);
}
else
{
printf("Largest: %d\n",d);
printf("Smallest:%d",a);
}
}
return 0;
}
【思考】这道题算法是难点,重要在于运用什么可以简化程序,这样写程序虽然也可以实现功能,但是对于思考和纠错都有很大困难。
【简化后】
#include <stdio.h>
int main(void)
{
int a, b, c, d;
printf("Enter your integer: ");
scanf("%d %d %d %d", &a, &b, &c, &d);
int max;
max = a >= b ? a : b;
max = max >= c ? max : c;
max = max >= d ? max : d;
int min;
min = a <= b ? a : b;
min = min <= c ? min : c;
min = min <= d ? min : d;
printf("Largest : %d \n", max);
printf("Smallest : %d \n", min);
return 0;
}
【编程题5.8】
#include <stdio.h>
int main(void)
{
int h,m,t;
printf("Enter the time you want to take off (24-hour-time):");
scanf("%d%d",&h,&m);
t=h*100+m;
if (t<852)
printf("Closest departure time is 8:00 A.M.,arriving at 10:26 A.M.");
else if (t<1032)
printf("Closest departure time is 9:43 A.M.,arriving at 11:52 A.M.");
else if (t<1204)
printf("Closest departure time is 11:09 A.M.,arriving at 1:31 P.M.");
else if (t<1324)
printf("Closest departure time is 12:47 A.M.,arriving at 3:00 P.M.");
else if (t<1453)
printf("Closest departure time is 2:00 P.M.,arriving at 4:08 P.M.");
else if (t<1723)
printf("Closest departure time is 3:45 P.M.,arriving at 5:55 P.M.");
else if (t<2023)
printf("Closest departure time is 7:00 P.M.,arriving at 9:20 P.M.");
else
printf("Closest departure time is 9:45 P.M.,arriving at 11:58 P.M.");
return 0;
}
【思考】书上提示说把时间换算成分钟计算,我认为我的这种写法比书上的说法好,因为更加直观。
另外本题我比较困惑的是题目要求“程序选择起飞时间与用户输入最接近的航班”,也就是说加入有一点的航班和四点的航班,那么两点十分的预计起飞时间就应该推荐一点的航班,但是实际生活中,我们可能更多的需要我预计时间之后的航班,或者人性化一点,从用户角度出发,我应该把前后两趟航班都罗列出来,并且标注价格供用户选择,实际设计程序,我认为实用性和贴近生活性要比算法简洁还重要。
【编程题5.9】
#include <stdio.h>
int main(void)
{
int m1,d1,y1,m2,d2,y2;
printf ("Enter first date(mm/dd/yy):");
scanf ("%d/%d/%d",&m1,&d1,&y1);
printf ("Enter second date(mm/dd/yy):");
scanf ("%d/%d/%d",&m2,&d2,&y2);
if(y1>y2)
{
printf ("%d/%d/%02d is early than %d/%d/%02d.",m2,d2,y2,m1,d1,y1);
}
if(y1<y2)
{
printf ("%d/%d/%02d is early than %d/%d/%02d.",m1,d1,y1,m2,d2,y2);
}
if(y1==y2)
{
if(m1>m2)
{
printf ("%d/%d/%02d is early than %d/%d/%02d.",m2,d2,y2,m1,d1,y1);
}
if(m1<m2)
{
printf ("%d/%d/%02d is early than %d/%d/%02d.",m1,d1,y1,m2,d2,y2);
}
if(m1==m2)
{
if(d1>d2)
{
printf ("%d/%d/%02d is early than %d/%d/%02d.",m2,d2,y2,m1,d1,y1);
}
if(d1<d2)
{
printf ("%d/%d/%02d is early than %d/%d/%02d.",m1,d1,y1,m2,d2,y2);
}
if(d1==d2)
{
printf ("%d/%d/%02d and %d/%d/%02d are the same day.",m1,d1,y1,m2,d2,y2);
}
}
}
return 0;
}
【编程题5.10】
【方法一】
#include <stdio.h>
int main(void)
{
int grade;
printf ("Enter numerical grade:");
scanf ("%d",&grade);
switch (grade/10)
{
case 9: printf("Letter grade: A");
break;
case 8: printf("Letter grade: B");
break;
case 7: printf("Letter grade: C");
break;
case 6: printf("Letter grade: D");
break;
case 5:
case 4:
case 3:
case 2:
case 1:
case 0: printf("Letter grade: F");
break;
}
if (grade>100 || grade<0)
printf("The grade is wrong.");
return 0;
}
【方法二】
#include <stdio.h>
int main(void)
{
int grade,score;
printf ("Enter numerical grade:");
scanf ("%1d%1d",&grade,&score);
switch (grade)
{
case 9: printf("Letter grade: A");
break;
case 8: printf("Letter grade: B");
break;
case 7: printf("Letter grade: C");
break;
case 6: printf("Letter grade: D");
break;
case 5:
case 4:
case 3:
case 2:
case 1:
case 0: printf("Letter grade: F");
break;
}
if (grade>100 || grade<0)
printf("The grade is wrong.");
return 0;
}
【编程题5.11】
#include <stdio.h>
int main(void)
{
int tens_digit,unit_digit;
printf ("Enter a two-digit number:");
scanf ("%1d%1d",&tens_digit,&unit_digit);
if (unit_digit==0)
{
switch (tens_digit)
{
case 9: printf("ninety");
break;
case 8: printf("eighty");
break;
case 7: printf("seventy");
break;
case 6: printf("sixty");
break;
case 5: printf("fifty");
break;
case 4: printf("forty");
break;
case 3: printf("thirty");
break;
case 2: printf("twenty");
break;
case 1: printf("ten");
break;
case 0: printf("zero");
break;
}
}
else
{
switch (tens_digit)
{
case 9: printf("ninety-");
goto one_nine;
case 8: printf("eighty-");
goto one_nine;
case 7: printf("seventy-");
goto one_nine;
case 6: printf("sixty-");
goto one_nine;
case 5: printf("fifty-");
goto one_nine;
case 4: printf("forty-");
goto one_nine;
case 3: printf("thirty-");
goto one_nine;
case 2: printf("twenty-");
goto one_nine;
case 1: goto eleven_nineteen;
case 0: goto one_nine;
}
eleven_nineteen:
switch (unit_digit)
{
case 9: printf("nineteen");
goto done;
case 8: printf("eighteen");
goto done;
case 7: printf("seventeen");
goto done;
case 6: printf("sixteen");
goto done;
case 5: printf("fifteen");
goto done;
case 4: printf("fourteen");
goto done;
case 3: printf("thirteen");
goto done;
case 2: printf("twelve");
goto done;
case 1: printf("eleven");
goto done;
}
one_nine:
switch (unit_digit)
{
case 9: printf("nine");
break;
case 8: printf("eight");
break;
case 7: printf("seven");
break;
case 6: printf("six");
break;
case 5: printf("five");
break;
case 4: printf("four");
break;
case 3: printf("three");
break;
case 2: printf("two");
break;
case 1: printf("one");
break;
}
}
done:
return 0;
}
【编程题6.1】
【问题】
因为float型十进制小数转换为二进制小数的算法是*2取整知道没有小数了为止,但不论如何计算*2是永远不能消灭小数部分的,计算将无线进行下去。局限于浮点型变量的长度,所以精度自然会丢失。
将一个float型转化为内存存储格式的步骤为(Java):
先将这个实数的绝对值化为二进制格式,
(2)将这个二进制格式实数的小数点左移或右移n位,直到小数点移动到第一个有效数字的右边。
(3)从小数点右边第一位开始数出二十三位数字放入第22到第0位。
(4)如果实数是正的,则在第31位放入“0”,否则放入“1”。
(5)如果n 是左移得到的,说明指数是正的,第30位放入“1”。如果n是右移得到的或n=0,则第30位放入“0”。
(6)如果n是左移得到的,则将n减去1后化为二进制,并在左边加“0”补足七位,放入第29到第23位。如果n是右移得到的或n=0,则将n化为二进制后在左边加“0”补足七位,再各位求反,再放入第29到第23位。
对应到本题中,当默认输出6位小时数,最末一位小数可能出现错乱,如图所示100.620003
#include <stdio.h>
int main(void)
{
float a,b;
a=0,b=0;
printf("Enter a number: ");
scanf("%f",&a);
if (a<=0)
printf("The largest number entered was %f",a);
else
{
printf("Enter a number: ");
scanf("%f",&b);
}
judge_b:
if (b<=0)
printf("The largest number entered was %f",a);
else
{
if (a>=b)
{
printf("Enter a number: ");
scanf("%f",&b);
goto judge_b;
}
if (a<b)
{
a=b;
printf("Enter a number: ");
scanf("%f",&b);
goto judge_b;
}
}
return 0;
}
【改进思路】
- 把输入数据拆开来读,将整数、小数两部分读成两个int型
- 尝试用%.xf来表示,读取数据时,计算小数位数,并用x来表示,试验当x 为变量是否会正常运行
- 采用字符串来接收输入数据,因为浮点数是个不精确的数据,如:1.345显示出来可能不是你想象的,有可能是1.344999,所以,采用字符串来作为输入比较合理。
然后采用字符串遍历,计算小数点前的数的个数,再计算小数点后的数的个数,即可实现程序。
(此方法用到后面的内容,目前处理起来稍微困难,可以简单尝试,留到后面进一步改进)
【方法一,尝试,失败】
#include <stdio.h>
int main(void)
{
int z1,x1,z2,x2;
z1=0,z2=0,x1=0,x2=0;
printf("Enter a number: ");
scanf("%d.%d",&z1,&x1);
if (z1<=0)
{
if(x1==0)
printf("The largest number entered was %d",z1);
else
printf("The largest number entered was %d.%d",z1,x1);
}
else
{
printf("Enter a number: ");
scanf("%d.%d",&z2,&x2);
}
judge_b:
if (z2<=0)
{
if(x1==0)
printf("The largest number entered was %d",z1);
else
printf("The largest number entered was %d.%d",z1,x1);
}
else
{
if (z1>z2)
{
z2=0,x2=0;
printf("Enter a number: ");
scanf("%d.%d",&z2,&x2);
goto judge_b;
}
if (z1<z2)
{
z1=z2;
x1=x2;
printf("Enter a number: ");
scanf("%d.%d",&z2,&x2);
goto judge_b;
}
if (z1==z2)
{
if(x1>=x2)
{
z2=0,x2=0;
printf("Enter a number: ");
scanf("%d.%d",&z2,&x2);
goto judge_b;
}
if (x1<x2)
{
z1=z2;
x1=x2;
printf("Enter a number: ");
scanf("%d.%d",&z2,&x2);
goto judge_b;
}
}
}
return 0;
}
【思考】此种方法的确适用于绝大多数数字,但是极端情况为当小数部分为 .0001这种形式,即小数的有效数字之前存在0时,整型变量x会直接忽略0,而输出 .1
这种问题出现的原因是算法本身导致的,因为把小数部分看成整型时,每个小数位的大小关系改变了。
如果尝试嵌套方法二的确定小数位数然后补0,,,同样会因为位数为变量而无法实现。
解决这种问题的办法只能是在scanf时,把小数点后面的一位一位读取,装进不同的变量,然而小数有多少位呢?这种方法肯定可以输出准确的结果,但是对于小数位数有限制。
事实上,我理解这就是字符串思想吧……
【方法二,尝试,失败】
judge_b:
if (b<=0)
{
z=a/1;
x=a-a/1;
for(i = 0;i < 100;i++)
{
if(x*(10^i) >1)
break;
}
printf("The largest number entered was %f",a);
}
【思考】当写成%.if时,由于i是变量,程序无法识别,所以出错,因而定义小数位数时,只能写作% .常量f !!!
【方法三,尝试,有一点问题待修改】
#include <stdio.h>
#include <string.h>
#define NUM_LEN 50
void read_line(char str[],int n);
int main(void)
{
char largest_number[NUM_LEN+1],
current_number[NUM_LEN+1],
stop_number[]="0";
printf("Enter a number: ");
read_line(current_number,NUM_LEN);
strcpy(largest_number,current_number);
while(strcmp(stop_number,current_number)<0)
{
printf("Enter a number: ");
read_line(current_number,NUM_LEN);
if (strcmp(largest_number,current_number)<=0)
strcpy(largest_number,current_number);
}
printf("\nLargest number:%s\n",largest_number);
return 0;
}
void read_line(char str[],int n)
{
int ch,i=0;
while ((ch=getchar()) !='\n')
if (i<n)
str[i++]=ch;
str[i]='\0';
}
【问题】字符串比较时,(默认字符串位数相同,直接先比的第一位大小,再比第二位,该方法未尝试成功,编译出现错误,详细改进方法参考
[C语言][编程]将字符串分割到字符串数组中_hotkitchen的博客-CSDN博客_字符串分割成数组c语言
运用将字符串分割成数组的方法)
#include <stdio.h>
#include <string.h>
#define INT_LEN 50
#define DEC_LEN 50
void read_line(char str[],int n);
int main(void)
{
char large_int_str[INT_LEN+1],
large_dec_str[DEC_LEN+1],
current_int_str[INT_LEN+1],
current_dec_str[DEC_LEN+1],
stop_number[]="0";
printf("Enter a number: ");
read_line(current_int_str,INT_LEN);
read_line(current_dec_str,DEC_LEN);
strcpy(large_int_str,current_int_str);
strcpy(large_dec_str,current_dec_str);
while(strcmp(stop_number,current_int_str)<0)
{
while(strcmp(stop_number,current_dec_str)<0)
{
printf("Enter a number: ");
read_line(current_int_str,INT_LEN);
read_line(current_dec_str,DEC_LEN);
int l_len,c_len;
l_len=strlen(large_int_str);
c_len=strlen(current_int_str);
if(l_len<c_len)
{
strcpy(large_int_str,current_int_str);
strcpy(large_dec_str,current_dec_str);
}
if(l_len==c_len)
{
if (strcmp(large_int_str,current_int_str)<=0)
strcpy(large_int_str,current_int_str);
strcpy(large_dec_str,current_dec_str);
if (strcmp(large_int_str,current_int_str)==0)
{
if (strcmp(large_dec_str,current_dec_str)<=0)
strcpy(large_int_str,current_int_str);
strcpy(large_dec_str,current_dec_str);
}
}
}
}
printf("\nLargest number:%s%s\n",large_int_str,large_dec_str);
return 0;
}
void read_line(char large_int_str[],int n)
{
int i=0,ch;
while ((ch=getchar()) !='\.')
if (i<n)
large_int_str[i++]=ch;
large_int_str[i]='\0';
}
void read_line(char large_dec_str[],int n)
{
int i=0,ch;
while ((ch=getchar()) =='\.'||!='\n')
if (i<n)
large_dec_str[i++]=ch;
large_dec_str[i]='\0';
}
void read_line(char current_int_str[],int n)
{
int i=0,ch;
while ((ch=getchar()) !='\.')
if (i<n)
current_int_str[i++]=ch;
current_int_str[i]='\0';
}
void read_line(char current_dec_str[],int n)
{
int i=0,ch;
while ((ch=getchar()) =='\.'||!='\n')
if (i<n)
current_dec_str[i++]=ch;
current_dec_str[i]='\0';
}
【编程题6.2】
#include <stdio.h>
int main(void)
{
int m,n,remainder;
printf("Enter two integers:");
scanf("%d%d",&m,&n);
judge:
if (n==0)
printf("Greatest common divisor: %d",m);
else
{
remainder=m%n;
m=n;
n=remainder;
goto judge;
}
return 0;
}
【总结】求最大公约数算法
(经典Euclid算法):
分别让变量m、n存储两个数的值,如果n为0,那么停止操作,m中的值是GCD;否则计算m除以n的余数,把n保存到m中,并把余数保存到n中。然后重复上述过程,每次都先判定n是否为0。
【编程题6.3】
#include <stdio.h>
int main(void)
{
int m,n,remainder,numerator,denominator;
printf("Enter a fraction:");
scanf("%d/%d",&m,&n);
numerator=m;
denominator=n;
judge:
if (n==0)
printf("In lowest terms: %d/%d",numerator/m,denominator/m);
else
{
remainder=m%n;
m=n;
n=remainder;
goto judge;
}
return 0;
}
【总结】将分数化为最简算法:
首先计算分子和分母的最大公约数,然后将分子和分母都除以最大公约数。
【编程题6.4】
#include <stdio.h>
int main(void)
{
float commission,value;
start:
printf("Enter value of trade:");
scanf("%f",&value);
if (value==0)
goto done;
else
{
if (value<2500.00f)
commission=30.00f+.017f*value;
else if (value<6250.00f)
commission=56.00f+.0066f*value;
else if (value<20000.00f)
commission=76.00f+.0034f*value;
else if (value<50000.00f)
commission=100.00f+.0022f*value;
else if (value<500000.00f)
commission=155.00f+.0011f*value;
else
commission=255.00f+.0009f*value;
if (commission<39.00f)
commission=39.00f;
printf("Your commissions:$%.2f\n",commission);
goto start;
}
done:
return 0;
}
【编程题6.5】
#include <stdio.h>
int main(void)
{
int number,answer;
printf("Enter a number:");
scanf("%d",&number);
printf("The reversal is:");
do
{
answer=number%10;
printf("%d",answer);
number=number/10;
}
while(number/10!=0);
answer=number%10;
printf("%d",answer);
return 0;
}
【编程题6.6】
#include <stdio.h>
int main(void)
{
int i,number,answer;
printf("Enter a number:");
scanf("%d",&number);
printf("All even squared values:");
for(i=1;answer<number;i++)
{
answer=(i*2)*(i*2);
printf("\n%d",answer);
}
return 0;
}
【编程题6.7】
#include <stdio.h>
int main(void)
{
int i,n,odd,square;
printf("This progrem prints a table of squares.\n");
printf("Enter number of entries in table:");
scanf("%d",&n);
odd=3;
square=1;
for (i=1;i<=n;i++)
{
printf("%10d%10d\n",i,square);
square+=odd;
odd+=2;
}
return 0;
}
【编程题6.8】
#include <stdio.h>
int main(void)
{
int i,j,week,num_day,start_day;
printf("Enter number of days in month:");
scanf("%d",&num_day);
printf("Enter starting day of the week(1=sun,7=sat):");
scanf("%d",&start_day);
printf("\n");
printf(" Your calender:\n");
week=start_day-1;
for(j=1;j<start_day;j++)
{
printf(" ");
}
if (j==start_day)
{
for (i=1;i<=num_day;i++)
{
printf("%3d",i);
week++;
while(week==7)
{
printf("\n");
week-=7;
}
}
}
return 0;
}
【编程题6.9】
#include <stdio.h>
int main(void)
{
float amount_of_loan,monthly_payment,monthly_principal,monthly_principal_and_interest;
int loan_periods,payment_times,interest_rate,ten_times;
printf(" Enter amount_of_loan:");
scanf("%f",&amount_of_loan);
printf(" Enter the loan periods:");
scanf("%d",&loan_periods);
printf("\n Your pending payments:\n\n");
ten_times=6;
start:
for (payment_times=0;payment_times<=loan_periods;payment_times++)
{
//一般利率会与贷款期数有关,此时我假设3期1.5%,6期3%,12期6%,24期12%
interest_rate=loan_periods/2;
monthly_payment=monthly_principal+monthly_principal_and_interest;
monthly_principal=amount_of_loan/loan_periods;
monthly_principal_and_interest=(amount_of_loan-payment_times*monthly_principal)*interest_rate*0.01;
ten_times++;
while (ten_times==8)
{
printf(" Your payments for %2dst month is: $ %8.2f\n",payment_times,monthly_payment);
printf(" Balance remaining after %2dst payment: $ %8.2f\n",payment_times,amount_of_loan-payment_times*monthly_principal);
goto other;
}
while (ten_times==9)
{
printf(" Your payments for %2dnd month is: $ %8.2f\n",payment_times,monthly_payment);
printf(" Balance remaining after %2dnd payment: $ %8.2f\n",payment_times,amount_of_loan-payment_times*monthly_principal);
goto other;
}
while (ten_times==10)
{
printf(" Your payments for %2drd month is: $ %8.2f\n",payment_times,monthly_payment);
printf(" Balance remaining after %2drd payment: $ %8.2f\n",payment_times,amount_of_loan-payment_times*monthly_principal);
ten_times-=10;
goto off;
}
other:
if (ten_times<=7)
{
printf(" Your payments for %2dth month is: $ %8.2f\n",payment_times,monthly_payment);
printf(" Balance remaining after %2dth payment: $ %8.2f\n",payment_times,amount_of_loan-payment_times*monthly_principal);
}
off:
printf("");
}
return 0;
}
【编程题6.10】
#include <stdio.h>
int main(void)
{
int m1,d1,y1,m2,d2,y2,e_m,e_d,e_y;
printf ("Enter a date(mm/dd/yy):");
scanf ("%d/%d/%d",&m1,&d1,&y1);
printf ("Enter a date(mm/dd/yy):");
scanf ("%d/%d/%d",&m2,&d2,&y2);
judge:
if (m1==0 || d1==0 || y1==0)
{
printf ("%d/%d/%02d is the earliest date.",e_m,e_d,e_y);
}
else if (m2==0 || d2==0 || y2==0)
{
printf ("%d/%d/%02d is the earliest date.",e_m,e_d,e_y);
}
else
{
if(y1>y2)
{
e_m=m2,e_d=d2,e_y=y2;
printf ("Enter a date(mm/dd/yy):");
scanf ("%d/%d/%d",&m1,&d1,&y1);
goto judge;
}
if(y1<y2)
{
e_m=m1,e_d=d1,e_y=y1;
printf ("Enter a date(mm/dd/yy):");
scanf ("%d/%d/%d",&m2,&d2,&y2);
goto judge;
}
if(y1==y2)
{
if(m1>m2)
{
e_m=m2,e_d=d2,e_y=y2;
printf ("Enter a date(mm/dd/yy):");
scanf ("%d/%d/%d",&m1,&d1,&y1);
goto judge;
}
if(m1<m2)
{
e_m=m1,e_d=d1,e_y=y1;
printf ("Enter a date(mm/dd/yy):");
scanf ("%d/%d/%d",&m2,&d2,&y2);
goto judge;
}
if(m1==m2)
{
if(d1>d2)
{
e_m=m2,e_d=d2,e_y=y2;
printf ("Enter a date(mm/dd/yy):");
scanf ("%d/%d/%d",&m1,&d1,&y1);
goto judge;
}
if(d1<d2)
{
e_m=m1,e_d=d1,e_y=y1;
printf ("Enter a date(mm/dd/yy):");
scanf ("%d/%d/%d",&m2,&d2,&y2);
goto judge;
}
if(d1==d2)
printf ("%d/%d/%02d and %d/%d/%02d are the same day.",m1,d1,y1,m2,d2,y2);
}
}
}
return 0;
}
【编程题6.11】
#include <stdio.h>
int main(void)
{
int i,n;
float j,e;
printf("Enter the number of n:");
scanf("%d",&n);
for (i=1,j=1,e=1;i<=n;i++)
{
j=j*i;
e=e+1/j;
}
printf("The approximate value of e is: %.20f",e);
return 0;
}
【总结】一开始我在测试时,输出结果始终为2.000000,经过检查发现我把j定义为int型了,导致1/j的结果始终为0,因此要留意计算时,中间变量的类型,粗心可能导致结果错误。
【编程题6.12】
#include <stdio.h>
int main(void)
{
int i;
float j,eta,e;
printf("Enter the number of eta:");
scanf("%f",&eta);
for (i=1,j=1,e=1;;i++)
{
j=j*i;
e=e+1/j;
if (1/j<eta)
goto done;
}
done:
printf("The approximate value of e is: %.20f",e);
return 0;
}