Я новичок в C ++ и, как и многие другие, здесь, я пытаюсь узнать это из программирования Бьярна Страуструпа — Принципы и практика с использованием C ++.
Я застрял в упражнении 7, глава 4, где идея состоит в том, чтобы написать калькулятор, который, когда ввод либо целое число и / или строка с последующим символ (+, -, * или /), выход должен объявить «сумма / разность / уд / отношение» вход 1 и ввод 2 это результат; так что если («два» 3 *) является входом, выход должен быть «произведение 2 * 3 = 6».
Вот решение Страуструпа (я оставляю комментарии Страуструпа):
— Там нет нарушения авторских прав, так как это все с его сайта —
/*The solution uses two functions (in addition to main():
initialize_numbers() to initialize the vector of number string
representations
get_number() to read a number that is either a string or a sequence of
digits
*/
vector<string> numbers; // representation of numbers as strings
// numbers[i] is the string representation for i
// for numbers[0] to numbers[numbers.size()-1]
void initialize_numbers()
{
numbers.push_back("zero");
numbers.push_back("one");
numbers.push_back("two");
numbers.push_back("three");
numbers.push_back("four");
numbers.push_back("five");
numbers.push_back("six");
numbers.push_back("seven");
numbers.push_back("eight");
numbers.push_back("nine");
numbers.push_back("ten"); // why not? :-)
}
int get_number()
{
const int not_a_symbol = numbers.size(); // not_a_symbol is a value that does not correspond
// to a string in the numbers vector
int val = not_a_symbol;
if (cin>>val) return val; // try to read an integer composed of digits
cin.clear(); // clear string after failed attempt to read an integer
string s;
cin>>s;
for (int i=0; i<numbers.size(); ++i) // see if the string is in numbers
if (numbers[i]==s) val = i;
if (val==not_a_symbol) error("unexpected number string: ",s);
return val;
}
int main()
try
{ initialize_numbers();
cout<< "please enter two floating-point values separated by an operator\n The operator can be + - * / % : ";
while (true) { // "forever"; that is until we give an unacceptable input or make a computations error
int val1 = get_number();
char op = 0;
cin>>op; // get the operator
int val2 = get_number();
string oper; // text appropriate for an operator
double result;
switch (op) {
case '+':
oper = "sum of ";
result = val1+val2;
break;
case '-':
oper = "difference between ";
result = val1-val2;
break;
case '*':
oper = "product of ";
result = val1*val2;
break;
case '/':
oper = "ratio of ";
if (val2==0) error("trying to divide by zero");
result = val1/val2;
break;
case '%':
oper = "remainder of ";
if (val2==0) error("trying to divide by zero (%)");
result = val1%val2;
break;
default:
error("bad operator");
}
cout << oper << val1 << " and " << val2 << " is " << result << '\n';
cout << "Try again: ";
}
}
Более конкретно, моя проблема со следующей частью:
int get_number()
{
const int not_a_symbol = numbers.size(); // not_a_symbol is a value that does not correspond
// to a string in the numbers vector
int val = not_a_symbol;
if (cin>>val) return val; // try to read an integer composed of digits
cin.clear(); // clear string after failed attempt to read an integer
и т. д. и т. д. …
}
Я просто не понимаю, что здесь происходит, в широком контексте. У меня проблемы с пониманием всей этой функции get_number (), и как она связана с остальным кодом.
1 — Зачем присваивать значение number.size () в not_a_symbol? Что это делает?
2 — if (cin >> val) — почему это условно? val == размер вектора чисел, то есть 11, так это условное число 11? Как это полезно?
И что это возвращает? Сам?
3 — // пытаемся прочитать целое число, состоящее из цифр — как это достигается и почему это полезно?
Спасибо, и извините за длинный формат вопроса.
В for
это во всей функции get_number()
i
идет от 0 до одного меньше, чем numbers.size()
и ставит i
где входная строка не содержит цифр по сравнению с одной из строк в numbers
вектор в val
(так что вы конвертируете имя числа в значение числа). После этого вы проверяете, val
такой же, как размер вектора numbers
потому что, если это так, не было совпадения (кто-то ввел слово, которое не является именем какого-либо числа, которое вы можете обработать).
От если (чин >> x) — Почему вы можете использовать это условие? cin>>val
(cin читает из ввода в переменную val) вернет false, если вы ввели хотя бы одну букву.
Если вы вводите число без букв, вы можете его вернуть (нам нужна либо строка, представляющая название числа, либо обычная цифра).
Извини, что забрал твой ответ, чувак, но я понял это сам, и все гораздо проще (и умнее).
Цикл for работает должным образом, сравнивая входные строки со строками внутри вектора и возвращая соответствующий порядковый номер.
Но причина присвоения значению numbers.size () функции not_a_symbol, присваивающей val значение numbers.size (), заключается в том, что, если первый IF завершится неудачно и только тогда, второй станет истинным, поскольку val был уже инициализирован. Вот почему есть 2 отдельных оператора IF вместо IF-ELSE: ELSE не будет делать ранее инициализированный счетчик val, потому что ввод из строки «s» вступит во владение, препятствуя работе с начальным значением val (val = not_a_symbol) внутри ДРУГОГО.
Забудьте о функциях, поместите все это в главное:
int main() {
vector<string> numbers{ "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten" };
int not = numbers.size();
int val = numbers.size(); //val is initialized
string s;
cin >> s;
for (int i = 0; i<numbers.size(); ++i)
if (numbers[i] == s) val = i; // first IF; if this condition is not met, it will return val as it was initialized (val=numbers.size() or 11)
if (val == not) val = 88; // then this condition will be checked. It will be true. It will return val = 88 (a random number);
cout << "val is: " << val << "\n" << "not is: " << not << "\n";
}
Таким образом, речь идет не о сравнении val с числом элементов вектора, а о том, что val уже равен ему, и этот факт действует при невыполнении первого условия.