Цикл while

Тема в разделе "LANGS.C", создана пользователем Nafanya, 26 июл 2011.

  1. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    Добрый день, друзья.
    Необходима помощь в одном непростом вопросе.

    Как вот такое (C++):

    Код (Text):
    1. {
    2. int i;
    3. while ((i = Func1()) != Func2()) Func3();
    4. }
    записать одной строкой, без нарушения стандарта С++?

    Необходимо как-то внести объявление int i в while, но

    а) while ((int i = Func1()) != Func2()) Func3(); - нельзя
    б) while (int i = Func1() != Func2()) Func3(); - можно, но нарушится порядок, оператор сравнения имеет больший приоритет, чем оператор присваивания и будет выполнен первым.

    Второй вариант - основываясь на стандарте Си++ ISO/IEC 14882:2003 доказать, что это невозможно.

    Вот размышляю...
     
  2. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    while ((int i = Func1()) != Func2()) Func3();
     
  3. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    стр. 125 Стандарта

    6.5 Iteration statements
    Iteration statements specify looping.
    iteration-statement:
    while ( condition ) statement

    Не могу пока найти в стандарте, точное описание condition - это и x>y и int x=5 - всё это condition будет...
     
  4. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    Спасибо, но g++ такую конструкцию не пропускает, ошибка, я уже пробовал.
     
  5. qqwe

    qqwe New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2009
    Сообщения:
    2.914
    for(.., .., .., ; .. ; .., .., ..);
     
  6. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    qqwe
    C for проще:

    Код (Text):
    1. for (int i = Func1(); i != Func2(); i=Func1()) Func3();
    тоже самое - эквивалентно;

    Мне в while надо - либо записать, либо доказать, что невозможно...
     
  7. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    Видимо невозможно записать, по стандарту:

    condition это:
    либо expression
    либо type-specifier-seq declarator = assignment-expression

    Других вариантов нет.
     
  8. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    я чет не понял условие задачи, но помоему наиболее близкое будет что-то типа:
    Код (Text):
    1. while(int i = Func1()) if(i != Func2()) Func3(); else break;
    можно было бы заюзать тернарный оператор, но похоже, что использовать ключевое слово break в тернарном операторе некорректно с точки зрения стандарта:
    Код (Text):
    1. while(int i = Func1()) (i != Func2()) ? Func3() : break;
    а если еще подумать, то вот еще... не совсем корректно, но все же:
    Код (Text):
    1. while(int i = Func1() && i != Func2()) Func3();
    а чтобы исключить выход из цикла при нулевом возврате из Func1 можно сделать такую штуку:
    Код (Text):
    1. while(((int i = Func1()) && 1) && i != Func2()) Func3();
     
  9. qqwe

    qqwe New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2009
    Сообщения:
    2.914
    Rel малость опередил

    мой пример

    while(int i = 0 || ((i=foo1()) != foo2() && foo3() | 1));
     
  10. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    Rel

    Красиво!
     
  11. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    правильно будет такими конструкциями не писать программы...
     
  12. newbie

    newbie New Member

    Публикаций:
    0
    Регистрация:
    2 дек 2008
    Сообщения:
    1.246
    { int i; while ((i = Func1()) != Func2()) Func3(); }
     
  13. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    Rel
    Я Вас успокою, никто так и не пишет, разве не очевидно, что подобными примерами программисты передают концепцию...

    Ваш вариант Rel:
    к сожалению не эквивалентен:
    Переменной i в Вашем варианте, на каждой итерации будет присваиваться значение выражения ( Func1() && i != Func2() )- так уж while работает, а должно присваиваться значение выражения Func1().

    Вот чистый эквивалент - оптимизированный for:
    Код (Text):
    1. for (int i; (i = Func1()) != Func2(); ) Func3();
     
  14. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    Кто-нибудь может сказать, на каких основаниях компилятор gcc не пропускает конструкцию:

    while((int i = func1()) != func2()) func3();

    Где нарушение стандарта - почему конструкцию (int i = func1()) gcc не парсит как expression?
     
  15. valterg

    valterg Active Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    2.105
    Вообще-то gcc - это компилятор с Си. Компилятор с C++ называется g++ :)
     
  16. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    valterg

    gcc test.cpp -lstdc++
    g++ test.cpp
    Эквивалентно. И g++ и gcc компилируют С++ код.

    Суть вопроса в другом.
     
  17. newbie

    newbie New Member

    Публикаций:
    0
    Регистрация:
    2 дек 2008
    Сообщения:
    1.246
    наханя трололо
     
  18. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    скобки поставьте правильно, как в последнем моем варианте...

    не, ну а что трололо-то? допустим такой код собирается gcc и работает как часы:
    Код (Text):
    1. #include <iostream>
    2.  
    3. template <int b> class A
    4. {
    5.     public:
    6.         virtual void Test(int a) { std::cout << "Test A: " << a << " " << b << std::endl; }
    7. };
    8.  
    9. template <int b> class B : public A<b + 100>
    10. { };
    11.  
    12. int main()
    13. {
    14.     int n = 0;
    15.     std::cout << "Hello World!" << std::endl;
    16.     B<200> b;
    17.     b.Test(100);
    18.     std::cin >> n;
    19.     return 0;
    20. }