Приложение first

advertisement
Приложение 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
Download