C++: условия (что есть истина?)

Модератор: Модераторы разделов

Аватара пользователя
ArkanJR
Сообщения: 1132

C++: условия

Сообщение ArkanJR »

В опусе Страуструпа "Язык программирования C++" специальное издание (Москва, издательство "БИНОМ" 2005 г.) в главе 2.3.2 "Условия и циклы" нашёл код с примером функции, которая выводит приглашение к вводу и возвращает логическое значение, зависящее от ответа пользователя:

Код: Выделить всё

bool accept();
cout << "Продолжить - y (да) или n (нет)? ";
char answer = 0;
cin >> answer;
if(answer == 'y');
{
return true;
}
return false;
}

Воткнул данный код в программу "Каптёрка":
#include <iostream>
#include <stdlib.h>
using namespace std;
int main()
{
system("clear");
double rRost;
cout << "\x1B[32;1mВведите рост военнослужащего в см:\x1B[0m ";
cout << "\x1B[33;1m";
cin >> rRost;
cout << "\x1B[0m";
if (rRost < 0)
cout << "\x1B[31;1mОшибка! Рост не может быть меньше нуля.\x1B[0m";
if (rRost == 0)
cout << "\x1B[31;1mОшибка! Рост не может быть равен нулю.\x1B[0m";
if (0 < rRost&&rRost < 150)
cout << "\x1B[31;1mОшибка! При росте менее 150 см в ряды ВС РФ не призывают.\x1B[0m";
bool accept();
cout << "\x1B[37;1mПродолжить - y (да) или n (нет)? \x1B[0m";
char answer = 0;
cout << "\x1B[33;1m";
cin >> answer;
cout << "\x1B[0m";
if(answer == 'y');
{
return true;
}
return false;
}

Но при вводе y программа также завершает работу, как и при вводе n.

Кто-нибудь может подсказать в чём тут дело?
— Да, это была ошибка, Кемп, огромная ошибка, что я взялся один за это дело. Напрасно потрачены силы, время, возможности. Один… Удивительно, как беспомощен человек, когда он один! Мелкая кража, потасовка — и всё.

© Г. Уэллс "Человек-невидимка"
Спасибо сказали:

Аватара пользователя
serzh-z
Бывший модератор
Сообщения: 8255
Статус: Маньяк
ОС: Arch, CentOS, Ubuntu

Re: C++: условия

Сообщение serzh-z »

ArkanJR писал(а):
18.09.2014 16:36
Но при вводе y программа также завершает работу, как и при вводе n.
А что ожидалось?
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 18978
Статус: ✡ иностранный агент
ОС: Debian GNU/Linux

Re: C++: условия

Сообщение Bizdelnick »

