C程序制作一个计算器,可以执行简单的算术并在int和双精度变量之间切换



我对c编程有点陌生。对于我的项目,我的任务是开发一个简单的计算器,该计算器要求用户输入一个选项,然后该选项声明要执行的操作(即,如果用户输入 1,这对应于选择加法选项,然后允许用户添加他们选择的两个数字。我已经完成了大部分代码,但问题是我需要计算器在 int 和双精度变量之间切换。当用户输入 5 时,计算器现在应该使用整数,然后如果用户再次点击 5,计算器就会切换回双精度,反之亦然,只要您想来回切换。计算器自动使用双精度。所以,更具体地说,如果我想使用整数变量,我会输入 5,然后假设我想切换回双精度,我应该输入 5 并收到消息"计算器现在可以使用双精度"。所以这是我到目前为止的代码:

#include<stdio.h>
#include<math.h>
#include<stdbool.h>
int main()
{
int integermode, doublemode, m, a, b, sum2, difference2, product2, 
quotient2;
double i, j, sum1, difference1, product1, quotient1;
printf("This program implements a calculator.");
while(m !=6) {
printf("Options:n");
printf("1 - additionn2 - subtractionn3 - multiplicationn4 - divisionn5 - toggle calculator typen6 - exit programn");
printf("Please enter your option: ");
scanf("%d", &m);
if(m > 6) {
printf("Invalid option.n");
printf("Options:n");
printf("1 - additionn2 - subtractionn3 - multiplicationn4 - divisionn5 - toggle calculator typen6 - exit programn");
printf("Please enter your option: ");
scanf("%d", &m);
}
switch (m) {
case 1: 
if (integermode == true) {
printf("Enter first term: ");
scanf("%d", &a);    
printf("Enter second term: ");
scanf("%d", &b);
printf("The sum is: %dn", a+b);
break;
}
if (integermode == false) {
printf("Enter first term: ");
scanf("%lf", &i);   
printf("Enter second term: ");
scanf("%lf", &j);
printf("The sum is: %.15lfn", i+j);
}
break;  
case 2: 
if (integermode == true) {
printf("Enter first term: ");
scanf("%d", &a);    
printf("Enter second term: ");
scanf("%d", &b);
printf("The difference is: %dn", a-b);
break;
}
if (integermode == false) {
printf("Enter first term: ");
scanf("%lf", &i);   
printf("Enter second term: ");
scanf("%lf", &j);
printf("The difference is: %.15lfn", i-j);
}
break;  
case 3: 
if (integermode == true) {
printf("Enter first term: ");
scanf("%d", &a);    
printf("Enter second term: ");
scanf("%d", &b);
printf("The product is: %dn", a*b);
break;
}
if (integermode == false) {
printf("Enter first term: ");
scanf("%lf", &i);   
printf("Enter second term: ");
scanf("%lf", &j);
printf("The product is: %.15lfn", i*j);
}
break;  
case 4: 
if (integermode == true) {
printf("Enter first term: ");
scanf("%d", &a);    
printf("Enter second term: ");
scanf("%d", &b);
if (b != 0) printf("The quotient is: %dn", a/b);
if (b == 0) printf("Cannot divide by zero!n");
break;
}
if (integermode == false) {
printf("Enter first term: ");
scanf("%lf", &i);   
printf("Enter second term: ");
scanf("%lf", &j);
if(j != 0) printf("The quotient is: %.15lfn", i/j);
if(j == 0) printf("Cannot divide by zero!n");
break;
}
case 5: 
if (m = 5) {
integermode = true;
printf("Calculator now works with integers.n");
}
if (m != 5) integermode = false;
}
} 
return 0;
}

一般改进

首先,你应该注意到你的主函数对于它需要完成的事情来说是巨大的,并且需要大量的缩进级别(当正确缩进时)。这主要是因为您有大量重复的功能。您可以轻松地将要求输入数字的代码提取到函数中并重用它,仅更改在每种情况下执行的操作。或者更好的是,您可以要求输入数字作为主while循环的一部分,然后根据您所处的操作模式对它们执行不同的操作。

您没有使用<math.h>,因此您可以将其排除在外。

我注意到的另一件事是,在 while 循环中使用m变量之前,您不会对其进行初始化。这可能会导致很多问题,因此您应该将其初始化为某个不是有效模式的值,例如 0 或 -1。

当可以使用if/else时,您还使用了两个连续的if语句。

if (integermode == true) {
.....
}
if (integermode == false) {
.....
}

if (integermode == true) {
.....
} else {
.....
}

但更难阅读,效率更低,因为你在做两个比较而不是一个。


双精度/整数模式的实现

关于你想要实现的功能,你可以很好地定义一个具有可能模式的枚举:

typedef enum _datamode {
INTEGER_MODE,
DOUBLE_MODE
} data_mode;

然后有一个变量保持当前模式:

data_mode datamode = INTEGER_MODE /* Initializing this to the default mode */

然后在计算和输出过程中使用整数或双精度,具体取决于变量的当前值。当然,这可以用更短的方式用整数而不是enumtypedef来完成,但我发现这是一种更冗长的方式。

对于输入和结果,您可以使用unionC 类型,该类型为您在其中指定的最大类型保留内存,并允许您在其中存储其中的任何类型。例如:

union io {
int i;
double d;
} a, b, result;

声明三个将io联合为类型的变量。这样,您可以根据需要将它们用作整数或双精度值(只要您不混合类型,例如,存储整数并将其读取为双精度)


全面工作实施

以下是我对您必须做的程序的实现。它可以以更短的方式完成(考虑到处理枚举的开关占用了总空间的相当一部分),但我认为这更加优雅和冗长。

我尊重您的打印语句和应用程序流程,即使我认为它们可以更好(也许这是您的作业强加给您的?

请以此为契机学习,不要只是复制粘贴代码。

#include <stdio.h>
#include <stdlib.h>
typedef enum _datamode {
INTEGER_MODE,
DOUBLE_MODE
} data_mode;
typedef enum _operationmode {
ADDITION,
SUBSTRACTION,
MULTIPLICATION,
DIVISION,
TOGGLE,
EXIT
} operation_mode;
operation_mode ask_mode () {
int input = -1;
while (1) {
printf("Options:n");
printf("1 - additionn2 - subtractionn3 - multiplicationn4 - divisionn5 - toggle calculator typen6 - exit programn");
printf("Please enter your option: ");
scanf("%i", &input);
if (input < 1 || input > 6) {
printf("Invalid option.n");
} else {
switch (input) {
case 1:
return ADDITION;
case 2:
return SUBSTRACTION;
case 3:
return MULTIPLICATION;
case 4:
return DIVISION;
case 5:
return TOGGLE;
case 6:
return EXIT;
default:
exit(EXIT_FAILURE); /* Error must've occurred in order for a different value to be present */
}
}
}
}
union _io {
int i;
double d;
};
void get_inputs_integer (int *a, int *b) {
printf("Enter first term: ");
scanf("%i", a);    
printf("Enter second term: ");
scanf("%i", b);
}
void get_inputs_double (double *a, double *b) {
printf("Enter first term: ");
scanf("%lf", a);    
printf("Enter second term: ");
scanf("%lf", b);
}
int main (int argc, char **argv) {
union _io operand1, operand2, result;
operation_mode o_mode;
data_mode d_mode = INTEGER_MODE;
printf("This program implements a calculator.");
do {
o_mode = ask_mode();
if (o_mode == TOGGLE) {
if (d_mode == INTEGER_MODE) {
d_mode = DOUBLE_MODE;
printf("Calculator now on double moden");
} else {
d_mode = INTEGER_MODE;
printf("Calculator now on integer moden");
}
} else if (o_mode != EXIT) {
if (d_mode == INTEGER_MODE) {
get_inputs_integer(&operand1.i, &operand2.i);
switch (o_mode) {
case ADDITION:
result.i = operand1.i + operand2.i;
break;
case SUBSTRACTION:
result.i = operand1.i - operand2.i;
break;
case MULTIPLICATION:
result.i = operand1.i * operand2.i;
break;
case DIVISION:
result.i = operand1.i / operand2.i;
break;
default:
exit(EXIT_FAILURE); /* Error must've occurred in order for a different value to be present */
}
printf("The result is %in", result.i);
} else {
get_inputs_double(&operand1.d, &operand2.d);
switch (o_mode) {
case ADDITION:
result.d = operand1.d + operand2.d;
break;
case SUBSTRACTION:
result.d = operand1.d - operand2.d;
break;
case MULTIPLICATION:
result.d = operand1.d * operand2.d;
break;
case DIVISION:
result.d = operand1.d / operand2.d;
break;
default:
exit(EXIT_FAILURE); /* Error must've occurred in order for a different value to be present */
}
printf("The result is %lfn", result.d);
}
}
} while (o_mode != EXIT);
}

最新更新