Форум программистов, компьютерный форум CyberForum.ru

Возврат к началу switch - C++

Восстановить пароль Регистрация
 
 
JAson13
0 / 0 / 0
Регистрация: 16.05.2012
Сообщений: 36
02.05.2014, 22:42     Возврат к началу switch #1
Здравствуйте.

Есть программа, включающая в себя
C++
1
2
3
4
5
6
7
8
...
switch(x)
{
case 1: {};
case 2: {};
case n: {};
default: {};
}
Как сделать так, чтобы этот switch выполнялся до тех пор, пока не выберется один из case.

Например, есть меню из 5 пунктов. Как сделать так, чтобы при вводе числа 6 программа не закрывалась, а снова выводила это меню.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DrOffset
6426 / 3800 / 880
Регистрация: 30.01.2014
Сообщений: 6,594
04.05.2014, 01:20     Возврат к началу switch #21
Цитата Сообщение от stawerfar Посмотреть сообщение
На всякий случай если вдруг не знали почитайте в стандарте языка значение оператора inline где вы прочтете что данная команда носит лишь рекомендательный характер в отличие от define. Эти топкости нужно знать. Или просто почаще смотреть понял ли вас компилятор при генерации кода асм
Если ты не понял о чем я говорю, это не значит, что я дурак
Во-первых inline в первом тесте не было вообще. Компилятор сам принял решение о встраивании.
Во-вторых, я пишу одно, а ты читаешь совершенно другое, сам придумываешь, потом сам же разоблачаешь -- нехорошо.
В третьих не надо отправлять меня в стандарт. Эта тема его мало касается. Т.к. мы говорим об оптимизации, а о ней там ни слова.
В четвертых в стандарт я и сам могу кого хочешь отправить

В общем, смотри еще раз:
Цитата Сообщение от DrOffset Посмотреть сообщение
при сохранении возможности "заинлайнить" accept, совершенно неважно что внутри него вызывается
Что тут не понятного?
Я где-то утверждал, что в случае невозможности встроить accept код будет другим?
Вот ты пишешь:
Цитата Сообщение от stawerfar Посмотреть сообщение
Попробуй в тело switch добавить пару функций да так что бы значения результатов было трудно прогназируемо
А я говорю, что добавление чего-то в тело switch не повлияет в целом на работу, если только мы не создадим условия, при которых невозможно будет встроить accept. Обеспечение эти условий - это отдельный разговор, и я даже не пытался его касаться.
Пример, я специально его не писал, потому что я знал что будет, а не потому что мне лень или еще что. Но раз ты так хочешь, то вот:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
extern "C" int foo1(); // эти функции определены в другой единице трансляции
extern "C" int foo2(); // поэтому компилятор НЕ может предположить что-то об их результате, как ты и хотел
 
extern "C" int test1()
{
    int x = 0;
    bool run = true;
 
    while(run)
    {
        run = false;
        std::cin >> x;
 
        switch(x)
        {
        case 1: run = foo1() != 2; break;
        case 2: run = foo2() != 1; break;
        case 3: break;
        default:
            run = true;
        }
    }
    return 0;
}
 
inline bool accept(int x)
{
    switch(x)
    {
    case 1:
        return foo1() != 2;
    case 2:
        return foo2() != 1;
    case 3:
        return true;
    default:
        return false;
    }
}
 
extern "C" int test2()
{
    int x = 0;
    while( std::cin >> x, !accept(x) );
    return 0;
}
 
int main()
{
}
Вот что получилось.
Это код БЕЗ функции. Цифрами пронумерованы прыжки.
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
_test1:
    push    ebx
    sub esp, 40
    mov DWORD PTR [esp+28], 0
    lea ebx, [esp+28]
L14:
    mov DWORD PTR [esp], ebx
    mov ecx, OFFSET FLAT:__ZSt3cin
    call    __ZNSirsERi
    push    eax
    mov eax, DWORD PTR [esp+28]
    cmp eax, 2
    je  L6  ;#1
    cmp eax, 3
    je  L7  ;#2
    dec eax
    jne L14 ;#3
    call    _foo1
    cmp eax, 2
    setne   al