Во-первых, в первом куске кода явно должна быть { на месте первой ;.
Во-вторых, завершать работу программа должна не так же, а с другим кодом выхода.
В-третьих, чего Вы хотели-то, вызывая return в main()?
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
ArkanJR
Сообщения: 1132

Re: C++: условия

Сообщение ArkanJR »

serzh-z писал(а):
18.09.2014 17:16
А что ожидалось?

Возврат логического значения в зависимости от ответа пользователя (по книге).
— Да, это была ошибка, Кемп, огромная ошибка, что я взялся один за это дело. Напрасно потрачены силы, время, возможности. Один… Удивительно, как беспомощен человек, когда он один! Мелкая кража, потасовка — и всё.

© Г. Уэллс "Человек-невидимка"
Спасибо сказали:

Аватара пользователя
serzh-z
Бывший модератор
Сообщения: 8255
Статус: Маньяк
ОС: Arch, CentOS, Ubuntu

Re: C++: условия

Сообщение serzh-z »

ArkanJR писал(а):
18.09.2014 19:46
Возврат логического значения в зависимости от ответа пользователя (по книге).
Возврат куда? Пардон, но на лицо неверное поставленная цель. Или непонимание...

Если заменить

Код: Выделить всё

if(answer == 'y');
{
return true;
}
return false;
На

Код: Выделить всё

if(answer == 'y')
{
exit(0);
}
exit(1);
То приложение будет возвращать код, по которому можно будет судить о результах его работы. Код можно будет использовать, например, в Bash как "$?".

"bool accept();" - это просто объявление прототипа функции, без её определения и вызова. В цитате, видимо, опечатка.

Определение функции accept, возвращающей true или false будет таким:

Код: Выделить всё

bool accept() {
cout << "Продолжить - y (да) или n (нет)? ";
char answer = 0;
cin >> answer;
if(answer == 'y')
{
return true;
}
return false;
}
Бессмысленный вызов, без проверки возвращёного значения, таким:

Код: Выделить всё

accept();
Спасибо сказали:

Аватара пользователя
serzh-z
Бывший модератор
Сообщения: 8255
Статус: Маньяк
ОС: Arch, CentOS, Ubuntu

Re: C++: условия

Сообщение serzh-z »

P.S.: вообще, имхо, выбранная книга совсем не подходит для обучения основам программирования и логики. Это книга для обучения конкретному языку, его синтаксису и особенностям.
Спасибо сказали:

Аватара пользователя
ArkanJR
Сообщения: 1132

Re: C++: условия

Сообщение ArkanJR »

serzh-z писал(а):
18.09.2014 21:41
Возврат куда? Пардон, но на лицо неверное поставленная цель. Или непонимание...

В книге не уточняется. Я поэтому и вбил один из примеров в программу - посмотреть, что в итоге получится.
— Да, это была ошибка, Кемп, огромная ошибка, что я взялся один за это дело. Напрасно потрачены силы, время, возможности. Один… Удивительно, как беспомощен человек, когда он один! Мелкая кража, потасовка — и всё.

© Г. Уэллс "Человек-невидимка"
Спасибо сказали:

Аватара пользователя
serzh-z
Бывший модератор
Сообщения: 8255
Статус: Маньяк
ОС: Arch, CentOS, Ubuntu

Re: C++: условия

Сообщение serzh-z »

ArkanJR писал(а):
18.09.2014 22:09
В книге не уточняется. Я поэтому и вбил один из примеров в программу - посмотреть, что в итоге получится.
Стоит начать с этого: http://bit.do/SvH8
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 18978
Статус: ✡ иностранный агент
ОС: Debian GNU/Linux

Re: C++: условия

Сообщение Bizdelnick »

ArkanJR писал(а):
18.09.2014 22:09
Я поэтому и вбил один из примеров в программу - посмотреть, что в итоге получится.

Вы не то вбили. Вам нужно было (если я правильно понимаю Вашу цель) всю функцию скопировать, а потом использовать её как-то так:

Код: Выделить всё

if (accept()) {
    ; // какое-то полезное действие
} else {
    exit(1);
}
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
bormant
Сообщения: 1349

Re: C++: условия

Сообщение bormant »

Не надо индусского кода вида if ( true ) return true; else return false; , достаточно

Код: Выделить всё

...
    return answer == 'y';
}
Спасибо сказали:

Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: C++: условия

Сообщение drBatty »

ArkanJR
в C/C++ нет особого встроенного типа bool. Это на самом деле int.

Истинны все значения, которые НЕ равны нулю. Также можно проверять не только int(bool), но и любую переменную, которую можно автоматически преобразовать в int. Например указатель по стандарту конвертируется в (int)0 если он равен NULL, и в не ноль если !=NULL. Во что конкретно — зависит от платформы.

Что касается кодов возвратов, то коды возврата имеют ИНОЙ СМЫСЛ. Истинный только код возврата РАВНЫЙ нулю. Если программа вернул 0, (aka EXIT_SUCCESS), то всё хорошо, задача выполнена. Если код НЕ равен нулю, то произошла ошибка. Коды от 1 до 63 зарезервированны системой, коды >128 говорят о прерывании.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:

Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: C++: условия

Сообщение drBatty »

bormant писал(а):
19.09.2014 07:09
Не надо индусского кода вида if ( true ) return true; else return false; , достаточно

в данном случае правильно как раз:

Код: Выделить всё

int main()
{
        /* … */
        if(answer == 'y')
            return EXIT_SUCCESS;
        return EXIT_FAILURE;
}

ну и ЕМНИП из std::cin приедет 'y\n', а не 'y'.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:

NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: C++: условия

Сообщение NickLion »

drBatty писал(а):
19.09.2014 23:07
в C/C++ нет особого встроенного типа bool. Это на самом деле int.

Не путайте человека. В C нет типа bool (правда, добавили в C99 _Bool), а вот в C++ есть отдельный тип bool. И это не int, ни по размеру (sizeof(bool) <= sizeof(int)), ни по сути. Если в if(выражение) в Си "выражение" приводится к int и производится сравнение на != 0, то в C++ "выражение" приводится к bool. Это имеет значение для пользовательских типов и определённых операторов приведения типа.

Можете проверить на такой программке:

Код: Выделить всё

#include <iostream>

class X
{
public:
    X(int A, bool B);

    operator bool ();
    operator int ();
private:
    int a;
    bool b;
};

X::X(int A, bool B) : a(A), b(B)
{ }

X::operator bool ()
{
    return b;
}

X::operator int ()
{
    return a;
}

int main(int argc, const char *argv[])
{
    X a(1, false);
    X b(0, true);
    std::cout << (int)a << (bool)a
        << (int)b << (bool)b << std::endl;
    if (a)
        std::cout << "a is true" << std::endl;
    else
        std::cout << "a is false" << std::endl;
    std::cout << "b is " << (b ? "true" : "false") << std::endl;
    return 0;
}


Результат:

g++ b.cpp -o b && ./b && rm b

1001 a is false b is true



drBatty писал(а):
19.09.2014 23:14
ну и ЕМНИП из std::cin приедет 'y\n', а не 'y'.

Память немного изменила :) в данном случае вводится один символ, поэтому приедет 'y', два символа приехать не могут. Но может приехать '\n' от предыдущего ввода.
Спасибо сказали:

Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: C++: условия

Сообщение drBatty »

NickLion писал(а):
19.09.2014 23:55
Не путайте человека. В C нет типа bool (правда, добавили в C99 _Bool), а вот в C++ есть отдельный тип bool.

да, точно. Текущий стандарт уже это всё определяет, а вот раньше компилятор ЕМНИП путался на строчках типа

Код: Выделить всё

[code]if(foo)
[code]
когда для foo были доступны как bool(), так и int(). Писал "преобразование неоднозначно". Сейчас проверил, всё собирается.

В любом случае, ИМХО только быдлокодер может надеяться на то, что true==1. Т.ч. на вопрос ТСа ответ

"true это константа типа bool, которая при приведении к (int) даёт ненулевой результат"

А внутри скобок if() действительно ожидается тип bool.

NickLion писал(а):
19.09.2014 23:55
в данном случае вводится один символ,

да. Но в любом случае, если это не 'y' и не 'n', то надо попросить ещё раз ввести.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:

NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: C++: условия

Сообщение NickLion »

drBatty
Опять же, стандарт явно говорит:
(C++11 4.5.6) писал(а):A prvalue of type bool can be converted to a prvalue of type int, with false becoming zero and true becoming one.

Т.е. сама константа true (или результат сравнения <,>,==,!=) при приведении к int должна быть 1 (иначе это не стандарт). Но естественно, истинным является не только значение 1.

Можете проверить, например:

Код: Выделить всё

#include <iostream>

int main(int argc, const char *argv[])
{
    std::cout << (int)(bool)2 << std::endl;
    return 0;
}


Выводит 1 как GCC так и Clang.
Спасибо сказали:

Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: C++: условия

Сообщение drBatty »

NickLion писал(а):
20.09.2014 00:52
Выводит 1

ну мало-ли что выводит ваша текущая версия компилятора? У меня тоже 1. Всё равно надеяться на то, что true==1 это быдлокодерство ИМХО.
NickLion писал(а):
20.09.2014 00:52
Цитата(C++11 4.5.6)

а просто C++? А то в g++ дефолт -std=c++98.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:

Аватара пользователя
/dev/random
Администратор
Сообщения: 5113
ОС: Gentoo

Re: C++: условия

Сообщение /dev/random »

drBatty писал(а):
20.09.2014 05:07
а просто C++? А то в g++ дефолт -std=c++98.


Нет такого "просто C++". А в C++98 так:
(4.7.4) писал(а):If the destination type is bool, see 4.12. If the source type is bool, the value false is converted to zero
and the value true is converted to one.
Спасибо сказали: