|
前次发贴,以下程序编译不能通过,后经lanche指点,才知是犯了两个低级错误 ,改后就能顺利编译了。但是程序本身还有bug.现发帖以供大家讨论学习(比较长,请耐心看下去)。源程序如下:
////////////////////////////////////////////////
//compute.c:简单计算器
////////////////////////////////////////////////
#include<stdio.h>
//#include<string.h>
//#include<stdlib.h>
double sum(double a,double b);
double subtract(double a,double b);
double multiply(double a,double b);
double divide(double a,double b);
double remainder(double a,double b);
int main(void)
{
int choice;
double a,b;
double (*func)();
while(1)
{
printf("\n*****************************************");//输入提示询息
printf("\n1.sum");
printf("\n2.subtract");
printf("\n3.multiply");
printf("\n4.divide");
printf("\n5.remainder");
printf("\nInput a choice(any other key to exit):");
//fflush(stdin);
choice=getc(stdin)-'0';
//choice=getchar()-'0';
//choice=getche();
switch(choice)
{
case 1:
func=sum;
break;
case 2:
func=subtract;
break;
case 3:
func=multiply;
break;
case 4:
func=divide;
break;
case 5:
func=remainder;
default:
return;
}
printf("\n\nPlease input a:");
scanf("%lf",&a);
printf("Pleast input b:");
scanf("%lf",&b);
printf("\nThe result is:%lf.\n",(*func)(a,b));
//fflush(stdin);
//choice=0;
}
return 0;
}
double sum(double a,double b)
{
return a+b;
}
double subtract(double a,double b)
{
return a-b;
}
double multiply(double a,double b)
{
return a*b;
}
double divide(double a,double b)
{
return a/b;
}
double remainder(double a,double b)
{
return (int)a%(int)b;
}
该程序运行后,第一次运算很正常。但是第一次运算结束后,就直接退出了程序,根本没有进行第二次运算选择的机会 。运行如下:
[chenye@chenye chenye]$ ./compute2(注:compute2是可执行文件名)
*****************************************
1.sum
2.subtract
3.multiply
4.divide
5.remainder
Input a choice(any other key to exit):1(注意这里:能进行第一次运算选择)
Please input a:2
Pleast input b:3
The result is:5.000000.
*****************************************
1.sum
2.subtract
3.multiply
4.divide
5.remainder
Input a choice(any other key to exit):[chenye@chenye chenye]$(看:自动退出程序了)
我的分析如下:
1.getc(stdin)或getchar() (两者作用一样)都是从输入缓冲队列中取下一个字符。而当延第一次进行运算方式选择后,随后输入回车。然后又输入2(a的值),3(b的值),所以在第二次进行输入运算选择时,输入缓冲队列其实并不为空,所以getc(stdin)或getchar()自动从输入缓冲队列中取数值,而不必等待用户的输入。这样,choice的值自然不是1至5了,所以程序自动退出。
2.根据以上分析,我在choice=getc(stdin)-'0';语句前加了一句fflush(stdin); ,目的是清空输入缓冲队列,使getc(stdin)必须等待用户输入,可是结果和没加fflush(stdin)一样。
这个问题我一直没想通,为什么fflush(stdin)没有把输入缓冲区清空呢?
3.我在第一次运算方式选择时输入12,这时发现运算方式为1(即加法运算),可是a的值已自动被赋为2.这是不是说明:scanf和getc(或getchar)一样,其实都是从输入缓冲队列中取值,如果输入缓冲队列不为空,有数值,则scanf不会等待用户输入,而是直接从输入缓冲队列中取值。运行结果如下:
[chenye@chenye chenye]$ ./compute2
*****************************************
1.sum
2.subtract
3.multiply
4.divide
5.remainder
Input a choice(any other key to exit):12(注意:我在这步输入12)
Please input aleast input b:3(这里a不是用户输入)
The result is:5.000000.(可见a的值为2,运算方式为1即加法)
*****************************************
1.sum
2.subtract
3.multiply
4.divide
5.remainder
Input a choice(any other key to exit):[chenye@chenye chenye]$
4.我用gdb调试,在 choice=getc(stdin)-'0';句设置了一个断点,并观察choice的值,发现在进行第二次运算方式选择时,choice的值总是为-38(这也难怪会自动退出程序了)。我觉得应该为-35,因为我在输入数字后总是输入回车,而回车的ascii值为13,所以choice=13-'0'=-35.为什么是-38呢?
5.在用gdb进行单步调试时,我发现了一个怪现象。在调至printf("\n\nPlease input a:"); scanf("%lf",&a); printf("Pleast input b:"); scanf("%lf",&b);时,执行printf语句后并不立即输出Please input a:,而是在执行完scanf("%lf",&a);语句后才输出Please input a:。这是为什么?
运行情况如下:
53 printf("\n\nPlease input a:");
(gdb)
//为什么不是在这里输出Please input a:呢?
54 scanf("%lf",&a);
(gdb)
Please input a
顺便问一下,各位在linux编程及调试大都用什么工具? |
|