Основы программирования на языке C#

Примеры программ

В качестве первого примера рассмотрим реализацию алгоритма Евклида нахождения наибольшего общего делителя двух чисел. Интерфейс программы представлен на рисунке.

Вычисление наибольшего общего делителя происходит в обработчике щелчка на кнопке "Вычислить".

        private void button1_Click(object sender, EventArgs e)
        {
            long a, b, t;
            a = long.Parse(textBox1.Text);
            b = long.Parse(textBox2.Text);
            while (b > 0)
            {
                t = a % b;
                a = b;
                b = t;
            }
            textBox3.Text = a.ToString();
        }

Профессиональное программирование включает требование: обезопасить программу от ввода некорректных данных, чтобы, к примеру, пользователь не мог оставить поле пустым или вместо чисел ввести буквы. В данном случае это можно сделать заменив простое считывание текстового окна в переменную следующим кодом.

            try
            {
                a = int.Parse(textBox1.Text);
            }
            catch (FormatException)
            {
                MessageBox.Show("Введите число.");
                textBox1.Select();
                return;
            }

Кроме того, чтобы пользователь не имел возможности вводить информацию в окно, предназначенное для вывода, рекомендуется для этого окна установить свойство ReadOnly в True.

Следующий пример демонстрирует эффективный алгоритм возведения в целочисленную степень. Интерфейс программы представлен на рисунке.

Возведение в степень происходит в обработчике щелчка на кнопке "Возвести".

        private void button1_Click(object sender, EventArgs e)
        {
            long a, b, c;
            int n, k;
            a = long.Parse(textBox1.Text);
            n = int.Parse(textBox2.Text);
            k = n;
            b = 1;
            c = a;
            //Инвариантом является
            //a в степени n = b * (c в степени k)
            //Перед циклом (a в степени n = c в степени n)
            while (k > 0)
            {
                if (k % 2 == 0)
                {
                    //c в степени k = (c * c) в степени (k \ 2)
                    k = k / 2;
                    c = c * c;
                }
                else
                {
                    //Один множитель c переходит в b
                    k = k - 1;
                    b = b * c;
                }
            }
            //После цикла (a в степени n = b)
            textBox3.Text = b.ToString();
        }
 

Важно отметить что этот алгоритм может использоваться не только для возведения в целочисленную степень целых чисел, но и других математических объектов, например, матриц.

Следующая программа позволяет вычислить простые множители заданного числа. Ее графический интерфейс представлен на следующем рисунке.

Нахождение множителей осуществляется с помощью следующего алгоритма.

        private void button1_Click(object sender, EventArgs e)
        {
            long n, k, m;
            string s;
            n = long.Parse(textBox1.Text);
            s = "";
            k = n;
            //Инвариант - произведение напечатанных чисел и k равно n
            while (k > 1)
            {
                m = 2;
                //Инвариант - k не имеет делителей в интервале (1, m)
                while ((k % m) > 0)
                {
                    m = m + 1;
                }
                //m - наименьший делитель k больший 1,
                //следовательно, простой
                s = s + m.ToString() + ", ";
                k = k / m;
            }
            s = s.Substring(0, s.Length - 2);
            textBox2.Text = s;
        }
 

При проверке быстродействия программы на случайно выбранных числах складывается впечатление, что программа работает достаточно быстро. Однако чтобы реально оценить быстродействие программы, лучше использовать большие простые числа, например, 2147483647. Отметим, что отсутствие быстрого алгоритма разложения числа на простые множители, используется при создании алгоритмов шифрования с открытым ключом. В данном случае отметим другой факт - при работе с большими простыми числами окно программы перестает реагировать на действия пользователя, что является нежелательным эффектом. Этот эффект является следствием того, что программа является однопоточной. Чтобы программа сохраняла интерактивность при проведении вычислений, необходимо эти действия осществлять в двух разных потоках. Приведем один из примеров того, как это делается.

Откройте конструктор формы. На панели элементов выберите элемент BackgroundWorker и перетащите его на форму. В окне свойств измените его имя (Name) на bgWorker.

В окне кода введите следующий программный код

using System;
using System.ComponentModel;
using System.Windows.Forms;

namespace Mults
{
    public partial class frmMain : Form
    {
        private long nmbIn;
        public frmMain()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            textBox2.Text = String.Empty;
            nmbIn = long.Parse(textBox1.Text);
            bgWorker.RunWorkerAsync(nmbIn);
            button1.Enabled = false;
            // Попробовать простое число - 2147483647
        }

        private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            string s = ComputeMults((long)e.Argument, worker, e);
            e.Result = s;
        }

        string ComputeMults(long n, BackgroundWorker worker, DoWorkEventArgs e)
        {
            // Попробовать простое число - 2147483647
            long k, m;
            string s;
            s = "";
            k = n;
            //Инвариант - произведение напечатанных чисел и k равно n
            while (k > 1)
            {
                m = 2;
                //Инвариант - k не имеет делителей в интервале (1, m)
                while ((k % m) > 0)
                {
                    m = m + 1;
                }
                //m - наименьший делитель k больший 1,
                //следовательно, простой
                s = s + m.ToString() + ", ";
                k = k / m;
            }
            s = s.Substring(0, s.Length - 2);
            e.Result = s;
            return s;
        }

        private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            textBox2.Text = e.Result.ToString();
            button1.Enabled = true;
        }

    }
}

Проверьте поведение этой программы при проведении длительных вычислений. Сравните с предыдущим примером и сделайте вывод.

Следующая программа демонстрирует использование встроенного генератора случайных чисел для имитации бросания игральной кости. Ее графический интерфейс представлен на следующем рисунке.

Сама программа состоит из двух строчек кода.

	private void button1_Click(object sender, EventArgs e)
	{
		Random r = new Random();
		textBox1.Text = r.Next(1, 7).ToString();
	}
Hosted by uCoz