none
Вопрос по Switch - Case RRS feed

  • Вопрос

  • Мучаюсь с написанием калькулятора.

    Есть вот такой код.

     public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            int clear;
            decimal result, mresult = 0;
            string op;
    
            int ClearScr(int cl)
            {
                switch (cl)
                {
                    case 1:
                        {
                            label_main.Text = "";
                        }
                        break;
                    case 2:
                        {
                            label_main.Text = "";
                            label_info.Text = "";
                            op = "";
                        } break;
                }
    
                return 0;
            }
    
    
            decimal Calculate(string op)
            {
                clear = 1;
                try
                {
                    switch (op)
                    {
                        case "+": result += Convert.ToDecimal(label_main.Text); break;
                        case "-": result -= Convert.ToDecimal(label_main.Text); break;
                        case "/": result /= Convert.ToDecimal(label_main.Text); break;
                        case "*": result *= Convert.ToDecimal(label_main.Text); break;
                        case "Mod": result = result % Convert.ToDecimal(label_main.Text); break;
                        case "=": break;
                        default: result = Convert.ToDecimal(label_main.Text); break;
                    }
                }
                catch (System.OverflowException)
                {
                    label_info.Text = "";
                    label_info.Text = "Overflow";
                    clear = 2;
                    SystemSounds.Asterisk.Play();
                }
                catch (System.DivideByZeroException)
                {
                    label_info.Text = "";
                    label_info.Text = "Cannot divide by zero";
                    clear = 2;
                    SystemSounds.Asterisk.Play();
                }
                return result;
            }

    Как в принципе работает конструкция Switch я представляю.

    В каждой метке case указывается значение-константа. Управление передаётся разделу переключения, метка case которого содержит

    значение-константу совпадающую со значением выражения переключения

    Есть метод ClearScr, который в зависимости от принимаемого значения cl тем или иным образом очищает экран.

    Но, далее везде по коду для очистки используется переменная clear = 1 , clear = 2; и в зависимости от значения этой переменной происходит очистка. Вот тут совершенно не понятно как эта переменная сlear связана с методом ClearScr 

    вот такую бы запись, я понял бы clear = ClearScr(1) или clear = ClearScr(2)

Ответы

  • Да! Здесь Clear действительно участвует в логике, во многих местах, и поэтому он здесь нужен. Кстати, и в предыдущей версии он тоже нужен в одном единственном месте, в методе buttonNumber_Click, где он является аргументом при обращении к ClearSrc - вначале я этого не заметил. Так что все нормально, кроме сложнятины. Упрощайте - проще жить будет.
    • Помечено в качестве ответа Andrey Langovoy 8 мая 2013 г. 13:27

