这段代码目前正在工作,我想知道我是否可以做任何优化或任何事情,以使代码看起来更干净使用函数或诸如此类的,建议是受欢迎的!
#include <cmath>
#include <cstdio>
int prompt(const char* name)
{
printf("%s", name);
int value;
scanf("%d", &value);
return value;
}
int main()
{
int mod, a, b, zbroj, razlika, umnozak, kolicnik;
printf("Mod 1 je za zbrajanje \n");
printf("Mod 2 je za oduzimanje \n");
printf("Mod 3 je za mnozenje \n");
printf("Mod 4 je za dijeljenje \n");
printf("U kojem modu zelis biti: \n");
std::scanf("%d", &mod);
switch (mod)
{
case 1:
printf("Odabrali ste zbrajanje! \n");
a = prompt("a: ");
b = prompt("b: ");
zbroj = a + b;
printf("%d + %d = %d", a, b, zbroj);
break;
case 2:
printf("Odabrali ste oduzimanje! \n");
a = prompt("a: ");
b = prompt("b: ");
razlika = a - b;
printf("%d - %d = %d", a, b, razlika);
break;
case 3:
printf("Odabrali ste mnozennje! \n");
a = prompt("a: ");
b = prompt("b: ");
if(a == 0 or b==0){
printf("Mnozite s nulom, a kad se mnozi s nulom rezultat je uvijek 0: \n");
umnozak = 0;
}
else
{
umnozak = a * b;
}
printf("%d * %d = %d", a, b, umnozak);
break;
case 4:
printf("Odabrali ste dijeljenje! \n");
a = prompt("a: ");
b = prompt("b: ");
if(a == 0 or b==0){
printf("Dijelite s nulom, a kad se dijeli s nulom rezultat je uvijek 0: \n");
kolicnik = 0;
}
else
{
kolicnik = a / b;
}
printf("%d / %d = %d", a, b, kolicnik);
break;
default:
printf("Nemamo tu opciju trenutno, prcekajte za nadogradnju programa, ili se javite developeru! \n");
}
return 0;
}发布于 2019-12-22 15:41:22
以下是一些可以帮助您改进代码的东西。
调用scanf可能失败。您必须检查返回值,以确保没有返回值,或者当给定格式错误的输入或系统资源不足时,程序可能会崩溃(或更糟)。严格的错误处理是大多数工作软件和无错误软件之间的区别。你应该为后者而奋斗。
这里几乎所有的逻辑都是在一个相当长且密集的代码块中的main中。最好将其分解为不同的函数。
using namespace std将using namespace std放在每个程序的顶端是您最好避免的坏习惯。知道什么时候使用它,什么时候不使用它(就像写包含标题的时候一样)。在这个特殊的例子中,我碰巧认为它是非常合适的,因为它是一个短程序,而不是头。有些人似乎认为在任何情况下都不应该使用它,但我的看法是,只要是负责任和充分了解其后果,就可以使用它。
<cstdio>而不是<stdio.h>这两种表单的不同之处在于前者定义了std::命名空间中的东西,而不是全局命名空间中的东西。语言律师对此有很多乐趣,但对于日常使用,我建议使用<cstdio>。详情请参见这个问题。
iostream而不是老式的printfiostream库是更现代的C++实现I/O的方式。更喜欢它而不是printf和scanf。所以,不是这样的:
printf("%d + %d = %d", a, b, zbroj);写这个:
std::cout << a << " + " << b << " = " << zbroj << '\n';;详情请参见SL.io.3。
之前初始化变量
在将mod变量设置为任何值之前将其打印出来。这不太可能有用。更好的做法是始终确保所有变量在使用前都已初始化。
该代码目前包括以下几行:
cout << "U kojem modu kalkulatora zelis biti? \n" << mod;
cout << "Mod 1 je za zbrajanje \n";
cout << "Mod 2 je za oduzimanje \n";
cout << "Mod 3 je za mnozenje \n";
cout << "Mod 4 je za dijeljenje \n";我建议把它写成这样:
std::cout <<
"U kojem modu kalkulatora zelis biti? \n"
"Mod 1 je za zbrajanje \n"
"Mod 2 je za oduzimanje \n"
"Mod 3 je za mnozenje \n"
"Mod 4 je za dijeljenje \n";由于下一行恰好是scanf,我建议您使用prompt函数。
虽然您对and和not的使用在技术上并没有错,但是您应该注意到,许多经验丰富的C++程序员将不熟悉这些操作符替代方案,因此如果其他人阅读了您的代码,这可能会妨碍他们对代码的理解。
我不会说克罗地亚语,但变量名很好,因为它们准确地描述了程序上下文中变量的含义。但是,我建议您可以使用一个变量zbroj, razlika, umnozak, kolicnik来代替rezultat。
case语句中的数学操作都包含非常相似的重复代码。与其重复代码,通常更好的做法是将通用代码转换为函数。唯一变化的是提示符、数学运算和打印结果的方式。一种先进的技术是将它们汇集到一个数据结构中。如果你才刚开始,如果你还不明白,就别担心。它使用lambda表达式和C++17 std::string_view等。我把它放在这里是为了展示C++有多强大:
#include <cmath>
#include <iostream>
#include <string_view>
#include <array>
int prompt(const char* name)
{
std::cout << name;
int value;
std::cin >> value;
return value;
}
int main()
{
struct MathOp {
std::string_view opname;
int (*operate)(int a, int b);
std::string_view opsymbol;
void operator()() const {
std::cout << "Odabrali ste " << opname << "!\n";
int a = prompt("a: ");
int b = prompt("b: ");
int rezultat = operate(a, b);
std::cout << a << opsymbol << b << " = " << rezultat << '\n';
}
};
constexpr std::array<MathOp, 4> op{{
{ "zbrajanje", [](int a, int b){ return a+b; }, " + " },
{ "oduzimanje", [](int a, int b){ return a-b; }, " - " },
{ "mnozenje", [](int a, int b){ return a*b; }, " * " },
{ "dijeljenje", [](int a, int b){
if (b == 0) {
std::cout << "dijeljenje s nulom \n";
return 0;
}
return a/b;
}, " / " },
}};
std::cout << "U kojem modu kalkulatora zelis biti? \n";
for (std::size_t i{0}; i < op.size(); ++i) {
std::cout << "Mod " << i+1 << " je za " << op[i].opname << "\n";
}
unsigned mod;
std::cin >> mod;
if (mod > 0 && mod <= op.size()) {
op[mod-1]();
} else {
std::cout << "Nemamo tu opciju trenutno, prcekajte za nadogradnju programa, ili se javite developeru! \n";
}
}例如,如果我们想要添加指数,我们所需要做的就是向op数组中添加一行:
{ "eksponenciju", [](int a, int b){ return static_cast<int>(std::pow(a,b)); }, " ** " },发布于 2019-12-22 18:12:16
( 1)放置支架时应保持一致。未寄出下列文件:
if(a == 0 or b==0){
printf("Mnozite s nulom, a kad se mnozi s nulom rezultat je uvijek 0: \n");
umnozak = 0;
}
else
{
umnozak = a * b;
}要么写成这样:
if (a == 0 or b==0) {
printf("Mnozite s nulom, a kad se mnozi s nulom rezultat je uvijek 0: \n");
umnozak = 0;
} else {
umnozak = a * b;
}或作为
if (a == 0 or b==0)
{
printf("Mnozite s nulom, a kad se mnozi s nulom rezultat je uvijek 0: \n");
umnozak = 0;
}
else
{
umnozak = a * b;
}你可以选择任何你最喜欢的风格,但你应该坚持它。
2)在使用变量之前不要声明变量。延迟声明变量,直到您真正需要它们。所以而不是
int umnozak;
... some code here ...
umnozak = a * b;你写
int umnozak = a * b;这会导致switch语句的子句中的范围问题,因此它们现在必须被大括号包围。
3)把除法处理得更好。假设4/0= 0,结果是未定义的,这是不正确的。
4)变量zbroj和razlika只使用过一次。大多数情况下,这类变量可以而且应该被消除,这里也是如此。
最后的代码以紧凑的大括号样式格式化,如下所示:
#include <stdio.h>
int prompt(const char* name) {
printf("%s", name);
int value;
scanf("%d", &value);
return value;
}
int main() {
printf("Mod 1 je za zbrajanje\n");
printf("Mod 2 je za oduzimanje\n");
printf("Mod 3 je za mnozenje\n");
printf("Mod 4 je za dijeljenje\n");
printf("U kojem modu zelis biti:\n");
int mod;
scanf("%d", &mod);
switch (mod)
{
case 1: {
printf("Odabrali ste zbrajanje!\n");
int a = prompt("a: ");
int b = prompt("b: ");
printf("%d + %d = %d\n", a, b, a + b);
break;
}
case 2: {
printf("Odabrali ste oduzimanje!\n");
int a = prompt("a: ");
int b = prompt("b: ");
printf("%d - %d = %d\n", a, b, a - b);
break;
}
case 3: {
printf("Odabrali ste mnozennje!\n");
int a = prompt("a: ");
int b = prompt("b: ");
printf("%d * %d = %d\n", a, b, a * b);
break;
}
case 4: {
printf("Odabrali ste dijeljenje! \n");
int a = prompt("a: ");
int b = prompt("b: ");
if (b == 0) {
printf("%d / %d = undefined (divison by zero)\n", a, b);
} else {
printf("%d / %d = %d\n", a, b, a / b);
}
break;
}
default:
printf("Nemamo tu opciju trenutno, prcekajte za nadogradnju programa, ili se javite developeru! \n");
}
return 0;
}https://codereview.stackexchange.com/questions/234477
复制相似问题