L8:
    test    al, al
    jne L14 ;#4
L7:
    xor eax, eax
    add esp, 40
    pop ebx
    ret
L6:
    call    _foo2
    dec eax
    setne   al
    jmp L8  ;#5
Вот код с функцией:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
_test2:
    push    ebx
    sub esp, 40
    mov DWORD PTR [esp+28], 0
    lea ebx, [esp+28]
L32:
    mov DWORD PTR [esp], ebx
    mov ecx, OFFSET FLAT:__ZSt3cin
    call    __ZNSirsERi
    push    edx
    mov eax, DWORD PTR [esp+28]
    cmp eax, 2
    je  L20 ;#1
    cmp eax, 3
    je  L21 ;#2
    dec eax
    jne L32 ;#3
    call    _foo1
    cmp eax, 2
    setne   al
L22:
    test    al, al
    je  L32 ;#4
L21:
    xor eax, eax
    add esp, 40
    pop ebx
    ret
L20:
    call    _foo2
    dec eax
    setne   al
    jmp L22 ;#5
Компилятор mingw 4.7.2. Опции -02, -save-temps, -masm=intel.
Я намеренно допустил мааленькое расхождение в двух примерах. В первом примере результат сравнения с foo1() и foo2() берется без инверсии, а во втором - с инверсией (помним про !accept() в цикле). Эта разница хорошо видна на метке #4. На этом различия (ну кроме имен меток, естественно) заканчиваются.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
stawerfar
 Аватар для stawerfar
141 / 55 / 4
Регистрация: 14.12.2010
Сообщений: 347
Записей в блоге: 1
04.05.2014, 01:39     Возврат к началу switch #22
Большинство споров из за того что люди говорят совершенно о разных вещах. Ладно я понял что ты имел введу пожалуй пора заканчивать с этим. Спасибо за диалог
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.05.2014, 01:53     Возврат к началу switch
Еще ссылки по теме:

C++ Как вернуться к началу функции?
Найти ближайшую к началу координат точку C++
C++ Какая из точек находится ближе к началу координат: составить алгоритм

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
DrOffset
6426 / 3800 / 880
Регистрация: 30.01.2014
Сообщений: 6,594
04.05.2014, 01:53     Возврат к началу switch #23
В общем, я для ясности хочу вот что добавить.
1) Я знаю, что компилятор может не встроить функцию.
2) Я знаю, что теоретически эти примеры могли бы быть совсем разными (если взять какой-нибудь gcc 2.95 - это точно будет так)
3) Я знаю, что рассчитывать только на компилятор и писать говнокод в надежде на оптимизацию - это плохо.
Но, я так же знаю, что:
1) "Преждевременная оптимизация корень всех зол".
2) Современные компиляторы достаточно умны, чтобы генерировать оптимальный машинный код из кода с приемлемым количеством абстракций, увеличивающих читаемость. Т.е. не обязательно сейчас (в 2014 году), имея современные инструменты, писать приближенный к ассемблеру код, как это было принято раньше. Однако это не значит, что это дает нам право впадать в крайности (см п.3 первого абзаца).

В общем, пойнт в том, что код который дал Tulosba НЕ является крайностью и НЕ является гонокодом, т.к. содержит минимальный необходимый набор абстракций для увеличения читаемости кода, но в то же время позволяет компилятору провести все необходимые оптимизации на том же уровне, что и в коде без таких абстракций. Это то, чего достигла современная индустрия, мы теперь можем писать чуть более высокоуровневый код, без опасения, что он будет неоптимален. В конце концов текст программы пишется и для человека тоже. Его потом нужно сопровождать и понимать другим людям.
Поэтому сейчас всем известные классики пишут, и я с ними согласен на 100%, что если не дано специальных условий, приемлемым подходом будет писать код максимально точно описывающий и решающий задачу, а не код, который будет выигрывать такты и байты, при этом маскируя и размазывая алгоритм в своих деталях (за деревьями не видно леса - пословица очень в тему). А решение об оптимизации принимать уже после профилирования.
Yandex
Объявления
04.05.2014, 01:53     Возврат к началу switch
Ответ Создать тему
Опции темы

Текущее время: 12:31. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru