В принципе, вам необходимо сопоставить символы оператора с операциями.
Ваш текущий код представляет это сопоставление через управление потоком выполнения.
В C++ коллекция стандартной библиотеки map
является хорошим выбором для представления ее как данных, так что вам даже не нужно использовать цикл. В C массив структур, где каждый содержит char
и указатель функции, может выполнять ту же работу. Однако вам необходимо определить функции самостоятельно, потому что в отличие от стандартной библиотеки C++ стандартная библиотека C не предоставляет удобные именованные функции для арифметических операций.
Аналогичным образом, логическое состояние, будь-то является истинным или ложным, может быть представлена в виде позиции или исполнения в виде данных, как правило, в качестве переменной типа bool
. Что выбрать - это главным образом инженерное чувство кишки. Иногда представление через управление потоком является самым простым и понятным, иногда представление как данных является самым простым и понятным.
C++, например, в основном, воспроизводя эффект данного кода примера, но с отображением в качестве данных:
#include <iostream>
#include <functional>
#include <map>
using namespace std;
auto main() -> int
{
const map<char, function<int(int,int)>> op =
{
{ '+', plus<int>() },
{ '-', minus<int>() },
{ '*', multiplies<int>() },
{ '/', divides<int>() }
};
char ch;
cout << "Operator? "; cin >> ch;
cout << "ch = '" << ch << "'\n";
if(op.count(ch) == 0)
{
cout << "invalid operator\n";
}
else
{
const int a = 10;
const int b = 20;
cout << "f = " << op.at(ch)(a, b) << "\n";
}
}
Соответствующий пример C, который действительно включает for
петлю, как упомянуто в вопросе :
#include <stdio.h>
int plus(int a, int b) { return a+b; }
int minus(int a, int b) { return a-b; }
int multiplies(int a, int b) { return a*b; }
int divides(int a, int b) { return a/b; }
typedef int(*Func_ptr)(int, int);
struct Mapping
{
char ch;
Func_ptr f;
};
const struct Mapping op[] =
{
{ '+', plus },
{ '-', minus },
{ '*', multiplies },
{ '/', divides }
};
const int n_ops = sizeof(op)/sizeof(*op);
Func_ptr op_at(char ch)
{
for(int i = 0; i < n_ops; ++i)
{
if(op[i].ch == ch) { return op[i].f; }
}
return NULL;
}
int main()
{
int ch; // Note: type `int` to accommodate EOF value.
printf("Operator? "); ch = getchar();
printf("ch = '%c'\n", ch);
if(op_at(ch) == NULL)
{
printf("invalid operator\n");
}
else
{
const int a = 10;
const int b = 20;
printf("f = %d\n", op_at(ch)(a, b));
}
}
C11, я думаю, что это было, ввели некоторые механизмы для эффективного использования verloading, поэтому их можно использовать так же, как перегруженные функции в C++. Я не очень много помню и не использовал его здесь. Я бы предположил, что если вам нужно обрабатывать разные типы данных, просто используйте разные имена функций.
Обратите внимание, что пример C также компилируется как C++, поэтому оба этих примера являются технически C++. Однако последний пример - в стиле C, используя C-идиомы и C i/o, и делает вещи, которые не нужны в C++. Обычно мы просто говорим, что такой код C, а не C-стиль; такой код может не всегда компилироваться как C++, потому что, в то время как C в основном является подмножеством C++, это два разных отдельных языка: технически нет такой вещи, как C/C++.
Что означает «без использования перерывов» в комментарии? Я вижу хотя бы один перерыв, –
Каков смысл этого кода? Можете ли вы предоставить ввод и ожидаемый результат? –
Что такое цикл 'for' в вашей программе калькулятора, когда выполняется только один случай? –