Приложение first // Строка using namespace System является декларацией того, // что имена классов из пространства имен System, // которые используются далее (например, String или Console), // могут писаться кратко. // Вместо полного имени System::String будет писаться краткое имя String. using namespace System; // Код, написанный далее, структурирован. // В нем выделены функции, выполняющие определенные действия. // Функции выделяют участки кода, // которые могут многократно использоваться путем вызова функции. // Описание функции требует: // 1. указания возвращаемого типа // (в большинстве функций этого примера возвращаемый тип есть void (пустота) // функция не возвращает какой-либо объект; // только функции Sum и infSeriesSum возвращает объект типа double) // 2. идентификатора имени (например ReadWrite) // 3. круглые скобки (в них перечисляются параметры функции, если они есть; // в большинстве функций в этом примере нет параметров, // кроме функций Sum и infSeriesSum). // 4. фигурные скобки, внутри которых помещаются операторы, // для выполнения которых функция предназначена. /// <summary> /// Описывает переменные простых встроенных типов - строка, целое число, /// число с плавающей запятой. /// Вводит с клавиатуры и выводит на экран значения переменных этих типов. /// </summary> void ReadWrite() { // Описание строк String ^s1,^s2; s1="Это 1-ая строка"; s2="Это 2-ая строка"; // Вывод строк на экран Console::WriteLine("Вывод на экран суммы двух строк"); Console::WriteLine(s2+s1); Console::Write("Введи строку:"); // Ввод строк с клавиатуры String ^s; s= Console::ReadLine(); Console::WriteLine("Я ввел строку "+s); // Целые числа Int32 i;// или int i; Console::Write("Введи целое число:"); 1 // Ввод целых чисел String ^si=Console::ReadLine(); i=int::Parse(si); //или Convert::ToInt32(si); // Вывод целого числа на экран с комментарием Console::WriteLine("i = "+i); // Ввод и вывод чисел с плавающей запятой Console::Write("Введи вещественное число:"); Double d=Double::Parse(Console::ReadLine()); Console::WriteLine("d = {0},4xd = {1}",d,4*d); } /// <summary> /// Описывает операции над переменными простых встроенных типов – /// строка, целое число, число с плавающей запятой. /// </summary> void Operators() { // Операции над строками Console::WriteLine("Операции над строками"); String ^s1,^s2; Console::Write("Введи строку s1 "); s1= Console::ReadLine(); Console::Write("Введи строку s2 "); s2=Console::ReadLine(); Console::WriteLine( "Строка s1 = {0}; строка s2 = {1}; \n сумма строк s1 + s2 = {2};\n"+ "Операции сравнения строк \n s1 == s2 = {3}; s1 != s2 = {4}", s1,s2,s1+s2,s1==s2,s1!=s2); // Операции над целыми числами Console::WriteLine("Операции над целыми числами"); int i1,i2; Console::Write("Введи целое число i1 = "); i1=int::Parse(Console::ReadLine()); Console::Write("Введи целое число i2 = "); i2=int::Parse(Console::ReadLine()); Console::WriteLine("Операнды: i1 = {0}; i2 = {1};\n"+ "Арифметические операции \n"+ "i1 + i2 = {2}; i1 - i2 = {3}; i1 * i2 = {4}; i1 / i2 = {5}; i1 % i2 = {6};\n"+ "Операции сравнения\n"+ "i1 > i2 = {7}; i1 <= i2 = {8}; i1 == i2 = {9}; i1 != i2 = {10}", i1,i2,i1+i2,i1-i2,i1*i2,i1/i2,i1%i2,i1>i2,i1<=i2,i1==i2,i1!=i2); // Операции над числами с плавающей запятой Console::WriteLine("Операции над числами с плавающей запятой"); Double d1,d2; Console::Write("Введи число с плавающей запятой d1 = "); d1=Double::Parse(Console::ReadLine()); Console::Write("Введи число с плавающей запятой d2 = "); d2=Double::Parse(Console::ReadLine()); Console::WriteLine("Операнды: d1 = {0}; d2 = {1};\n"+ 2 "Арифметические операции \n"+ "d1 + d2 = {2}; d1 - d2 = {3}; d1 * d2 = {4}; d1 / d2 = {5}; \n"+ "Операции сравнения\n"+ "d1 > d2 = {6}; d1 <= d2 = {7}; d1 == d2 = {8}; d1 != d2 = {9}", d1,d2,d1+d2,d1-d2,d1*d2,d1/d2,d1>d2,d1<=d2,d1==d2,d1!=d2); // Операции над переменными логического типа Console::WriteLine("Операции над переменными логического типа true, false"); bool b1,b2; Console::Write("Введи логическую переменную b1 (true или false) = "); b1=bool::Parse(Console::ReadLine()); Console::Write("Введи логическую переменную b2 (true или false) = "); b2=bool::Parse(Console::ReadLine()); Console::WriteLine("Операнды: b1 = {0}; b2 = {1};\n"+ "Логические операции: \"или\" ||, \"и\" &&, \"исключающее или\" ^ \n"+ "b1 || b2 = {2}; b1 && b2 = {3}; b1 ^ b2 = {4}; \n"+ "Операции сравнения\n"+ "b1 > b2 = {5}; b1 <= b2 = {6}; b1 == b2 = {7}; b1 != b2 = {8}", b1,b2,b1||b2,b1&&b2,(bool)( b1^b2),b1>b2,b1<=b2,b1==b2,b1!=b2); } /// <summary> /// Вычисляет конечную сумму /// </summary> /// <param name="n"> /// Число членов суммы /// </param> /// <param name="exactSum"> /// Точное значение суммы. Параметр по ссылке - вычисляется внутри функции. /// </param> /// <return> /// Значение суммы /// </return> double Sum(int n,double %exactSum) // Символ % перед именем параметра exactSum означает, что функции передается // ссылка на параметр, а не его значение. // После выполнения функции по этой ссылке будет помещено // значение параметра, вычисленное внутри функции. { double result=0;// Текущее значение суммы for (int k=1;k<=n;k++) result+=1.0/k/(k+1); // Обратите внимание на необходимость писать именно 1.0, а не 1. // Замените здесь (и отдельно ниже) 1.0 на 1 и объясните результаты. exactSum=n/(n+1.0);// Возвращает точное значение суммы return result; } /// <summary> /// Описывает примеры использования циклов с перечислениями. /// </summary> void for_loop() { // Цикл с перечислением 3 Console::WriteLine("Цикл с перечислением for (...;...;...){...}"); Console::Write("Введите число целых чисел, выводимых на экран n = "); int n=int::Parse(Console::ReadLine()); for (int i=0;i<n;i++) Console::WriteLine(i); Console::WriteLine("Strike any key to continue!"); Console::ReadKey(true); Console::WriteLine("Таблица логических операций"); // Примеры использования циклов с перечислением // Таблица бинарных операций с bool Console::WriteLine("b1 |b2 |b1 || b2|b1 && b2|b1 ^ b2|"); bool b1,b2; for (int i=0;i<2;i++) { b1=i==0; for (int j=0;j<2;j++) { b2=j==0; Console::WriteLine("{0,-8}|{1,-8}|{2,-8}|{3,-8}|{4,-7}|", // Форматирующая строка b1,b2,b1||b2,b1&&b2,(bool)(b1 ^ b2)); } } Console::WriteLine("Strike any key to continue!"); Console::ReadKey(true); Console::Write( "На экран будут выводиться четные целые числа из последовательности\n 0, 1, ... , n = "); n=int::Parse(Console::ReadLine()); for (int i=0;i<n;i+=2) Console::WriteLine(i); // или /* for (int i=0;i<n;i++) if (i%2==0) // Так можно определить четность числа Console::WriteLine(i); */ // или /* for (int i=0;i<n;i++) if ((i&1)==0) Console::WriteLine(i); */ // или /* for (int i=0;i<n;i++) { if (i%2!=0) continue; // Пропускаем нечетные числа Console::WriteLine(i); } */ Console::WriteLine("Strike any key to continue!"); 4 Console::ReadKey(true); // Таблица умножения Console::WriteLine("Таблица умножения. Построчный вывод"); // Построчный вывод for (int i=1; i<10;i++) { for (int j=1;j<10; j++) Console::WriteLine("{0} x {1} = {2}", i,j,i*j); Console::WriteLine(); } Console::WriteLine("Strike any key to continue!"); Console::ReadKey(true); // Другая версия - вывод столбцами Console::WriteLine("Таблица умножения. Вывод столбцами"); for (int i = 1; i < 10; i++) { for (int j = 2; j < 6; j++) Console::Write("{0} * {1} = {2}\t", j, i, j * i); Console::WriteLine(); } Console::WriteLine(); for (int i = 1; i < 10; i++) { for (int j = 6; j < 10; j++) Console::Write("{0} * {1} = {2}\t", j, i, j * i); Console::WriteLine(); } Console::WriteLine("Strike any key to continue!"); Console::ReadKey(true); // Подсчет конечной суммы слагаемых 1/k/(k+1) от k = 1 до k = n, // которая должна равняться n/(n + 1) Console::WriteLine( "Подсчет конечной суммы слагаемых 1/k/(k+1) от k = 1 до k = n."); Console::WriteLine("Сумма должна равняться n/(n + 1)."); Console::Write("n = "); int N=int::Parse(Console::ReadLine()); double exact, sum; sum=Sum(N,exact); // Вызов функции Console::WriteLine( "Полученное значение в формате f8 (8 знаков после запятой) = {0:f8};\n"+ "Значение n/(n+1) в формате e9 (9 знаков после запятой с указанием степени 10) = {1:e9}", sum,exact); Console::WriteLine("Strike any key to continue!"); Console::ReadKey(true); } /// <summary> /// Описывает примеры использования циклов с постусловием. /// </summary> void do_loop() { 5 // Цикл с постусловием // Подсчет минимального числа, изменяющего единицу Console::WriteLine("Подсчет минимального числа delta, изменяющего единицу"); Double delta = 1; do { delta *= .5; } while (1 + delta*.5 != 1); Console::WriteLine("delta={0}", delta); Console::WriteLine("Strike any key to continue!"); Console::ReadKey(true); // Арифметическая прогрессия do { Console::WriteLine("Подсчет суммы арифметической прогрессии"); Console::Write("Начальный член a0="); double a0=double::Parse(Console::ReadLine()); Console::Write("Шаг прогрессии d="); double d=double::Parse(Console::ReadLine()); Console::Write("Предел aMax="); double aMax=double::Parse(Console::ReadLine()), a=a0,// текущий член прогрессии sum=a0; // сумма членов прогрессии // Число членов int n=(int)((aMax - a0)/d); Console::WriteLine("Число членов прогрессии n = "+n); while (a+d<aMax) sum+=(a+=d); Console::WriteLine("sum = "+sum+ ";\nПо формуле s = (n+1)/2*(a0 + an): "+(n + 1)*.5*(2*a0 + n*d)); Console::WriteLine("Strike any key to restart and esc to continue!"); } while (Console::ReadKey(true).Key!=ConsoleKey::Escape); // Геометрическая прогрессия do { Console::WriteLine("Подсчет суммы геометрической прогрессии"); Console::Write("Начальный член a0 = "); double a0=double::Parse(Console::ReadLine()); Console::Write("Множитель прогрессии r = "); double r =double::Parse(Console::ReadLine()); Console::Write("Число членов n = "); int n = int::Parse(Console::ReadLine()); double sum=a0,a = a0; for (int i=0;i<=n;i++) sum+=(a*=r); Console::WriteLine( "sum = "+sum+"; По формуле s = (a0 - an*r)/(1 - r): "+(a0-a*r)/(1-r)); Console::WriteLine("Strike any key to restart and esc to continue!"); } while (Console::ReadKey(true).Key!=ConsoleKey::Escape); 6 } /// <summary> /// Вычисляет сумму бесконечного ряда с заданной точностью /// </summary> /// <param name="truncErr"> /// Ошибка усечения /// </param> /// <param name="exactSum"> /// Точное значение суммы. Параметр по ссылке - вычисляется внутри функции. /// </param> /// <return> /// Значение суммы /// </return> double infSeriesSum(double truncErr, double %exactSum) { double sum=1, prevTerm=0,// Предыдущий член ряда term=1, // Текущий член ряда dterm=1; // Текущий модуль разности между членами ряда int k = 1;// Номер члена ряда while (dterm > truncErr*term) { // Вычисляется следующий член ряда k++; term=1.0/(2*k - 1)/(2*k - 1); sum+=term;// К сумме добавляется текущий член ряда // Вычисляется модуль разности членов ряда dterm=Math::Abs(term-prevTerm); prevTerm=term; // Текущий член ряда копируется в предыдущий } exactSum=.125*Math::PI*Math::PI; return sum; } /// <summary> /// Описывает примеры использования циклов с предусловием. /// </summary> void while_loop() { // Цикл с предусловием внутри цикла с постусловием // Факториал do { Console::WriteLine("Подсчет факториала числа n"); UInt64 f = 1; int n,nStart; Console::Write("n="); nStart= n=int::Parse(Console::ReadLine()); while (n>1) { if (f*n<=0) { Console::WriteLine( 7 "Слишком большое значение n.\nn! превышает значение {0:n0} типа {1}!", UInt64::MaxValue,f.GetTypeCode()); break; } else f*=n--; } if (n==1) // В этом случае цикл подсчета факториала был выполнен до конца Console::WriteLine("{0}! = {1:n0}",nStart,f); Console::WriteLine("Strike any key to restart and esc to continue!"); } while (Console::ReadKey(true).Key!=ConsoleKey::Escape); // Подсчет экспоненты суммированием ряда do { Console::WriteLine("Вычисление экспоненты от x суммированием ряда."); Console::Write("x = "); double x = double::Parse(Console::ReadLine()), // Вводим аргумент exp=0, // Текущее значение результата (экспоненты) term=1; // Текущий член ряда Console::Write("Ошибка усечения = "); double truncErr=Double::Parse(Console::ReadLine()); // Первая версия кода int n=1; // номер члена ряда while(term>truncErr) { // Пока выполняется условие "текущий член больше ошибки усечения" // будут выполняться операторы в фигурных скобках exp+=term; // К результату добавляется новый член ряда term*=x; // Текущий член ряда умножается на аргумент term/=n++; // Текущий член делится на номер члена ряда // и после этого номер увеличивается на единицу } Console::WriteLine("exp = {0}; exactExp = {1}",exp,Math::Exp(x)); // или /* exp=0; // Текущее значение результата (экспоненты) term=1; // Текущий член ряда // Вторая версия кода for (int n=1;// секция инициализации // секция условия (операторы выполняются, если условие соблюдается) term>truncErr; n++ // секция изменения ) { exp+=term;// Добавляем текующий член ряда // Изменяем текущий член ряда 8 term*=x; term/=n; } Console::WriteLine("exp = {0}; exactExp = {1}",exp,Math::Exp(x)); */ // Вычисляется сумма бесконечного ряда с заданной погрешностью Console::WriteLine( "Вычисление суммы ряда 1/(2k - 1)/(2k - 1) с ошибкой truncErr"); Console::Write("Значение truncErr = "); truncErr=Double::Parse(Console::ReadLine()); double exact; double sum = infSeriesSum(truncErr,exact); Console::WriteLine( "sum = {0:g9} в формате g9 (9 значащих цифр); exactExp = {1}",sum,exact); Console::WriteLine("Strike any key to restart and esc to continue!"); } while (Console::ReadKey(true).Key!=ConsoleKey::Escape); } /// <summary> /// Решает квадратное уравнение. /// </summary> void quadrEq() { // Решение квадратного уравнения do { // Коэффициенты квадратного уравнения double a,b; // Комментарий ввода Console::WriteLine( "Вводим коэффициенты квадратного уравнения x^2 + a*x + b = 0"); // Вводится первый коэффициент Console::Write("Коэффициент a = "); String^ _a=Console::ReadLine(); a=Double::Parse(_a); // Вводится свободный член Console::Write("Коэффициент b = "); String^ _b=Console::ReadLine(); b=Double::Parse(_b); // Комментарий решения Console::WriteLine( "Решаем квадратное уравнение x^2 + {0}*x + {1} = 0",a,b); // Считаем дискриминант double discr= a*a - 4*b; // Считаем знак дискриминанта bool discrSign = discr>=0; // Значение discrSign равно true, если знак положительный или ноль. //В противном случае false. // Корни уравнения double x1Re,x1Im,x2Re,x2Im; // Ветвление в зависимости от знака дискриминанта 9 if (discrSign) // Корни действительные { x1Re=(-a-.5*Math::Sqrt(discr)); x1Im=0; x2Re=(-a+.5*Math::Sqrt(discr)); x2Im=0; } else // Корни комплексные { x1Re=x2Re= -.5*a; x1Im=-.5*Math::Sqrt(-discr); x2Im=-x1Im; } // Комментарий тестирования Console::WriteLine("Проверяем корни уравнения x^2 + {0}x + {1} = 0",a,b); double zero1Re=0,zero1Im=0, zero2Re=0,zero2Im=0; // Ветвление в зависимости от типа корней if (discrSign) { zero1Re=x1Re*x1Re+a*x1Re+b; zero2Re=x2Re*x2Re+a*x2Re+b; } else { zero1Re=(x1Re*x1Re-x1Im*x1Im) +a*x1Re+b; zero1Im=2*x1Re*x1Im+b*x1Im; zero2Re=(x2Re*x2Re-x2Im*x2Im)+a*x2Re+b; zero2Im=2*x2Re*x2Im+b*x2Im; } // Комментарий завершения и вывода результатов решения и тестирования Console::WriteLine("Вывод корней уравнения x^2 + {0}x + {1} = 0",a,b); Console::WriteLine( "Корни "+ (discrSign?"вещественные":"комплексные")); // Условное выражение!! if (discrSign) Console::WriteLine("x1 = {0}; x2 = {1}",x1Re,x2Re); else Console::WriteLine( "x1 = {0} - {1}i; x2 = {0} + {1}i",x1Re,Math::Abs(x1Im)); Console::WriteLine("Вывод результатов тестирования корней уравнения"); if (discrSign) { Console::WriteLine( "Первый корень: {0} + {1}*{2} + {3} = {4}",x1Re*x1Re,a,x1Re,b,zero1Re); Console::WriteLine( "Второй корень: {0} + {1}*{2} + {3} = {4}",x2Re*x2Re,a,x2Re,b,zero2Re); } else { // Здесь поиграть форматом вывода 10 Console::WriteLine( "Первый корень:\n {0} + {1}i + {2}*({3} + {4}i) + {5} = {6:r} + {7:f8}i", x1Re*x1Re-x1Im*x1Im, 2*x1Re*x1Im, a, x1Re, x1Im, b, zero1Re, zero1Im); Console::WriteLine( "Второй корень:\n {0} + {1}i + {2}*({3} + {4}i) + {5} = {6:g3} + {7:e3}i", x2Re*x2Re-x2Im*x2Im, 2*x2Re*x2Im, a, x2Re, x2Im, b, zero2Re, zero2Im); } Console::WriteLine("Strike any key to restart and esc to exit!"); } while (Console::ReadKey(true).Key!=ConsoleKey::Escape); } // Функция main() состоит из последовательного вызова отдельных функций, // описанных выше. void main() { // Описание, ввод, вывод строк, целых чисел, чисел с плавающей запятой ReadWrite(); // Операции со строками, целыми числами, числами с плавающей запятой и логическими переменными Operators(); // Циклы // Циклы с перечислением for(...;...;...){...} for_loop(); // Циклы с постусловием do{...}while() do_loop(); // Циклы с предусловием while(){...} while_loop(); // решение квадратного уравнения quadrEq(); } 11