Все ответы

  • clear у вас никак с ClearScr не связан. где-то должна быть строчка clear = ClearScr(2), скорее всего в catch вместо clear = 2.
    Модератор
  • Приведу весь код

       public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            int clear;
            decimal result, mresult = 0;
            string op;
    
            int ClearScr(int cl)
            {
                switch (cl)
                {
                    case 1:
                        {
                            label_main.Text = "";
                        }
                        break;
                    case 2:
                        {
                            label_main.Text = "";
                            label_info.Text = "";
                            op = "";
                        } break;
                }
    
                return 0;
            }
    
    
            decimal Calculate(string op)
            {
                clear = 1;
                try
                {
                    switch (op)
                    {
                        case "+": result += Convert.ToDecimal(label_main.Text); break;
                        case "-": result -= Convert.ToDecimal(label_main.Text); break;
                        case "/": result /= Convert.ToDecimal(label_main.Text); break;
                        case "*": result *= Convert.ToDecimal(label_main.Text); break;
                        case "Mod": result = result % Convert.ToDecimal(label_main.Text); break;
                        case "=": break;
                        default: result = Convert.ToDecimal(label_main.Text); break;
                    }
                }
                catch (System.OverflowException)
                {
                    label_info.Text = "";
                    label_info.Text = "Overflow";
                    clear = 2;
                    SystemSounds.Asterisk.Play();
                }
                catch (System.DivideByZeroException)
                {
                    label_info.Text = "";
                    label_info.Text = "Cannot divide by zero";
                    clear = 2;
                    SystemSounds.Asterisk.Play();
                }
                return result;
            }
    
            private void button_number_Click(object sender, EventArgs e)
            {
                clear = ClearScr(clear);
                if (label_main.Text.Length < 28)
                    label_main.Text = label_main.Text + ((Button)sender).Text;
                else
                    SystemSounds.Beep.Play();
            }
    
            private void button_Comma_Click(object sender, EventArgs e)
            {
                if (label_main.Text.Contains(','))
                {
                    SystemSounds.Beep.Play();
                }
                else label_main.Text = label_main.Text + ",";
            }
    
            private void button_Equal_Click(object sender, EventArgs e)
            {
                label_info.Text += label_main.Text;
                label_main.Text = Calculate(op).ToString();
                clear = 2;
                label_info.Text = String.Empty;
                op = "=";
            }
    
            private void button_Plus_Click(object sender, EventArgs e)
            {
                label_info.Text += label_main.Text + " + ";
                label_main.Text = Calculate(op).ToString();
                op = "+";
            }
    
            private void button_Minus_Click(object sender, EventArgs e)
            {
                label_info.Text += label_main.Text + " - ";
                label_main.Text = Calculate(op).ToString();
                op = "-";
            }
    
            private void button_Slash_Click(object sender, EventArgs e)
            {
                label_info.Text += label_main.Text + " / ";
                label_main.Text = Calculate(op).ToString();
                op = "/";
            }
    
            private void button_Asterisk_Click(object sender, EventArgs e)
            {
                label_info.Text += label_main.Text + " * ";
                label_main.Text = Calculate(op).ToString();
                op = "*";
            }
    
            private void button_Mod_Click(object sender, EventArgs e)
            {
                label_info.Text += label_main.Text + " Mod ";
                label_main.Text = Calculate(op).ToString();
                op = "Mod";
            }
    
            private void button_1_x_Click(object sender, EventArgs e)
            {
                if (label_info.Text.Contains("reciprocal"))
                {
                    label_info.Text = label_info.Text.Insert(label_info.Text.IndexOf('r'), "reciprocal(");
                    label_info.Text = label_info.Text.Insert(label_info.Text.IndexOf(')'), ")");
                }
                else
                    label_info.Text = label_info.Text + "reciprocal(" + label_main.Text + ")";
                label_main.Text = (1 / Convert.ToDecimal(label_main.Text)).ToString();
            }
    
            private void button_SquareRoot_Click(object sender, EventArgs e)
            {
                if (label_info.Text.Contains("sqrt"))
                {
                    label_info.Text = label_info.Text.Insert(label_info.Text.IndexOf('s'), "sqrt(");
                    label_info.Text = label_info.Text.Insert(label_info.Text.IndexOf(')'), ")");
                }
                else
                    label_info.Text = label_info.Text + "sqrt(" + label_main.Text + ")";
                label_main.Text = Math.Sqrt(Convert.ToDouble(label_main.Text)).ToString();
            }
    
            private void button_Percent_Click(object sender, EventArgs e)
            {
                label_main.Text = (result * Convert.ToDecimal(label_main.Text) / 100).ToString();
                label_info.Text = label_info.Text + label_main.Text;
            }
    
            private void button_PlusMinus_Click(object sender, EventArgs e)
            {
                if (label_main.Text.Contains('-'))
                {
                    label_main.Text = label_main.Text.Remove(label_main.Text.IndexOf('-'), 1);
                }
                else label_main.Text = "-" + label_main.Text;
            }
    
            private void button_CE_Click(object sender, EventArgs e)
            {
                ClearScr(2); clear = 1; label_main.Text = "0"; result = 0;
            }
    
            private void button_C_Click(object sender, EventArgs e)
            {
                ClearScr(1); clear = 1; label_main.Text = "0";
            }
    
            private void button_MS_Click(object sender, EventArgs e)
            {
                mresult = Convert.ToDecimal(label_main.Text);
                clear = 1;
                label_M.Text = "M";
            }
    
            private void button_MR_Click(object sender, EventArgs e)
            {
                label_main.Text = mresult.ToString();
                clear = 1;
            }
    
            private void button_M_plus_Click(object sender, EventArgs e)
            {
                mresult = mresult + Convert.ToDecimal(label_main.Text);
                clear = 1;
            }
    
            private void button_M_minus_Click(object sender, EventArgs e)
            {
                mresult = mresult - Convert.ToDecimal(label_main.Text);
                clear = 1;
            }
    
            private void button_MC_Click(object sender, EventArgs e)
            {
                mresult = 0;
                clear = 1;
                label_M.Text = String.Empty;
            }
    
            private void label1_TextChanged(object sender, EventArgs e)
            {
                if (label_main.Text.Length <= 20)
                {
                    Font font = new Font("Consolas", 14, FontStyle.Regular);
                    label_main.Font = font;
                }
                else if (label_main.Text.Length > 20 && label_main.Text.Length <= 26)
                {
                    Font font = new Font("Consolas", 11, FontStyle.Regular);
                    label_main.Font = font;
                }
                else
                {
                    Font font = new Font("Consolas", 9, FontStyle.Regular);
                    label_main.Font = font;
                }
            }

    Получается, что переменная clear  тут вообще никчему!? Однако, если ее убрать из кода, то вообще ничего не работает...

    И вот такая запись, тоже, получается бесполезна в  private void button_number_Click
    clear = ClearScr(clear);
  • Мне кажется, что Clear - это какой-то атавизм,
    что-то, что имело смысл в начале кодирования,
    но потом, в процессе доработки, утратило свое значение.
    ClearScr в единственном месте возвращает 0 и присвает его переменной Clear,
    в остальных случаях Clear везде, где встречается, принимает значение либо 1, либо 2,
    и при этом нигде не анализируется.
    А вообще программа написана витиевато,
    нужно писать проще - легче разбираться.

    А что такое label_... в Вашей программе?
    Это не текст-боксы случаем?
    • Изменено QazRdx 7 мая 2013 г. 5:05
  • Да, изначально было написано вот так...

     public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            int clear = 1;
            decimal result, mresult = 0;
            string op;
    
            int Clear(int cl)
            {
                switch (cl)
                {
                    case 1:
                        {
                            label1.Text = "";
                        }
                        break;
                    case 2:
                        {
                            label1.Text = "";
                            label2.Text = "";
                            op = "";
                        } break;
                    case 3:
                        {
                            label1.Text = "";
                            label2.Text = label2.Text.Remove(label2.Text.IndexOf('r'));
                        } break;
                    case 4:
                        {
                            label1.Text = "";
                            label2.Text = label2.Text.Remove(label2.Text.IndexOf('s'));
                        } break;
                    case 5:
                        {
                            label1.Text = "";
                            label2.Text = label2.Text.Remove(label2.Text.LastIndexOf(' ') + 1);
                        } break;
                }
    
                return 0;
            }
    
            decimal eval(string op)
            {
                clear = 1;
                try
                {
                    switch (op)
                    {
                        case "+": result = result + Convert.ToDecimal(label1.Text); break;
                        case "-": result = result - Convert.ToDecimal(label1.Text); break;
                        case "/": result = result / Convert.ToDecimal(label1.Text); break;
                        case "*": result = result * Convert.ToDecimal(label1.Text); break;
                        case "Mod": result = result % Convert.ToDecimal(label1.Text); break;
                        default: result = Convert.ToDecimal(label1.Text); break;
                    }
                }
                catch (System.OverflowException) { label2.Text = ""; label2.Text = "Overflow"; clear = 2; SystemSounds.Asterisk.Play(); }
                catch (System.DivideByZeroException) { label2.Text = ""; label2.Text = "Cannot divide by zero"; clear = 2; SystemSounds.Asterisk.Play(); }
                return result;
            }
    
            private void button_0_Click(object sender, EventArgs e)
            {
                clear = Clear(clear);
                if (label1.Text.Length < 28)
                    label1.Text = label1.Text + "0";
                else SystemSounds.Beep.Play();
            }
    
            private void button_1_Click(object sender, EventArgs e)
            {
                clear = Clear(clear);
                if (label1.Text.Length < 28)
                    label1.Text = label1.Text + "1";
                else SystemSounds.Beep.Play();
            }
    
            private void button_2_Click(object sender, EventArgs e)
            {
                clear = Clear(clear);
                if (label1.Text.Length < 28)
                    label1.Text = label1.Text + "2";
                else SystemSounds.Beep.Play();
            }
    
            private void button_3_Click(object sender, EventArgs e)
            {
                clear = Clear(clear);
                if (label1.Text.Length < 28)
                    label1.Text = label1.Text + "3";
                else SystemSounds.Beep.Play();
            }
    
            private void button_4_Click(object sender, EventArgs e)
            {
                clear = Clear(clear);
                if (label1.Text.Length < 28)
                    label1.Text = label1.Text + "4";
                else SystemSounds.Beep.Play();
            }
    
            private void button_5_Click(object sender, EventArgs e)
            {
                clear = Clear(clear);
                if (label1.Text.Length < 28)
                    label1.Text = label1.Text + "5";
                else SystemSounds.Beep.Play();
            }
    
            private void button_6_Click(object sender, EventArgs e)
            {
                clear = Clear(clear);
                if (label1.Text.Length < 28)
                    label1.Text = label1.Text + "6";
                else SystemSounds.Beep.Play();
            }
    
            private void button_7_Click(object sender, EventArgs e)
            {
                clear = Clear(clear);
                if (label1.Text.Length < 28)
                    label1.Text = label1.Text + "7";
                else SystemSounds.Beep.Play();
            }
    
            private void button_8_Click(object sender, EventArgs e)
            {
                clear = Clear(clear);
                if (label1.Text.Length < 28)
                    label1.Text = label1.Text + "8";
                else SystemSounds.Beep.Play();
            }
    
            private void button_9_Click(object sender, EventArgs e)
            {
                clear = Clear(clear);
                if (label1.Text.Length < 28)
                    label1.Text = label1.Text + "9";
                else SystemSounds.Beep.Play();
            }
    
            private void button_Comma_Click(object sender, EventArgs e)
            {
                if (label1.Text.Contains('.'))
                {
                    SystemSounds.Beep.Play();
                }
                else label1.Text = label1.Text + ".";
            }
    
            private void button_Plus_Click(object sender, EventArgs e)
            {
                if (clear == 3 || clear == 4 || clear == 5)
                    label2.Text = label2.Text + " + ";
                else label2.Text = label2.Text + label1.Text + " + ";
                label1.Text = eval(op).ToString();
                op = "+";
            }
    
            private void button_Minus_Click(object sender, EventArgs e)
            {
                if (clear == 3 || clear == 4 || clear == 5)
                    label2.Text = label2.Text + " - ";
                else label2.Text = label2.Text + label1.Text + " - ";
                label1.Text = eval(op).ToString();
                op = "-";
            }
    
            private void button_Slash_Click(object sender, EventArgs e)
            {
                if (clear == 3 || clear == 4 || clear == 5)
                    label2.Text = label2.Text + " / ";
                else label2.Text = label2.Text + label1.Text + " / ";
                label1.Text = eval(op).ToString();
                op = "/";
            }
    
            private void button_Asterisk_Click(object sender, EventArgs e)
            {
                if (clear == 3 || clear == 4 || clear == 5)
                    label2.Text = label2.Text + " * ";
                else label2.Text = label2.Text + label1.Text + " * ";
                label1.Text = eval(op).ToString();
                op = "*";
            }
    
            private void button_Mod_Click(object sender, EventArgs e)
            {
                if (clear == 3 || clear == 4 || clear == 5)
                    label2.Text = label2.Text + " Mod ";
                else label2.Text = label2.Text + label1.Text + " Mod ";
                label1.Text = eval(op).ToString();
                op = "Mod";
            }
    
            private void button_1_x_Click(object sender, EventArgs e)
            {
                if (label2.Text.Contains("reciproc"))
                {
                    label2.Text = label2.Text.Insert(label2.Text.IndexOf('r'), "reciproc(");
                    label2.Text = label2.Text.Insert(label2.Text.IndexOf(')'), ")");
                }
                else
                    label2.Text = label2.Text + "reciproc(" + label1.Text + ")";
                label1.Text = (1 / Convert.ToDecimal(label1.Text)).ToString(); clear = 3;
            }
    
            private void button_SquareRoot_Click(object sender, EventArgs e)
            {
                if (label2.Text.Contains("sqrt"))
                {
                    label2.Text = label2.Text.Insert(label2.Text.IndexOf('s'), "sqrt(");
                    label2.Text = label2.Text.Insert(label2.Text.IndexOf(')'), ")");
                }
                else
                    label2.Text = label2.Text + "sqrt(" + label1.Text + ")";
                label1.Text = Math.Sqrt(Convert.ToDouble(label1.Text)).ToString(); clear = 4;
            }
    
            private void button_Percent_Click(object sender, EventArgs e)
            {
                label1.Text = (result * Convert.ToDecimal(label1.Text) / 100).ToString();
                label2.Text = label2.Text + label1.Text;
                clear = 5;
            }
    
            private void button_PlusMinus_Click(object sender, EventArgs e)
            {
                if (label1.Text.Contains('-'))
                {
                    label1.Text = label1.Text.Remove(label1.Text.IndexOf('-'), 1);
                }
                else label1.Text = "-" + label1.Text;
            }
    
            private void button_Equal_Click(object sender, EventArgs e)
            {
                if (clear != 3 && clear != 4 && clear != 5)
                    label2.Text = label2.Text + label1.Text;
                label1.Text = eval(op).ToString(); clear = 2;
            }
    
            private void button_CE_Click(object sender, EventArgs e)
            {
                Clear(2); clear = 1; label1.Text = "0"; result = 0;
            }
    
            private void button_C_Click(object sender, EventArgs e)
            {
                Clear(1); clear = 1; label1.Text = "0";
            }
    
            private void button_MS_Click(object sender, EventArgs e)
            {
                mresult = Convert.ToDecimal(label1.Text);
                clear = 1;
                label_M.Text = "M";
            }
    
            private void button_MR_Click(object sender, EventArgs e)
            {
                label1.Text = mresult.ToString();
                clear = 1;
            }
    
            private void button_M_plus_Click(object sender, EventArgs e)
            {
                mresult = mresult + Convert.ToDecimal(label1.Text);
                clear = 1;
            }
    
            private void button_M_minus_Click(object sender, EventArgs e)
            {
                mresult = mresult - Convert.ToDecimal(label1.Text);
                clear = 1;
            }
    
            private void button_MC_Click(object sender, EventArgs e)
            {
                mresult = 0;
                clear = 1;
                label_M.Text = String.Empty;
            }
    
            private void label1_TextChanged(object sender, EventArgs e)
            {
                if (label1.Text.Length <= 20)
                {
                    Font font = new Font("Consolas", 14, FontStyle.Regular);
                    label1.Font = font;
                }
                else if (label1.Text.Length > 20 && label1.Text.Length <= 26)
                {
                    Font font = new Font("Consolas", 11, FontStyle.Regular);
                    label1.Font = font;
                }
                else
                {
                    Font font = new Font("Consolas", 9, FontStyle.Regular);
                    label1.Font = font;
                }
            }
        }
    }

    Потом повторяющийся код обработки нажатия числовых кнопок был спрятан в 1 метод. А метод Clear переделан в ClearScr...

    Но все равно и в первоначальной версии присутствует clear = 1; переменная, которая не связана с Clear...

    label.main и label.info - по аналогии с калькулятором в Win 8 (не уверен на счет других версий) Есть основное поле, и сверху, мелким шрифтом - вспомогательное...

  • Да! Здесь Clear действительно участвует в логике, во многих местах, и поэтому он здесь нужен. Кстати, и в предыдущей версии он тоже нужен в одном единственном месте, в методе buttonNumber_Click, где он является аргументом при обращении к ClearSrc - вначале я этого не заметил. Так что все нормально, кроме сложнятины. Упрощайте - проще жить будет.
    • Помечено в качестве ответа Andrey Langovoy 8 мая 2013 г. 13:27
  • Все-равно не очень понятно, как переменная clear вяжется в методом Clear,  кроме как значение, которое заранее присваивается переменной clear подставляется в метод... т.е. я хочу сказать, какой смысл в этой переменной clear и зачем писать вот так

    clear = 1;

    clear = Clear(clear);

    Ведь это равносильно 

    clear = Clear(1)

    И даже при такой записи:

     private void button_8_Click(object sender, EventArgs e)
            {
                clear = Clear(clear);
                if (label1.Text.Length < 28)
                    label1.Text = label1.Text + "8";
                else SystemSounds.Beep.Play();
            }

    ну присвоили переменной clrar значение 1 - и что ? Тут все равно значения переменной clear допустим от 1 до 5 не связаны с case 1 -5.

  • Это же ваш код? Я просто никак не могу понять суть вопроса. Вы объявили поле (не переменную) clear. И спрашиваете на форуме, зачем она нужна. Вопрос "зачем нужна clear и зачем писать вот так" надо задавать самому себе в тот момент, когда пишешь код. А не другим людям на форумне.
    Модератор
  • Не совсем мой... Задался вопросом как сделать калькулятор, чтобы был похож на Win-довый...Т.е не просто в текст боксе цифры показывал, а в 2 строки....Нашел вот такую реализацию...только в том виде в котором она есть она не работает...вернее работает но не совсем корректно... Вот я подсмотрел задумку, и пытаюсь по образу и подобию написать так, чтобы все работало. Как можно видеть в коде выше..кое-что переделано...события кнопок например....