c#1_osnovy
.PDFВвод данных с консоли
Методы ввода ReadLine - тип string, |
Read – символ (код). |
|
Требуется преобразование в нужный тип! |
||
Метод: Parse |
Класс: Convert |
|
string str = Console.ReadLine(); |
// ввод строки |
|
char c = (char)Console.Read(); |
// ввод символа |
string s = Console.ReadLine(); |
|
|
|
int k = int.Parse(s); // преобразование в целое |
|
||
nt m = Convert.ToInt32(s); |
// преобразование в целое |
||
Console.WriteLine("строка s={0} число k={1} |
m={2}", s, k, m); |
||
s = Console.ReadLine(); |
|
|
|
double x = double.Parse(s); |
// преобразование в вещ. |
||
double y = Convert.ToDouble(s); |
// преобразование в вещ. |
||
Console.WriteLine("строка s={0} число x={1} |
y={2}", s, x, y); |
Пример: перевод температуры из F в oС using System;
class Program
{
static void Main()
{
Console.WriteLine( "Введите температуру по Фаренгейту" ); double far = Convert.ToDouble( Console.ReadLine() ); double cels = 5 * (far - 32) / 9 ;
Console.WriteLine( "По Фаренгейту: {0} по Цельсию: {1}", far, cels );
}
}
Основы структурного программирования
∙Любую программу можно реализовать
как совокупность базовых алгоритмических конструкций:
следование повторение ветвление
∙Каждая алгоритмическая конструкция имеет только один вход и один выход, поэтому они могут вкладываться друг в друга.
∙Использование алгоритмических конструкций позволяет получать простую и понятную структуру программы.
Блок (составной оператор) - последовательность операторов, заключенная в операторные скобки:
begin … end |
в Паскале |
{… … } |
в С-подобных языках |
Блок воспринимается компилятором как один оператор и может использоваться всюду, где синтаксис требует одного оператора, а алгоритм — нескольких.
Блок может содержать один оператор или быть пустым.
Выражение как оператор
∙Любое выражение, завершающееся точкой с запятой, может рассматриваться как оператор, выполнение которого
заключается в вычислении выражения.
i++; |
// выполняется операция инкремента |
a *= b + c; |
// выполняется умножение с присваиванием |
fun( i, k ); |
// выполняется вызов функции |
∙Пустой оператор ; используется, когда по синтаксису оператор требуется,
а по смыслу — нет:
while ( true ) ; // цикл, состоящий из пустого оператора (бесконечный)
; ; ; |
// три пустых оператора |
|
|
|
|
Базовые алгоритмические конструкции
Ветвление
∙ развилка if
∙ переключатель switch
Условный оператор if
if (условие) оператор_1; [else оператор_2;]
Примеры:
if ( a < 0 ) a += 5;
if ( a < b && (a > d || a == 0) ) b ++; else { b *= a; a = 0; }
if ( h >= 6 && h < 12 ) mes = “Доброе утро” ; else if (h >=12 && h<18) mes=“Добрый день" ;
else if (h >=18 && h<24) mes=“Добрый вечер" ; else mes =“Доброй ночи" ;
Пример 4: проверка попадания точки в заданную область
Console.Write("Введите x: ");
double x = double.Parse(Console.ReadLine()); Console.Write("Введите у: " );
double y = double.Parse(Console.ReadLine());
if ( x*x+y*y <= 2 || (x<=0 && y<=0 && y>=(-x-2) ) ) Console.WriteLine("Попал!" );
else Console.WriteLine("Мимо!" ); Проверка вещественных чисел на равенство
∙Из-за погрешности представления вещественных значений следует избегать прямой проверки на равенство.
Корректнее сравнивать модуль разности с некоторым малым числом.
double a, b; |
|
if (a == b) … |
// не рекомендуется! |
if (Math.Abs(a - b) < 1e-6 ) … |
// надежно! |
∙Значение величины, с которой сравнивается модуль разности, следует выбирать в зависимости от решаемой задачи и точности участвующих в выражении переменных.
∙Снизу эта величина ограничена определенной в классах Single и Double константой Epsilon.
Это минимально возможное значение переменной такое, что
1.0+ Epsilon != 1.0
Оператор выбора switch |
|
|
switch (выражение) |
|
|
{ case выражен_1: |
оператор_1 ; |
break; |
case выражен_2: |
оператор_2 ; |
break; |
………………………………………………………….. |
||
case выражен_n: |
оператор_n ; |
break; |
[ default: операторы ] } |
|
Пример: Калькулятор на четыре действия
// res и ok необходимо инициализировать, т.к. используются внутри switch
double res=0; bool ok=true;
Console.Write("Введите число А: ");
double A = double.Parse(Console.ReadLine());
Console.Write("Введите число B: ");
double A = double.Parse(Console.ReadLine());
Console.Write("Введите знак операции (+ - * /) |
"); |
|||||
string op = Console.ReadLine(); |
|
|||||
|
switch (op) { |
|
|
|
|
|
|
case "+": res = A + B; break; |
|
||||
|
case "-": |
res = A - B; |
break; |
|
||
|
case "*": |
res = A * B; |
break; |
|
||
|
case "/": |
res = A / B; |
break; |
|
||
|
default: |
ok = false; |
|
break; } |
|
|
if (ok) Console.WriteLine("{0} {1} {2} = {3}", A, op, B, res); |
||||||
else Console.WriteLine("Недопустимая операция"); |
||||||
Циклы: |
|
|
|
|
|
|
∙ |
с предусловием while |
|
с постусловием |
do … while |
||
∙ |
с параметром for |
|
перебора foreach |
|||
Структура циклов |
while |
и |
do…while |
|
|
Цикл с предусловием |
while (условие) |
|
|
блок_операторов |
|
Пример 1: табулирование функции |
|
|
double Xn= -2, Xk=4, |
dX=0.5, a=3, y; |
|
double x = Xn; |
// начальное значение |
|
while (x <= Xk) |
|
|
{ y = a*x; |
// тело цикла |
|
Console.WriteLine( “x = {0,9} |
y = {1,9}", x, y ); |
|
x += dX; } |
// приращение в теле цикла |
|
Пример 2: организация многократного ввода |
||
string otv; |
|
|
while (true) |
|
// бесконечный цикл |
{ Console.Write("Вам нравится программирование? "); |
||
otv = Console.ReadLine(); |
|
|
if (otv=="y") break; |
} |
// прерывание цикла |
Console.WriteLine("Ответ принят"); |
||
|
|
|
Цикл с постусловием |
do |
|
|
блок_операторов |
|
|
while |
(условие); |
Пример: организация многократного ввода string otv;
do
{ Console.Write("Вам нравится программирование? "); otv = Console.ReadLine(); }
while (otv != "y"); Console.WriteLine(“Ответ принят");
Цикл с параметром |
for (инициализация; условие; модификатор) |
|
|
|
блок операторов |
Пример 1: сумма и произведение натуральных чисел от 1 до 6 |
||
int sum = 0; |
int pro = 1; |
// инициализация |
for (int i=1; |
i<=6; i++) |
|
{ sum += i; pro *= i; |
// тело цикла |
Console.WriteLine(“i={0} сумма={1} произвед={2}", i, sum, pro); }
Пример 2: работа с вещественными числами
for (double x=-1; x<=2; x+=0.5) { double y = x*x;
Console.WriteLine("x={0:f2} y={1:f4}", x, y);
}
Использование сложных условий в цикле for
Пример 3: сумма четных от -2 до 14, произведение всех от 1 до 5
int sum = 0; int pro = 1; |
|
for (int i=-2, j=1; i<=14 && j<=5; i+=2, j++) |
// логическое и в условии |
{ sum += i; pro *= j;
Console.WriteLine("i={0,2} сумма={1,3} j= {2} произв={3}", i, sum, j, pro);
}
// логическое или в условии
for (int i=-2, j=1; i<=14 || j<=5; i+=2, j++)
Рекомендации по реализации циклов:
∙использовать do-while, если цикл требуется обязательно выполнить хотя бы один раз (например, при проверке ввода); в остальных случаях, как правило, применять while.
∙применять for , если известно количество повторений ;
∙заключать в блок тело цикла, состоящее более чем из одного оператора;
∙проверять, изменяется ли в теле цикла хотя бы одна переменная, входящая в условие продолжения цикла;
∙предусматривать аварийный выход из цикла, количество повторений которого невозможно вычислить заранее.
Пример: расчет высоты подъема тела, брошенного вверх с нач скоростью V0
Console.Write("Введите начальную скорость V0 (от 12 до 40) м/c : ");
double V0 = double.Parse(Console.ReadLine());
double t=0, y=0, |
V=V0, g=9.81; |
// инициализация |
while (V > 0) |
// цикл с предусловием: расчет скорости и высоты |
|
{ V=V0-g*t; |
y=V0*t - g*t*t/2; |
t += 0.001; } |
Console.WriteLine("время = {0:f2} c, |
макс высота = {1:f2} м", t, y); |
|
do |
// цикл с постусловием: расчет времени полета |
|
{ t += 0.001; y = V0*t - g*t*t/2; |
} |
while (y > 0);
Console.WriteLine("время полета = {0:f2} c", t);
Передача управления
∙break завершает выполнение цикла, внутри которого записан
∙continue выполняет переход к следующей итерации цикла
∙return завершает выполнение функции и передает управление
в точку ее вызова: |
return [ выражение ]; |
∙goto выполняет безусловную передачу управления
∙throw генерирует исключительную ситуацию.
Массивы
Массив — именованная упорядоченная последовательность однотипных элементов, к каждому из них можно обратиться по индексу.
Элементы массива имеют одно общее имя.
Во многих случаях индекс можно считать порядковым номером
Виды массивов в C#:
∙одномерные (линейные)
∙многомерные (например, двумерные, или прямоугольные)
∙массивы массивов (jagged - используются термины: ступенчатые, невыровненные, изрезанные, зубчатые…).
Описание массива
∙Массив относится к ссылочным типам данных (располагается в хипе), поэтому создание массива начинают с выделения памяти под его элементы.
∙Элементами массива могут быть величины как значимых, так и ссылочных типов (в том числе массивы),
например:
int[] w = new int[10]; string[] z = new string[100]; Car[] s = new Car[5];
double[,] t = new double[2, 10]; int[,,] m = new int[2,2,2]; int[][] a = new int[2][];
int[][][] b = new int[2][][];
//массив из 10 целых чисел
//массив из 100 строк
//массив из 5 объектов типа Car
//прямоугольный массив 2х10
//3-x мерный массив
//массив массивов
//массив массивов массивов
∙Элементы массивов значимых типов хранят значения, массивы ссылочных типов — ссылки на элементы.
∙Всем элементам при создании массива присваиваются
значения по умолчанию: 0 для значимых типов и null для ссылочных.
Размещение массивов в памяти
Размерность массива
∙Размерность массива (количество элементов в массиве) задается при объявлении (выделении памяти)
и не может быть изменена впоследствии.
∙Размерность может задаваться выражением:
int n = 5; string[] z = new string[2*n + 1];
∙В C# начальный индекс = 0 (элементы нумеруются с нуля).
∙Для обращения к элементу массива после его имени
указывается индекс элемента в квадратных скобках: w[4], z[i]
Действия с массивами
∙С элементами массива можно делать все, что допустимо для переменных того же типа.
∙При работе с массивом автоматически выполняется контроль выхода за его границы: если значение индекса выходит
за границы массива, генерируется исключение IndexOutOfRangeException.
∙Массивы одного типа можно присваивать друг другу.
При этом происходит присваивание ссылок, а не элементов:
int[] c = new int[10]; int[] b = c; // b и c указывают на один и тот же массив
Типовые задачи работы с массивами:
Поиск и определение:
∙значений и индекса минимума/максимума [по модулю];
∙индекса первого/второго/последнего положительного/отрицательного/нулевого элемента;
∙суммы/произведения/количества/среднего арифметического положительных/отрицательных/нулевых элементов;
∙сортировка (упорядочивание элементов) массива;
∙анализ возможных вариантов расположения элементов, и др….
Одномерные массивы
Варианты описания массива: тип[] имя;
тип[] имя = new тип [размерность]; тип[] имя = { список_значений };
тип[] имя = new тип [] { список_значений };
тип[] имя = new тип [ размерность ] { список_значений };
Примеры описаний:
int[] a; // описана только ссылка на массив, память под элементы не выделена
int[] b = new int[4]; |
// |
элементы равны 0 |
int[] c = { 61, 2, 5, -9 }; |
// |
new подразумевается |
int[] d = new int[] { 61, 2, 5, -9 }; |
// |
размерность вычисляется |
int[] e = new int[4] { 61, 2, 5, -9 }; |
// |
избыточное описание |
Пример 1a: работа с массивом чисел (использование цикла for) Определить сумму элементов массива из 6 целых чисел, количество отрицательных элементов, максимальный элемент.
int[] a = { 3, 12, 5, -9, 8, -4 };
for (int i = 0; i < a.Length; i++)
Console.Write( "{0,4}", a[i] ); //вывод элементов Console.WriteLine();
int sum = 0, kvo = 0; |
// cумма и к-во отрицательных элементов |
for (int i = 0; i < a.Length; i++) |
|
if (a[i] < 0) |
|
{ sum += a[i]; kvo++ ; |
} |
Console.WriteLine("Сумма отрицательных = {0} к-во = {1}", sum, kvo);
int max = a[0];
for (int i = 1; i < a.Length; i++) if (a[i] > max) max = a[i];
Console.WriteLine("Максимальный элемент = " + max );
Перебор элементов массива foreach … in
Синтаксис: foreach ( тип_перем in имя_массива ) тело_цикла
перем – имя локальной переменной цикла, которая по очереди принимает все значения элементов массива.
Например: |
int[] mas = { 24, 50, 18, |
3, 16, -7, 9, -1 }; |
||
|
foreach ( int x in |
mas ) |
Console.WriteLine( x ); |
|
Пример 1б: |
использование цикла |
foreach |
|
|
int[] ar = { 3, 12, 5, -9, 8, -4 }; |
|
|
|
|
foreach ( int x in ar ) Console.Write( "{0,4}", x ); |
// вывод элементов |
Console.WriteLine();
int sum = 0, kvo = 0; foreach ( int x in ar )
if ( x < 0 ) { sum += x; kvo++; } Console.WriteLine( "sum = {0} kvo = {1}“, sum, kvo );
int max = ar[0]; |
// пусть максимальный элемент ar[0] |
foreach ( int x in ar ) |
|
if ( x > max ) |
max = x; |
Console.WriteLine( "max = " + max );
Базовый класс Array
Все массивы в C# имеют общий базовый класс Array, определенный в пространстве имен System. Некоторые свойства и методы класса Array:
∙Length (свойство) - количество элементов массива (по всем размерностям)
∙BinarySearch (статический метод) Двоичный поиск в отсортированном массиве
∙IndexOf – (статический метод)
Поиск первого вхождения элемента в одномерный массив
∙Sort (статический метод) - упорядочивание элементов одномерного массива
∙Reverse - изменение порядка следования элементов на обратный
∙…………………………………………………………………………………………..
Пример 2: Заполнение массива случайными числами. Использование методов класса Array
Console.Write("Введите размерность массива (от 5 до 15) "); int n = int.Parse(Console.ReadLine());
Random r = new Random(); |
// создание экземпляра класса Random |
int[] a = new int[n]; |
// объявление массива размерности n |
for (int i = 0; i < n; i++) |
|
{ a[i] = r.Next(-20, 20); |
// заполнение массива случайными числами |
Console.Write("{0,4}", a[i]); } |
// форматный вывод |
Console.WriteLine(); |
|
Array.Sort(a); |
// упорядочивание по возрастанию |
foreach (int x in a) Console.Write("{0,4}", x); |
|
Console.WriteLine(); |
|
Array.Reverse(a); |
// реверс |
foreach (int x in a) Console.Write("{0,4}", x);