С++ и С# от 2017-12-04 Плещев Основы программирования

МИНИСТЕРСТВО ОБРАЗОВАНИЯ и науки
РОССИйСКОЙ ФЕДЕРАЦИИ

Уральский государственный экономический университет










В.В. Плещев, Е.И. Шишков

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








Екатеринбург
2018
УДК 681.3.06
ББК 32.973
П 38


Рецензенты:
Уральский институт бизнеса;
математикомеханический факультет Уральского государственного университета им. А.M. Горького;
кафедра информатики Курганского государственного университета




Плещёв В.В., Шишков Е.И.
П 38 Основы программирования на языках C++ и C#: Учеб. Пособие  Екатеринбург: Изд-во Урал. гос. экон. ун-та, 2018. – 230 с.




Учебник содержит компактное описание и примеры использования основных средств языков программирования C++, C# и их интегрированных сред быстрой разработки приложений Microsoft Visual Studio.
В качестве основных средств языков программирования рассмотрены операции, операторы, функции, компоненты, классы, объекты, их свойства, события, методы и процедуры вводавывода данных, создания и использования файлов, баз данных и формирования форм, запросов, отчетов.
Рекомендовано студентам всех форм обучения по специальности «Прикладная информатика (по областям)», «Инфоратика и вычислительная техника», «Математическое обеспечение и администрирование информационных систем», изучающим курсы, связанных с программированием.



Оглавление
13 TOC \o "1-4" 14Введение 13 PAGEREF _Toc500165292 \h 14615
Глава 1. C++ 13 PAGEREF _Toc500165293 \h 14715
1.1. Лексические структуры языка 13 PAGEREF _Toc500165294 \h 14715
1.1.1. Элементы 13 PAGEREF _Toc500165295 \h 14715
1.1.2. Константы 13 PAGEREF _Toc500165296 \h 14815
1.1.3. Типы данных 13 PAGEREF _Toc500165297 \h 14815
1.1.4. Массивы 13 PAGEREF _Toc500165298 \h 141115
1.1.5. Структуры (записи) 13 PAGEREF _Toc500165299 \h 141115
1.1.6. Объединения union 13 PAGEREF _Toc500165300 \h 141215
1.1.7. Перечисления enum 13 PAGEREF _Toc500165301 \h 141215
1.2. Основные возможности 13 PAGEREF _Toc500165302 \h 141315
1.2.1. Предпроцессор 13 PAGEREF _Toc500165303 \h 141315
1.2.2. Директива #Include 13 PAGEREF _Toc500165304 \h 141315
1.2.3. Директива #define 13 PAGEREF _Toc500165305 \h 141315
1.2.4. Функция вывод на терминал - Printf 13 PAGEREF _Toc500165306 \h 141315
1.2.5. Функция ввод с клавиатуры - Scanf 13 PAGEREF _Toc500165307 \h 141415
1.2.6. Функция Main в консольных приложениях 13 PAGEREF _Toc500165308 \h 141415
1.2.7. Функции 13 PAGEREF _Toc500165309 \h 141515
1.2.8. Классы памяти 13 PAGEREF _Toc500165310 \h 141515
1.2.8.1. Автоматические переменные 13 PAGEREF _Toc500165311 \h 141615
1.2.8.2. Регистровые переменные 13 PAGEREF _Toc500165312 \h 141615
1.2.8.3. Статические переменные и функции 13 PAGEREF _Toc500165313 \h 141615
1.2.8.4. Внешние переменные 13 PAGEREF _Toc500165314 \h 141715
1.2.9. Операции 13 PAGEREF _Toc500165315 \h 141715
1.2.9.1. Арифметические операции 13 PAGEREF _Toc500165316 \h 141715
1.2.9.2. Операции отношения 13 PAGEREF _Toc500165317 \h 141715
1.2.9.3. Логические операции 13 PAGEREF _Toc500165318 \h 141715
1.2.9.4. Операции присваивания 13 PAGEREF _Toc500165319 \h 141815
1.2.10. Операторы 13 PAGEREF _Toc500165320 \h 141815
1.2.10.1. Блоки и составные операторы 13 PAGEREF _Toc500165321 \h 141815
1.2.10.2. Оператор возврата из функции  return 13 PAGEREF _Toc500165322 \h 141815
1.2.10.3. Условный оператор  if 13 PAGEREF _Toc500165323 \h 141815
1.2.10.4. Условная операция  ? 13 PAGEREF _Toc500165324 \h 141915
1.2.10.5. Оператор выбора варианта  switch 13 PAGEREF _Toc500165325 \h 141915
1.2.10.6. Оператор безусловного перехода  goto 13 PAGEREF _Toc500165326 \h 141915
1.2.10.7. Цикл с предусловием  while 13 PAGEREF _Toc500165327 \h 142015
1.2.10.8. Цикл с постусловием  do while 13 PAGEREF _Toc500165328 \h 142015
1.2.10.9. Итерационный цикл  For 13 PAGEREF _Toc500165329 \h 142115
1.2.10.10. Пустой оператор 13 PAGEREF _Toc500165330 \h 142215
1.2.10.11. Указатели 13 PAGEREF _Toc500165331 \h 142215
1.2.10.12. Исключения. Обработка исключений 13 PAGEREF _Toc500165332 \h 142415
1.3. Потоки и система ввода-вывода 13 PAGEREF _Toc500165333 \h 142515
1.3.1. Базовые типы для работы с потоками 13 PAGEREF _Toc500165334 \h 142515
1.3.2. Запись в поток 13 PAGEREF _Toc500165335 \h 142515
1.3.3. Чтение данных 13 PAGEREF _Toc500165336 \h 142515
1.3.4. Файловые потоки. Открытие и закрытие 13 PAGEREF _Toc500165337 \h 142615
1.3.5. Чтение и запись текстовых файлов 13 PAGEREF _Toc500165338 \h 142715
1.3.6. Переопределение операторов ввода и вывода 13 PAGEREF _Toc500165339 \h 142815
Глава 2. C# 13 PAGEREF _Toc500165340 \h 143015
2.1. Переменные 13 PAGEREF _Toc500165341 \h 143015
2.1.1. Численные литералы 13 PAGEREF _Toc500165342 \h 143115
2.1.2. Вещественные литералы 13 PAGEREF _Toc500165343 \h 143215
2.1.3. Символьные литералы 13 PAGEREF _Toc500165344 \h 143215
2.1.4. Строковые литералы 13 PAGEREF _Toc500165345 \h 143315
2.1.5 Типы данных 13 PAGEREF _Toc500165346 \h 143315
2.2. Операции 13 PAGEREF _Toc500165347 \h 143515
2.2.1. Арифметические операции 13 PAGEREF _Toc500165348 \h 143515
2.2.2. Поразрядные операции 13 PAGEREF _Toc500165349 \h 143615
2.2.3. Операции присваивания 13 PAGEREF _Toc500165350 \h 143815
2.2.4. Преобразование базовых типов данных 13 PAGEREF _Toc500165351 \h 143915
2.2.5. Условные выражения 13 PAGEREF _Toc500165352 \h 144015
2.2.6. Логические операции 13 PAGEREF _Toc500165353 \h 144215
2.3. Условные конструкции 13 PAGEREF _Toc500165354 \h 144315
2.3.1. Конструкция if/else 13 PAGEREF _Toc500165355 \h 144315
2.3.2. Конструкция switch 13 PAGEREF _Toc500165356 \h 144415
2.3.3. Тернарная операция 13 PAGEREF _Toc500165357 \h 144515
2.4. Циклы 13 PAGEREF _Toc500165358 \h 144515
2.4.1. Цикл for 13 PAGEREF _Toc500165359 \h 144515
2.4.2. Цикл do 13 PAGEREF _Toc500165360 \h 144615
2.4.3. Цикл while 13 PAGEREF _Toc500165361 \h 144715
2.4.4. Операторы continue и break 13 PAGEREF _Toc500165362 \h 144715
2.5. Массивы 13 PAGEREF _Toc500165363 \h 144815
2.5.1. Одномерные массивы 13 PAGEREF _Toc500165364 \h 144815
2.5.2. Перебор массивов. Цикл foreach 13 PAGEREF _Toc500165365 \h 144815
2.5.3. Многомерные массивы 13 PAGEREF _Toc500165366 \h 144915
2.6. Структуры 13 PAGEREF _Toc500165367 \h 145015
2.7. Работа со строками 13 PAGEREF _Toc500165368 \h 145215
2.7.1. Строки и класс System.String 13 PAGEREF _Toc500165369 \h 145215
2.7.2. Операции со строками 13 PAGEREF _Toc500165370 \h 145315
2.7.3. Форматирование 13 PAGEREF _Toc500165371 \h 145415
2.8. Обработка исключений 13 PAGEREF _Toc500165372 \h 145515
2.9. Объектно-ориентированное программирование 13 PAGEREF _Toc500165373 \h 145615
2.9.1. Классы и объекты 13 PAGEREF _Toc500165374 \h 145615
2.9.2. Конструкторы 13 PAGEREF _Toc500165375 \h 145715
2.10. Разработка приложений по формированию запросов и отчётов с использованием баз данных 13 PAGEREF _Toc500165376 \h 145815
2.10.1. Создание проекта 13 PAGEREF _Toc500165377 \h 145815
2.10.2. Создание интерфейса приложения 13 PAGEREF _Toc500165378 \h 146015
2.10.3. Создание базы данных 13 PAGEREF _Toc500165379 \h 146415
2.10.4. Подключение к базе данных 13 PAGEREF _Toc500165380 \h 146915
2.10.5. Чтение данных 13 PAGEREF _Toc500165381 \h 147315
2.10.6. Закрытие базы данных 13 PAGEREF _Toc500165382 \h 147515
2.10.7. Добавление записей в базу данных 13 PAGEREF _Toc500165383 \h 147715
2.10.8. Корректировка записей в базе данных 13 PAGEREF _Toc500165384 \h 148315
2.10.9. Удаление записей из базы данных 13 PAGEREF _Toc500165385 \h 148615
2.10.10. Установка ReportViewer 13 PAGEREF _Toc500165386 \h 148815
2.10.11. Формирование отчетов 13 PAGEREF _Toc500165387 \h 149215
2.11. Файлы 13 PAGEREF _Toc500165388 \h 1410015
2.11.1. Чтение и запись файла. Класс FileStream 13 PAGEREF _Toc500165389 \h 1410515
2.11.2. StreamReader и StreamWriter 13 PAGEREF _Toc500165390 \h 1410815
2.11.3. Работа с бинарными файлами. BinaryWriter и BinaryReader 13 PAGEREF _Toc500165391 \h 1411115
2.12. Сборка мусора 13 PAGEREF _Toc500165392 \h 1411315
Глава 3. Лабораторный практикум 13 PAGEREF _Toc500165393 \h 1411715
3.1. Примеры программ на С++ (Microsoft Visual Studio 2010) 13 PAGEREF _Toc500165394 \h 1411715
3.1.1. Числовые типы, оператор присваивания 13 PAGEREF _Toc500165395 \h 1411715
3.1.2. Алгоритмы линейной структуры 13 PAGEREF _Toc500165396 \h 1411715
3.1.3. Алгоритмы разветвляющей структуры 13 PAGEREF _Toc500165397 \h 1411915
3.1.4. Алгоритмы циклической структуры 13 PAGEREF _Toc500165398 \h 1412615
3.1.5. Алгоритмы работы с рядами 13 PAGEREF _Toc500165399 \h 1414015
3.1.6. Алгоритмы работы с массивами 13 PAGEREF _Toc500165400 \h 1414715
3.1.7. Обработка символьных данных 13 PAGEREF _Toc500165401 \h 1416215
3.1.8. Организация подпрограмм 13 PAGEREF _Toc500165402 \h 1416515
3.1.9. Работа с файлами 13 PAGEREF _Toc500165403 \h 1416915
3.1.10. Комплексный пример 13 PAGEREF _Toc500165404 \h 1417215
3.1.10.1. Игра «Угадай число 13 PAGEREF _Toc500165405 \h 1417415
3.1.10.2. Секундомер 13 PAGEREF _Toc500165406 \h 1417715
3.1.10.3. Бегущая строка 13 PAGEREF _Toc500165407 \h 1417915
3.1.10.4. Рисование на экране 13 PAGEREF _Toc500165408 \h 1418015
3.1.10.5.Тестирование по арифметике 13 PAGEREF _Toc500165409 \h 1418315
3.1.10.6. Игра «Морской бой» 13 PAGEREF _Toc500165410 \h 1418515
3.1.10.7. Вывод диаграммы 13 PAGEREF _Toc500165411 \h 1418815
3.1.10.8. Перевозка ценных предметов 13 PAGEREF _Toc500165412 \h 1418915
3.2. Примеры программ на С# (Microsoft Visual Studio 2010) 13 PAGEREF _Toc500165413 \h 1419115
3.2.1. Игра «Угадай число». 13 PAGEREF _Toc500165414 \h 1419115
3.2.2. Секундомер 13 PAGEREF _Toc500165415 \h 1419515
3.2.3. Бегущая строка 13 PAGEREF _Toc500165416 \h 1419715
3.2.4. Рисование на экране 13 PAGEREF _Toc500165417 \h 1419815
3.2.5. Тестирование по арифметике 13 PAGEREF _Toc500165418 \h 1420115
3.2.6. Игра «Морской бой» 13 PAGEREF _Toc500165419 \h 1420315
3.2.7. Вывод диаграммы 13 PAGEREF _Toc500165420 \h 1420515
3.2.8. Перевозка ценных предметов 13 PAGEREF _Toc500165421 \h 1420715
3.2.9. Калькулятор срочных вкладов 13 PAGEREF _Toc500165422 \h 1421015
3.2.10. Игра “Крестики-Нолики “ 13 PAGEREF _Toc500165423 \h 1421315
3.3. Задачи для программирования на С++ и C# 13 PAGEREF _Toc500165424 \h 1421715
3.3.1. Числовые типы, оператор присваивания 13 PAGEREF _Toc500165425 \h 1421715
3.3.2. Алгоритмы линейной структуры 13 PAGEREF _Toc500165426 \h 1421815
3.3.3. Алгоритмы разветвляющей структуры 13 PAGEREF _Toc500165427 \h 1421815
3.3.4. Алгоритмы циклической структуры 13 PAGEREF _Toc500165428 \h 1421915
3.3.5. Алгоритмы работы с рядами 13 PAGEREF _Toc500165429 \h 1422115
3.3.6. Алгоритмы работы с массивами 13 PAGEREF _Toc500165430 \h 1422315
3.3.7. Обработка символьных данных 13 PAGEREF _Toc500165431 \h 1422515
3.3.8. Организация подпрограмм 13 PAGEREF _Toc500165432 \h 1422515
3.3.9. Работа с файлами 13 PAGEREF _Toc500165433 \h 1422515
3.3.10. Работа с формами и диаграммами 13 PAGEREF _Toc500165434 \h 1422615
3.4. Контрольные работы 13 PAGEREF _Toc500165435 \h 1422815
Библиографический список 13 PAGEREF _Toc500165436 \h 1423515
15 Введение
Предметом изучения курса являются: новейшие направления в области технологий программирования; программирование в средах современных информационных и программных систем; создание модульных программ; модульное и визуальное объектноориентированное программирование; освоение и практическое использование современных языков программирования.
Пособие содержит основные понятия, термины и определения объектноориентированных языков программирования C++ и C# с примерами и упражнениями.
Авторы пособия основной упор делали на примеры, которые демонстрируют основные возможности языков программирования и приёмы программирования.
Авторы пособия не претендуют на оригинальность всего содержания пособия, т.к. большой объем содержания был скопирован с минимальной обработкой из других источников, например [1].
В теоретическое части пособия нет описания основных фундаментальных классов (объектов) и их свойств, методов и событий, предполагается, что читатель уже знаком с ними при освоении языков программирования Visual Basic и/или Delphi и др. (примеры использования их можно найти в примерах приложений в данном пособии).
Главное в работе программиста это не знание языка программирования (его можно осваивать и в процессе разработки приложения с учетом особенности решаемой задачи – математическая, графическая, логическая, экономическая и т.д.), а умение программировать, которое вырабатывается только в результате самостоятельного кропотливого и продолжительного программирования многих задач различной сложности, не важно на каком языке программирования. Программист, умеющий программировать на одном языке, может успешно программировать на любом другом языке программирования, но не наоборот!
Авторы желают читателю настойчивости и успехов в изучении и освоении азов разработки приложений на языках программирования C++ и С#.
Глава 1. C++
Язык С (читается "Си") создан в начале 70х годов, Кенном Томпсоном и Дэннис Ритчи из Bell Labs для компиляции операционной системы UNIX. Операционная система UNIX первоначально распространялась в исходных кодах на С среди университетов и лабораторий, а получатель мог откомпилировать исходный код на С в машинный код с помощью подходящего компилятора С.
В 1990 году был разработан стандарт языка С ANSI/ISO 9899:1990.
Бьерн Страуструп  разработал новую версию С++ [1, 2, 5]. Сегодня это один из наиболее популярных языков программирования в мире. C++ наследует как хорошие, так и плохие стороны С. Язык C остается подмножеством языка C++ 
Название C++ выдумал Рик Масситти. Название указывает на эволюционную природу перехода к нему от C. "++" - это операция приращения в C.
Язык программирования C++ в настоящее время считается господствующим языком, используемым для разработки коммерческих продуктов, 90% игр пишутся на С++ с прменением DirectX. В пособии использовались частично материалы из [4].

1.1. Лексические структуры языка
1.1.1. Элементы
Программа представляет собой строку символов, состоящую из лексических элементов пяти типов: зарезервированные (ключевые) слова, константы, операции, ограничители и идентификаторы. Смежные элементы отделяются друг от друга разделителями или комментариями. Разделители состоят из пробелов, символов табуляции, возврата каретки, перевода строки. В конце команды указывается точка с запятой. Специальный символ переноса команды отсутствует. Перенос команды может быть в любом месте, где допускается пробел.
Комментарии служат для документирования программы и ограничиваются символами «/*» и «*/». Комментарии могут содержать любое количество символов или строк символов и трактуются компилятором как разделители. В конце строки после символов «//» можно указать одностроковый комментарий.
Идентификаторы пользователя состоят из букв и цифр и могут содержать символ «подчеркивание». Значащими являются первые 32 символа идентификатора, а остальные игнорируются.
Рекомендуется использовать в идентификаторах по возможности только строчные буквы.
Внимание! В идентификаторах прописные и строчные буквы различаются, например: идентификатор Bread отличается от bread. Зарезервированные (ключевые) слова (имена параметров команд, встроенных функций и другие встроенные в С++ идентификаторы) нельзя использовать в качестве идентификаторов пользователя.
1.1.2. Константы
Константы целого типа могут задаваться в десятичной, восьмеричной или шестнадцатеричной системах счисления.
Десятичные целые константы начинаются не с нулевой цифры. Восьмеричные константы всегда начинаются с цифры нуль (017).
Шестнадцатеричные константы всегда начинаются с символов 0X или ox (0X10A).
Константы вещественного типа состоят из цифр, десятичной точки и знаков десятичного порядка е или Е. Ниже приведены все возможные варианты записи констант вещественного типа: 1., 2е1, .1234, .1е3, .1, 2Е1, 1.234, 0.0035е-6, 1.0, 2e-1, 2.1e-12.
Символьные константы содержат один символ, заключенный в апострофы. Все символьные константы имеют значение типа int (целое), совпадающее с кодом символа в кодировке ASCII. Для повышения читабельности программы следует, где возможно, указывать символьную константу вместо кода символа.
Пример. Фрагмент кода if (ch >= 'а' && ch <= 'z' ) будет более наглядным, чем эквивалентный ему фрагмент if (ch >= 97 && ch <= 122 ) .
Управляющие символы (коды) и символы, которые не имеют графического изображения, задаются в виде: \n (новая строка), \t (горизонтальная табуляция), \v (вертикальная табуляция), \b (возврат на символ), \r (возврат в начало строки); \f (прогон бумаги до конца страницы), \\ (обратный слеш), \’ (апостроф), \» (кавычка), \а (звуковой сигнал), \ddd (код символа в ASCII - от одной до трех восьмеричных цифр), \xhhh (код символа в ASCII - от одной до трех шестнадцатеричных цифр).
Строковые константы состоят из нуля или более символов, заключенных в двойные кавычки («Иванов»). В строковых константах могут быть управляющие символы. Обратный слеш используется как символ переноса текста на новую строку.
1.1.3. Типы данных
Все переменные должны быть объявлены. При объявлении переменных вначале указывается тип, а затем имена переменных через запятую. Переменные можно инициировать в месте их описания (Int height=71).
Скалярные типы данных приводятся в следующих двух таблицах.
Простейшие скалярные стандартные типы
С++Builder
Delphi
Тип
Число
байтов
Диапазон значений

unsigned char13 XE "unsigned char" 15
Byte,
ByteBool,
AnsiChar
Целое, символ
1
[0,255]

char13 XE "char" 15
ShortInt,
Char
Целое
1
[-128,128]

wchar13 XE "wchar" 15_t
WideChar
Символ Unicode
2


unsigned short13 XE "unsigned short" 15
Word,
WordBool
Целое
2
[0,65535]

short13 XE "short" 15
SmallInt
Целое
2
[-32768,32767]

int13 XE "int" 15
Integer
Целое
2
[-32768,32767]

unsigned long
Cardinal,
LongBool
Целое
4
[0,4294967295]

long13 XE "long" 15
LongInt
Целое
4
[-2147483648,
2147483647]

float13 XE "float" 15
Single,
real
Вещественное
4
[3.4x10-38,
3.4x1038]

double13 XE "double" 15
Double,
comp
Вещественное
8
[1.7x10-308,1.7x10308]

long double
Extended
Вещественное
10
[3.4x10-4932,
1.1x104932]

unsigned
char13 XE "unsigned" 15 *
PChar,
PAnsiChar
Указатель на символы без знака
4


void13 XE "void" 15 *
Pointer
Указатель
4


bool13 XE "bool" 15
Boolean
Логический
1
false, true


Дополнительные типы, реализуемые классами
С++Builder
Delphi
Тип

Set13 XE "Set" 15
Set
Множество 1-32 байт

String13 XE "String" 15
String
Cтрока, подобная при работе строке Delphi

SmallString13 XE "SmallString" 15
String[n]
Короткие строки в Паскале длиной до 255 символов

AnsiString13 XE "AnsiString" 15
AnsiString
Текстовая строка Delphi произвольной длины

Variant13 XE "Variant" 15
Variant
Любое значение

TdateTime13 XE "TDateTime" 15
TDateTime
Значение даты и времени в виде Float

Currency13 XE "Currency" 15
Currency
Значение денежной величины

Рассмотрим отдельно эти типы.
Set13 XE "Set" 15 реализуется шаблонным классом Set:
Set<<тип>,<мин.значение элемента множества>,<макс. значение(<=255)>>
Пример:
typedef Set bolhiebukvi; // прописные латинские буквы
bolhiebukvi glasnie, soglasnie; // объявление множеств гласных и согласных
glasnie <<'A'<<'I'<<'E'; // заполнение множества гласными буквами
soglasnie <<'B'<<'C'<<'D'; // заполнение множества согласными буквами
// проверка принадлежности буквы B’ принадлежности множеству glasnie
Label1->Caption=glasnie.Contains('А')?»Да»:»Нет»; // вывод «Да»
String13 XE "String" 15 реализуется в виде: String <список имен>. Эти строки могут использоваться в привычных операциях сцепления (+) и сравнения строк (==).
Внимание! Отсчет символов начинается не с нуля, а с единицы
Перечислим основные методы (имя строки и метод разделяются точкой) работы с этими строками:
ToDouble/ToInt  перевод строки в вещественное/целое число.
c_str13 XE "c_str" 1513 XE "Length" 15  возвращает указатель на символьный массив с исходной строкой.
Length, IsEmpty  возвращает длину строки, признак пустой строки (True).
IsEmpty13 XE "IsEmpty" 15  возвращает true, если длина строки нулевая.
Insert13 XE "Insert" 15(i)  вставка строки после iй позиции исходной строки.
Delete/SubString13 XE "Delete" 15(i,n)  удаление/выделение подстроки длиной n с iй позиции исходной строки (r=Label1->Caption.SubString(2,3)).
LastDelimiter13 XE "LastDelimiter" 15  возвращает позицию последнего символаограничителя. LowerCase13 XE "LowerCase" 15/UpperCase13 XE "UpperCase" 15  перевод строки в нижний/верхний регистр.
Trim, TrimLeft/TrimRight13 XE "Trim" 15  убрать пробелы и управляющие символы в начале и в конце строки, только в начале/конце строки соответственно.
Format13 XE "Format" 15  форматирование строки, аналогично функции printf.
ToInt13 XE "ToInt" 15/ToDouble13 XE "ToDouble" 15 перевод числовой строки к целому/вещественному числу.
AnsiPos(s), Pos(s)  возврат номера первого символа вхождения строки S.
Пример формирования и вывода фамилии, имени и отчества:
String Fio, Fam=«Иванов», Imj=«Иван»; Fio=Fam+’ +Imj+’ ;
Fio.Insert(«Иванович»,Fio.Length()+1); Label1->Caption=Fio;
SmallString13 XE "SmallString" 15 реализуется в виде: SmallString <длина> <имя строки>.
Пример: SmallString<30>Fam; Fam=«Иванов»; Label1->Caption=Fam;
AnsiString13 XE "AnsilString" 15 реализуется в виде:
AnsiString<имя переменной>[<длина>]. Этот тип эквивалентен типу String.
Пример:
AnsiString Fio, Fam=«Иванов», Imj=«Иван»; Fio=Fam+’ +Imj+’ ;
Fio.Insert(«Иванович»,Fio.Length()+1); Label1->Caption=Fio;
Variant13 XE "Variant" 15 реализуется в виде: Variant <список имен переменных>.
Пример:
Variant Fam=«Иванов»,Dp=Date();//объявление универсальных переменных
Label1->Caption=Fam+DateToStr(Dp); // формирование и вывод метки
TDateTime13 XE "TDateTime" 15 реализуется в виде: TDateTime <список имен переменных>. Этот тип имеет структуру типа double, которая содержит в целой части значение даты (порядкового номера дня начиная с 30.12.1899), а в дробной  значение времени (отсчитывая от 12:00).
Пример: TDateTime d=Date(); Label1->Caption=d+1; // дата на завтра
Currency13 XE "Currency" 15 реализуется в виде: Currency <список имен переменных>.
Currency Stoimoct=123565.15; Label1->Caption=Stoimoct;
Переменныеконстанты задаются добавлением модификатора const и значений при объявлении этих переменных. Попытки изменить эти значения операторами присваивания будут обнаружены при компиляции.
Пример. const int a=1; /* переменнаяконстанта*/ a=2; // ошибка
Переопределение типа можно осуществить оператором typede13 XE "typedef" 15f.
Пример переопределения типа long double на новый тип vehhiclo:
typedef long double vehhiclo;vehhiclo a=1.2, b=1.6; // перемен. типа vehhiclo
1.1.4. Массивы
Массив13 XE "Массив" 15 - это набор объектов одинакового типа, доступ к которым осуществляется прямо по индексу в массиве. Обращение к массивам осуществляется с помощью указателей (pointers) (п.6.3).
Одномерный массив можно описать следующим образом:
<тип_данных> <имя_массива > [< размер>];
Используя имя массива и индекс, можно адресоваться к элементам массива: <имя_массива> [< значение_индекса >]
Значения индекса должны лежать в диапазоне от нуля до величины, на единицу меньшей, чем размер массива, указанный при его описании.
Пример: char fam [20]; // массив (строка) из 20 символов.
Двумерный массив можно описать следующим образом:
<тип_данных> <имя_массива> [<размер_1>] [< размер_2>];
Пример. int kol [30][20]; // таблица 30 на 20 чисел типа int.
Аналогично описываются массивы и больших размерностей.
Многомерные массивы располагаются в памяти так, что быстрее всего меняется последний индекс.
Начальные значения элементам массива можно присвоить при его объявлении в виде:
<тип имя_массива> [...] = {< знач-1>,< знач-2>, ...,< знач-N >};
Если пользователь не указал в квадратных скобках размер массива, то компилятор сам задает размер массива по числу приведенных начальных значений в фигурных скобках.
Примеры инициализации одномерных массивов:
int data [5 ]={5, 4, 3, 2, 1}; float scores [ ] = {3.4, 2.7, 1.8, 6.9, -24.3};
char tovar [20 ] = {«Сапоги»}; // строка «Сапоги»
char prompt [ ] = {«Ответ:»}; // строка «Ответ:»
char prompt [ ] = {'О', 'т', 'в', 'е', 'т', ':', '\0' }; // строка «Ответ:»
1.1.5. Структуры (записи)
Структуры (записи)  это группа логически связанных переменных. Объявление структуры имеет вид:
struct13 XE "struct" 15 [<имя структуры>]
{ <тип поля 1> <имя поля 1>;
...
<тип поля n > <имя поля n>;
} [<список имен структурных переменных>];
Описание переменной структурного типа выглядит следующим образом: struct <имя структуры> <список переменных-записей>;
Имя структурной переменной (записи) можно указать и сразу при объявлении структуры перед правой фигурной скобкой.
Структурным переменным можно присваивать значения агрегатно (сразу по всей структуре), но их нельзя сравнивать на равенство или неравенство. К полям записи можно обращаться, указывая имя переменной-записи, имя поля и разделяя эти имена точкой.
Пример. type1 valuel = x.field1; type3.value3 = z.field3;
Если структуры являются глобальными или описаны, как static, внутри функции, то их, как и массивы, можно инициализировать непосредственно в месте описания. Начальные значения для каждой структуры задаются внутри набора фигурных скобок. Соответствие между константами и полями устанавливается по порядку записи. Это означает, что первая по порядку константа связывается с первым по порядку полем, вторая - со вторым и т.д.
Комбинируя структуры и массивы, можно строить универсальные и гибкие структуры данных.
Пример
struct stovar // объявление структуры под именем stovar
{ int kt; // код товара - целочисленная переменная
char nt [20]; // наименование товара - строка из 20 байтов
} // конец тела структуры
zstovar={1,”Сыр”}; // наименование переменной-записи и значения полей
stovar mzstovar [2]; // объявление массива записей типа stovar
mzstovar[1].kt=2; // задание значения поля kt второй записи массива
printf(«\n%d, %d %s»,zstovar.kt,mzstovar[1].kt,zstovar.nt); // вывод значений
Битовые поля13 XE "Битовые поля" 15 задаются в виде:
<целочисленный тип> [<имя>] : <ширина в битах (<=64)>;
Раполагаются поля в памяти слева направо.
Пример.
struct vector {int i:2; int:2; unsigned j:4; long k:64;} a,b,c;
1.1.6. Объединения union13 XE "union" 15
Объединения соответствуют типам вариантных записей языка Delphi и объявляются подобно структурам. Активным может быть только одно поле. Все поля перекрывают друг друга в памяти.
Размер объединения равен размеру наибольшего поля.
Пример:
union un {int i; float f; char c;} a,b; // объявление объединения
a.i=1; Label1->Caption=a.i; // использование поля i
a.f=12.34; Label2->Caption=a.f; // использование поля f
a.c='w'; Label3->Caption=a.c; // использование поля c
1.1.7. Перечисления enum13 XE "enum" 15
Перечисления служат для присвоения имен набору целых чисел (int), что повышает наглядность и надежность задания правильных значений переменной. Объявление имеет вид:
enum [<имя перечисляемого типа для объявления переменных>]
{<имя 1>[=<значение 1>],...,<имя N>[=<значение N>]}
[<список имен перечисляемых переменных>] ;
По умолчанию значение первого элемента равно нулю, а значение следующего элемента списка на единицу больше.
Пример задания имен дням недели, начиная с понедельника:
int main(int argc, char **argv) // основная процедура
{enum dninedeli {poned=1,vtor,sreda,hetv,pjtn,subb,vosk} den; // дни недели
den=vosk; // задание значения перечисляемой переменной den
if (den==vosk) printf(«Воскресенье %d день недели», den); getch(); // вывод
}
1.2. Основные возможности
1.2.1. Предпроцессор
В задачи предпроцессора входят: подключение (при необходимости) к данной программе внешних файлов, указываемых директивой #include, и выполнение его директив.
1.2.2. Директива #Include13 XE "#Include" 15
Во многие программы подставляются один или несколько файлов, часто в самое начало кода главной программы main. Появление директив:
#include <файл_1>
...
#include «файл_n»
приводит к тому, что препроцессор подставляет на место этих директив тексты файлов: файл_1 файл_2 файл_n соответственно. Если имя файла заключено в кавычки, то включается файл пользователя. Если имя файла заключено в угловые скобки, то файл входит во внешние библиотеки C.
1.2.3. Директива #define13 XE "#define" 15
С помощью директивы #define, вслед за которой пишутся имя и значение макрооператора, оказывается возможным указать предпроцессору, чтобы он при любом появлении в исходном файле данного имени заменял это имя на соответствующее значение макрооператора (именованные константы (п. 1.1.1)).
Пример:
#define square (х) ((х)*(х)); /* задает замену символа square (аргумент) на значение (аргумент) * (аргумент) */
Пример:
#define рi 3.1415926; /* связывает идентификатор pi со значением 3.1415962 */
1.2.4. Функция вывод на терминал - Printf13 XE "Printf" 15
Функция включена в библиотеку stdio.h (стандартный ввод / вывод) и используется в С и в консольных приложениях С++ и обычно имеет вид:
int printf («<управляющая строка>« ,<список выводимых значений>);
Управляющая строка содержит набор спецификаций (шаблонов редактирования), управляющих и информационных символов, который выводятся без изменения).
Спецификация начинается с символа % и имеет вид:
% [<флаг>] [<ширина>] [.<точность>] <символ формата>
<флаг> - задает порядок вывода данных:
минус - выравнивание строковых данных по левому краю поля;
плюс - вывести знак значения: плюс или минус;
пусто - для неотрицательных значений вместо знака вывести пробелы.
<ширина> - минимальный размер поля вывода;
<точность> - задает число:
цифр для целочисленных данных;
цифр после десятичной точки для вещественных данных;
символов для строковых данных;
<символ формата> - задает тип выводимого данного: с (один символ), s (строка символов); d/u (десятичное целое со знаком/без знака); f/e/g (вещественное число в обычной/экспоненциальной/смешанной форме); % (процент), n, p (указатели).
Пример:
printf(“\n Возраст Володи -%d. Его доход %.2f рублей.”, age , income );
1.2.5. Функция ввод с клавиатуры - Scanf13 XE "Scanf" 15
Функция включена в библиотеку stdio.h и используется в С и в консольных приложениях С++ и обычно имеет вид:
int scanf («<управляющая строка>«,<список адресов переменных ввода>);
Каждой вводимой переменной в строке функции scanf должна соответствовать спецификация ввода. Перед именами переменных следует поставить символ &.(«взятие адреса»).
Спецификация начинается с символа % и имеет вид:
% [*] [<ширина>] [h|l|L] <символ формата>
 пропустить вводимое значение.
<ширина>  максимально вводимое число символов (ширина поля ввода).
h|l|L  тип модификации символа формата по умолчанию: h (short int), l (long int или double), L (long double).
<символ формата> - задает тип вводимого данного: d, i (int); D, I (long); e, E, f, g, G (float); u (unsigned int); U (unsigned long); s (строка); c (char); n, p (указатели).
Пример:
float weight; /* вес */ int height; /* рост */
printf ( «Введите ваш вес и рост « ); scanf («%f %d «, &weight, &height);
1.2.6. Функция Main в консольных приложениях
Каждый исполняемый файл консольного приложения должен содержать функцию main13 XE "main" 15 (главная). Если функция main имеет параметры, то эти параметры выбираются из строки вызова, и их значениями являются строки символов. В этом случае заголовок main и вся функция имеет вид: int main (int argc, char **argv) { /* тело функции */ }
В заголовке функции указываются два аргумента:
аrgc - число передаваемых в командной строке вызова аргументов + 1;
argv - массив строк со значениями аргументов в командной строке. Строка, определяемая argv[0], содержит имя самой программы. Все значения передаются в виде символьных строк. Если значение аргумента в командной строке содержит пробелы, то оно заключается в кавычки. Количество аргументов может быть выражено переменным числом.
1.2.7. Функции
Процесс разработки приложения предполагает расчленение сложной задачи на функции. Обычно функции задаются после основной функции. Функции могут иметь несколько параметров и возвращают значение скалярного типа, типа void13 XE "void" 15 (отсутствие возвращаемого значения) или указатель. Возвращаемое значение формируется оператором return13 XE "return" 15 (п.6.2.10.2). При вызове функции значения аргументов, задаваемые на входе, должны соответствовать числу и типу параметров в описании функции. С++ поддерживает прототипы (объявления) функций.
Пример функции cube, вычисляющей куб числа:
Int main(int argc,char **argv) // основная функция
{double cube(double x); // объявление функции cube
printf(«\n2 в кубе=%.0f «,cube(2.0));/*вывод куба числа 2*/getch();return 0;}
double cube( double x ) { return x * x * x ; } // тело функции cube
Изменение значения аргумента в функции производится путем передачи его адреса (например, в виде &<имя переменной> (п. 6.3)).
Пример передачи адреса аргумента:
int main(int argc, char **argv) // основная функция
{void vvod(char *s, int *v); // объявление функции адресом аргумента int *v
int vozrast; vvod(«Введите возраст сотрудника»,&vozrast);// вызов функции
printf(«\n %d»,vozrast); getch();} // конец основной функции
void vvod(char *s, int *v) {printf («\n %s»,s); scanf(«%d»,v);}// функция ввода
Перегруженные функции задают семейство одноименных функций с различными типами параметров. Компилятор автоматически выберет нужную функцию по типам аргументов.
Пример функций add сложения вещественных и целых чисел:
void __fastcall TForm1::Button1Click(TObject *Sender) // основная функция
{float add(float x,float y);Label1->Caption=add(1.2,2.4); //вещественные числа
int add (int x, int y); Label2->Caption=add(1,5); // целые числа
}
float add (float x, float y) {return x+y;} // функция сложения вешественных int add (int x, int y) {return x+y;} // функция сложения целых чисел
Для таких функций лучше использовать шаблоны функций (п. 6.6.4).
1.2.8. Классы памяти
Каждая переменная и функция, описанная в программе, принадлежат к какому-либо классу памяти. Класс памяти переменной определяет время ее существования и область видимости. Класс памяти для переменной задается либо по расположению ее описания, либо при помощи специального спецификатора класса памяти, помещаемого перед обычным описанием. Класс памяти для функции всегда external13 XE "external" 15, если только перед описанием функции не стоит спецификатор static13 XE "static" 15. Все переменные можно отнести к одному из следующих классов памяти: automatic13 XE "automatic" 15 (автоматическая, локальная), register13 XE "register" 15 (регистровая), extern (внешняя), static (статическая).

1.2.8.1. Автоматические переменные
Автоматические переменные можно описывать явно, используя спецификатор класса памяти auto13 XE "auto" 15. По умолчанию принимается, что всякая переменная, описанная внутри функции (локальная переменная) или внутри блока (группа команд, заключенная в фигурные скобки) и не имеющая явного указания на класс памяти, относится к классу памяти для автоматических переменных. Поле видимости автоматической переменной начинается от точки ее описания и заканчивается в конце блока, в котором переменная описана. Доступ к таким переменным из внешнего блока невозможен.
Память для автоматических переменных отводится динамически во время выполнения программы при входе в блок, в котором описана переменная. При выходе из блока память, отведенная под все его автоматические переменные, автоматически освобождается. Доступ к автоматической переменной возможен только из блока, где переменная описана, так как до момента входа в блок переменная вообще не существует.

1.2.8.2. Регистровые переменные
Спецификатор памяти register13 XE "register" 15 может использоваться только для автоматических переменных или для формальных параметров функции. Такой спецификатор указывает компилятору на то, что пользователь желает разместить переменную не в оперативной памяти, а на одном из быстродействующих регистров компьютера.
Рекомендуется спецификацию register использовать для переменных, доступ к которым в функции выполняется часто. Полученный в результате код будет выполняться быстрее.

1.2.8.3. Статические переменные и функции
Функции и переменные, для которых указан класс памяти static13 XE "static" 15, видимы лишь от точки описания до конца файла. Если пользователь не указал начального значения, то все статические переменные, как и внешние, инициируются значением нуль. Инициирование структурных статических переменных выполняется по тем же правилам, что и внешних. Если статическая переменная описана внутри функции, то первый раз она инициируется при входе в блок функции. Значение переменной сохраняется от одного вызова функции до другого. Таким образом, статические переменные можно использовать для хранения значений внутри функции на протяжении времени работы программы, причем такие переменные будут невидимы вне файла, где они определяются.

1.2.8.4. Внешние переменные
Любая переменная, описанная вне какой-либо функции и не имеющая спецификатора памяти, является внешней или глобальной переменной. Область видимости такой переменной простирается от точки ее описания до конца файла. Внутри локального блока одноименная локальная переменная заслоняет глобальную. Для внешних переменных память освобождается один раз и остается такой до окончания программы.
1.2.9. Операции
1.2.9.1. Арифметические операции
К арифметическим операциям относятся: сложение (+), вычитание (-), деление (/), умножение (*) и остаток от деления (%). Остаток не определен для вещественных переменных. Целочисленные сложение и вычитание выполняются без учета переполнения.
Операция поразрядного сдвига целого числа E влево или вправо на E2 разрядов имеет вид соответственно: E<>E2.

1.2.9.2. Операции отношения
В языке определены следующие операции отношения: равенство (==13 XE "==" 15, два знака равества), неравенство (!=13 XE "!=" 15), меньше (<), меньше или равно (<=), больше (>), больше или равно (>=).
Все перечисленные операции вырабатывают результат типа int (в числовых выражениях) или bool (в логических выражениях). Если данное отношение между операндами истинно, то значение этого целого - единица (true), а если отношение ложно, то нуль (false).
Все операции типа «больше - меньше» имеют равный приоритет, причем он выше, чем приоритет операций == и !=. Приоритет операции присваивания ниже приоритета всех операций отношения. Для задания правильного порядка вычислений используются скобки.

1.2.9.3. Логические операции
Допускаются следующие логические операции: &&13 XE "&&" 15 (И), ||13 XE "||" 15 (Или, две вертикальные черточки), ! (отрицание, восклицательный знак).
Аргументами логических операций могут быть любые числа, включая задаваемые аргументами типа char или логические переменные (bool). Результат логической операции аналогичен результату операции сравнения. Вообще все числовые значения, отличные от нуля, интерпретируются как истина.
Логические операции имеют самый низкий приоритет.
Внимание! Вычисление выражений, содержащих логические операции, производится слева направо и прекращается (усекается), как только удастся определить результат, т.е. остальные проверки, не влияющие на конечный результат, не производятся.
Для целочисленных переменных существуют операции поразрядного И (&), ИЛИ (^), исключающего ИЛИ (|, вертикальная черта), отрицания (~, тильда).
1.2.9.4. Операции присваивания
В одном операторе операция присваивания может встречаться несколько раз. Вычисления производятся справа налево.
Пример: а = ( b = c) * d; // в начале вычисляется b = c, далее a=b*d.
Пример использования многократного присваивания: a=b=c=d=e=0.
Операции a+=b, a-=b, a*=b и a/=b являются укороченной формой записи, соответственно: а = а + b; а = а - b; a= а* b; а = а/b.
Префиксные и постфиксные операции «++» (два плюса) и «–» (два минуса) используют для увеличения (инкремент) и уменьшения (декремент) на единицу значения переменной до использования переменной в выражении, если операция указана перед именем переменной; если операция указана после имени переменной, то после использования переменной соответственно.
Если тип левой части присваивания отличается от типа правой части, то тип правой части приводится к типу левой.
Пример вычисления выражения и вывода его значения (50):
int main(int argc, char **argv) { int a,b,c=3,d=4,f=3,g,h=5,z=6,i;
a=z+(b=c*d*f +(g= h +(i=3))); printf (“%d\n”, a ); getch(); return 0;}
Операцию sizeof (размер) можно применить к константе, типу или переменной. В результате будет получено число байтов, занимаемых операндом. Если операндом является тип, то такой операнд следует заключить в круглые скобки. Если операнд - переменная, то скобки можно опустить.
Операция «запятая» применяется для связывания между собой выражений. Список выражений, разделенный запятыми, трактуется как единое выражение и вычисляется слева направо.
1.2.10. Операторы

1.2.10.1. Блоки и составные операторы
Любая последовательность операторов, заключенная в фигурные скобки, является составным оператором (блоком). Составной оператор может использоваться везде, где синтаксис языка допускает обычный оператор. Идентификатор, объявленный в блоке, имеет область действия от точки объявления до конца блока.

1.2.10.2. Оператор возврата из функции  return13 XE "return" 15
return [<выражение>];
Оператор предназначен для выход из функции со значением указанного выражения. Если выражение отсутствует, то в объявлении функции это указывается параметром void перед именем функции.

1.2.10.3. Условный оператор  if13 XE "if" 15
if (<условие>) <оператор-1 > [else <оператор-2>]
Если условие истинно, то выполняется <оператор-1>, в противном случае - <оператор-2>. Синтаксис предписывает, что else всегда относится к ближайшему оператору if.
Пример вложенного оператора if:
int main(int argc, char **argv) { int i = 4, j = 6, k = 8; if (i < k) if (i > j)
printf ( «оператор 1\n» ); else printf ( «оператор 2\n»);getch(); return 0; }

1.2.10.4. Условная операция  ?13 XE "?" 15
<результат >= (<условие>) ?< выражение-1> :< выражение-2 >
Если условие истинно, то результату присваивается значение <выражение-1>, иначе  < выражение-1>.
Пример: main ( ) {int i = 6, j = 4; int result = ( i < j ) ? i : j; }

1.2.10.5. Оператор выбора варианта  switch13 XE "switch" 15
switch (< выражение >)
{ case <константное выражение_1> : <операторы> []
...
case <константное выражение_n > : <операторы> []
[default: <операторы>]
}
После вычисления выражения в заголовке оператора его результат последовательно сравнивается с константными выражениями, начиная с самого верхнего, пока не будет установлено их соответствие. Тогда выполняются операторы внутри соответствующего case, управление переходит на следующее константное выражение, и проверки продолжаются. Именно поэтому в конце каждой последовательности операторов должен присутствовать оператор break13 XE "break" 15. После выполнения последовательности операторов внутри одной ветки case, завершающейся оператором break, происходит выход из оператора switch. Обычно оператор switch используется тогда, когда программист хочет, чтобы была выполнена только одна последовательность операторов из нескольких возможных. Каждая последовательность операторов может содержать нуль или более отдельных операторов. Фигурные скобки в этом случае не требуются.
Если ветка, называемая default (умолчание) есть, то последовательность операторов, стоящая непосредственно за словом default и двоеточием, выполняется только тогда, когда сравнение ни с одним из стоящих выше константных выражений не истинно.

1.2.10.6. Оператор безусловного перехода  goto13 XE "goto" 15
Оператор goto используется для передачи управления внутри функции от одного оператора к другому. Синтаксис оператора такой:
goto <идентификатор>. Управление передается безусловно на оператор, помеченный указанным идентификатором.
Пример: goto backend; ... backend: x+= 3; ...
Рекомендуется минимизировать число операторов goto и не входить извне внутрь блока операторов if, else, switch или операторов цикла.

1.2.10.7. Цикл с предусловием  while13 XE "while" 15
while (<условие>) <оператор>.
Проверка условия производится перед выполнением тела цикла. Если результат вычисления условного выражения  истина, то выполняется оператор (или группа операторов). Перед входом в цикл while в первый раз обычно инициализируют одну или несколько переменных для того, чтобы условное выражение имело какое-либо значение. Оператор или группа операторов, составляющих тело цикла, должны, как правило, изменять значения одной или нескольких переменных, входящих в условное выражение, с тем, чтобы в конце концов выражение обратилось в нуль, и цикл завершился. Оператор continue13 XE "continue" 15 передает управления на начало следующего повторения цикла. Цикл while завершается, если условие стало ложным или в теле цикла встретился оператор break13 XE "break" 15 или return.
Пример программы поиска элемента в массиве:
int main(int argc, char **argv) // основная функция
{ int scores[100];extern int search(int data[ ],int size,int key);// объявл.функции
int i; for (i = 0; i < 100; i++) scores [ i ] = i; // заполнение массива
printf( «\nИндекс числа 107 в массиве = %d\n»,search (scores, 100, 107 ) );
getch(); return 0;
} // конец основной функции
int search (int data [],int size,int key) // функция поиска элемента массива
{ int index = 0; while ( index < size && data [ index ] != key ) index++;
return ( data [index]==key )?index : -1;}

1.2.10.8. Цикл с постусловием  do while13 XE "do while" 15
В цикле do while проверка условия осуществляется после выполнения тела цикла. Синтаксис цикла: do <оператор>while (<условие>);
Оператор continue передает управление на начало следующего повторения цикла. Цикл прекращает выполняться, когда условие становится ложным или внутри цикла встретился оператор break или return.
Пример функции сравнения двух строк (str1, str2):
int main(int argc, char **argv) // основная функция
{extern int compare ( char str1 [ ], char str2 [ ] ); char str1 [ 80 ], str2 [ 80 ];
printf («\nВведите первую строку: «); scanf( «%s», str1); // ввод строки 1
printf («\nВведите вторую строку: « ); scanf ( «%s», str2); // ввод строки 2
if ( compare (str1,str2 )< 0) printf ( «\nПервая строка меньше второй «);
else if (compare (str1,str2 )==0) printf ( «\n\nПервая строка равна второй»);
else printf («\n\nПервая строка больше второй»); getch();
} // конец основной функции
int length (char str [ ]) // функция вычисления длины строки
{int index=0; while (str [index++]!= 0 ); return -index;}
int compare (char str1 [ ], char str2 [ ] ) // функция сравнения строк
{ extern int length(char str[ ]); int len1 = length(str1); int len2=length( str2 );
int index=-1; int minlength=(len1 do index++; while (index < minlength && str1[index] ==str2[index]);
if (len1== len2 && str1[index] == str2[index]) return 0; // строки равны
if ( str1[index]==str2[index] &&len1 < len2)return -1; // строка 1 < строки 2
if (str1[index]==str2[index] &&len2 > len1) return 1; // строка 1 > строки 2
if (str1[index ] строки 2
}
1.2.10.9. Итерационный цикл  For13 XE "For" 15
for ([<выражение-1>];[<выражение-2>];[< выражение-3>]) <оператор>
Формально правила выполнения этого оператора можно описать так:
Если первое выражение присутствует, то оно вычисляется.
Вычисляется второе выражение (если оно присутствует). Если вырабатывается значение 0 (false), то цикл прекращается, в противном случае цикл будет продолжен.
Исполняется тело цикла (<оператор>).
Вычисляется третье выражение (если оно присутствует).
Переход к пункту 2.
Появление в любом месте тела цикла оператора continue или break приводит к переходу к шагу 4 или к выходу из цикла соответственно.
Пример программы подсчета суммы ряда 1+1/2+1/3+1/4+...1/1000:
int main(int argc, char **argv) {
float s, i; for (s=0,i=1;i<=1000; s+=1/i++); printf ( «\n%20.8f», s); getch(); }
Пример программы подсчета среднего числа массива чисел 1,2,..,100:
# define size 100 // макроподстановка размерности массива - 100
int main(int argc, char **argv) { // основная функция
int data [size]; extern float average (int a[ ], int s ); int i;
for (i=0; i printf( «\nСреднее значение массива data=%f\n»,average(data,size));getch(); }
float average( int a [ ], int s ) // функция подсчета среднего числа массива
{ float sum = 0.0; int i; for (i = 0; i < s; i++) sum += a [ i ]; return sum / s; }
Пример программы вычисление максимальных и минимальных значений элементов массива случайных чисел:
# define size 100 // макроподстановка size=100  размерность массива
int main(int argc, char **argv) { // основная функция
float scores [size]; // объявление массива из ста вещественных чисел
float max(float data[ ],int s), min(float data[ ],int s); // объявление функций
int i; randomize(); // включение счетчика случайных чисел
for (i =0; i < size; i++ ) scores[ i ]= rand(); // заполнение массива случ.чисел
printf (« \nМаксимальное значение = %f», max( scores, size ));
printf («\nМинимальное значение = %f\n», min( scores, size )); getch(); } float max(float data [ ], int s ) { // функция поиска максимального числа
float maximum = data [ 0 ]; int i; for(i=1;i if (data[i]>maximum ) maximum=data[i]; return maximum; }
float min( float data [ ], int s ) { // функция поиска минимального числа
float minimum = data [0]; int i; for (i = 1; i < s; i++)
if ( data [1] < minimum ) minimum = data [i]; return minimum; }
Пример программы сортировки «методом пузырька» массива из десяти случайных чисел. В основной функции в массив data заносится size (десять) вещественных чисел, затем вызывается функция сортировки bubble_sort, после чего отсортированный массив распечатывается.
На первом проходе алгоритма сортировки все элементы массива, начиная с последнего, сравниваются попарно, и если элемент а[j] оказывается меньше, чем элемент а[j-l], то элементы меняются местами. После завершения первого прохода наименьший элемент массива будет помещен в a[0]. На втором проходе выполняются те же действия, однако проход заканчивается на элементе a[1]. После второго прохода второй по значению элемент будет в a[1] и т.д. Название «метод пузырька» дано алгоритму потому, что при каждом просмотре наименьшие элементы как бы медленно всплывают «наверх», подобно пузырьку воздуха в воде.
# define size 10 // макроподстановка size=10  размерность массива
int main(int argc, char **argv) { // основная функция
float data [size]; // объявление массива
extern void bubble_sort(float a[ ], int s); // объявление функции сортировки
int index; randomize(); // включение счетчика случайных чисел
for (index=0;index bubble_sort ( data, size ); // обращение к функции сортировки массива
for (index=0;index printf( «\ndata [ %d ] = %f», index, data [ index ]); getch(); }
void bubble_sort( float a [ ], int s ) { // функция сортировки массива
int i, j; float temp; // объявление переменных
for ( i=0;i for(j=s-1;j>1;j--) // внутренний цикл
if (a[j]
1.2.10.10. Пустой оператор
Пустой оператор представляется символом «;», перед которым нет выражения. Пустой оператор используют там, где синтаксис языка требует присутствия в данном месте программы оператора, однако по логике программы оператор должен отсутствовать.
Необходимость в использовании пустого оператора часто возникает при программировании циклов, когда действия, которые могут быть выполнены в теле цикла, целиком помещаются в заголовок цикла.

1.2.10.11. Указатели
Указатель13 XE "Указатель" 15 - это адрес памяти. Значение указателя сообщает, где размещен объект, но не говорит о самом объекте. Переменная типа указатель описывается так: <тип> *<переменная-указатель>. Данная запись означает, что переменная-указатель является указателем на любую переменную указанного типа.
Символ операции «*» (звездочка) используется для задания указателя на объект.
Пример: int *х; // указатель на любую переменную типа int. Указатель на тип void совместим с любым указателем.
Пример: void *х; int *y; // допустимо присваивание: y = x.
Двумя наиболее важными операциями, связанными с указателями, являются операция обращения по адресу (разадресации) и операция определения адреса. Операция обращения по адресу (*) служит для присваивания или считывания значения переменной, размещенной по адресу «переменная указатель» (*ptr_var = value).
Пример. Предложение *х=16 означает, что по адресу, задаваемому в х, помещается значение 16.
Операция определения адреса возвращает адрес памяти своего операнда. Операндом должна быть переменная. Операция определения адреса выполняется следующим образом:
<указатель-переменная>=&<переменная>;
Пример. Запись a=*&b равносильна записи a=b.
Для определения адреса массива операцию & можно не указывать перед его именем.
Если переменная, например, ptr определена как указатель на структуру, то для доступа к полю структуры (field); можно использовать операцию -> в виде: ptr->field, которая эквивалентна выражению (*ptr).field.
Существует четыре способа задать переменной-указателю начальное значение:
описать указатель вне любой функции или снабдить его предписанием static. Начальным значением является нулевой адрес памяти  0;
присвоить указателю адрес переменной;
присвоить указателю значение другого указателя;
использовать операторы распределения памяти new13 XE "new" 15 и delete13 XE "delete" 15.
Операция динамического выделения памяти имеет вид:
<указатель-переменная>=new [<имя переменной>] [<тип переменной>];
Операция возвращает нулевое значение, если не может выделить память.
Операция освобождения выделенной памяти имеет вид:
delete <указатель-переменная>.
Примеры:
ptr=new int [3];// выделение памяти для массива из трех элементов типа int
ptrf=new float[3][5];// выделение памяти для массива 3 на 5 чисел типа float
ptrstack=new stack; //выделение памяти для структуры (записи) stack
delete ptrstack; // освобождается память выделенная ранее по адресу ptrstack
Пример динамического формирования и вывода стека
int main(int argc, char **argv) { // создание и вывод стека из чисел 1,2,3,4,5
struct stack { int inf; stack* next;}; // объявление структуры (записи) stack
stack *top=0,*kon,*del;//объявление переменных-указателей на запись stack
for (int i=1;i<=5;i++) // цикл формирования стека из пяти записей
{ kon=new stack; // выделение памяти для новой записи
kon->next=top; kon->inf=i; //запоминание адреса предыдущей записи
top=kon; // запоминание адреса последней записи (вершины стека)
} // конец цикла формирования стека
kon=top; // установка адреса вершины стека (последней записи стека)
while (kon!=0) // цикл вывода записей стека на экран (cout << )
{cout<inf<next;delete del;}//вывод 5,4,3,2,1
getch(); return 0; } // задержка и завершение работы функции

1.2.10.12. Исключения. Обработка исключений
Для обработки исключений применяется конструкция try...catch. Она имеет следующую форму:
try
{
    инструкции, которые могут вызвать исключение
}
catch(объявление_исключения)
{
    обработка исключения
}
В блок после ключевого слова try помещается код, который потенциально может сгенерировать исключение.
После ключевого слова catch в скобках идет параметр, который передает информацию об исключении. Затем в блоке производится собственно обработка исключения.
Пример [5].
#include
double divide(int, int);
int main()
{
    int x = 500;
    int y = 0;
    try
    
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
Код, который потенциально может сгенерировать исключение - вызов функции divide помещается в блок try.
В блоке catch идет обработка исключения. Причем многоточие в скобках после оператора catch (catch(...)) позволяет обработать любое исключение.
В итоге когда выполнение программы дойдет до строки double z = divide(x, y);, будет сгенерировано исключение, поэтому последующие инструкции из блока try выполняться не будут, а управление перейдет в блок catch, в котором на консоль просто выводится сообщение об ошибке.


1.3. Потоки и система ввода-вывода
1.3.1. Базовые типы для работы с потоками
Объект типа ostream получает значения различных типов, преобразует их в последовательность символов и передает их через буфер в определенное место для вывода (консоль, файл, сетевые интерфейсы и т.д.).
Поток istream получает через буфер из определенного места последовательности символов (с консоли, из файла, из сети и т.д.) и преобразует эти последовательности в значения различных типов. То есть когда мы вводим данные (с той же клавиатуры в консоли), сначала данные накапливаются в буфере и только затем передаются объекту istream.
По умолчанию в стандартной библиотеке определены объекты этих классов - cout, cin, cerr, которые работают с консолью.

1.3.2. Запись в поток
Для записи данных в поток ostream применяется оператор <<. Этот оператор получает два операнда. Левый операнд представляет объект типа ostream, а правый операнд - значение, которое надо вывести в поток.
К примеру, по умолчанию стандартная библиотека C++ предоставляет объект cout, который представляет тип ostream и позволяет выводить данные на консоль [5]:
#include
int main()
{
    std::cout << "Hello" << std::endl;
    return 0;
}
1.3.3. Чтение данных
Для чтения данных из потока применяется оператор ввода >>, который принимает два операнда. Левый операнд представляет поток istream, с которого производится считывание, а правый операнд - объект, в который считываются данные.
Для чтения с консоли применяется объект cin, который представляет тип istream.
#
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
Для вывода сообщения об ошибке на консоль применяется объект cerr, который представляет объект типа ostream [5]:
#include
int main()
{    std::cerr << "Error occured" << std::endl;
    return 0;
}
1.3.4. Файловые потоки. Открытие и закрытие
При операциях с файлом вначале необходимо открыть файл с помощью функции open(). Данная функция имеет две версии:
open(путь)
open(путь, режим)
Для открытия файла в функцию необходимо передать путь к файлу в виде строки. И также можно указать режим открытия. Список доступных режимов открытия файла:
ios::in: файл открывается для ввода (чтения). Может быть установлен только для объекта ifstream или fstream
ios::out: файл открывается для вывода (записи). При этом старые данные удаляются. Может быть установлен только для объекта ofstream или fstream
ios::app: файл открывается для дозаписи. Старые данные не удаляются.
ios::ate: после открытия файла перемещает указатель в конец файла
ios::trunc: файл усекается при открытии. Может быть установлен, если также установлен режим out
ios::binary: файл открывается в бинарном режиме
Если при открытии режим не указан, то по умолчанию для объектов ofstream применяется режим ios::out, а для объектов ifstream - режим ios::in. Для объектов fstream совмещаются режимы ios::out и ios::in
Пример [5]
std::ofstream out;          // поток для записи
out.open("D:\\hello1.txt"); // окрываем файл для записи
std::ofstream out2;
out2.open("D:\\hello2.txt", std::ios::app); // окрываем файл для дозаписи
std::ofstream out3;
out2.open("D:\\hello3.txt", std::ios::out | std::ios::trunc); // установка нескольких режимов
std::ifstream in;       // поток для чтения
in.open("D:\\hello4.txt"); // окрываем файл для чтения
std::fstream fs;        // поток для чтения-записи
fs.open("D:\\hello5.txt"); // окрываем файл для чтения-записи
После завершения работы с файлом его следует закрыть с помощью функции close(). Также стоит отметить, то при выходе объекта потока из области видимости, он удаляется, и у него автоматически вызывается функция close [5].
#include
#include
int main()
{
    std::ofstream out;          // поток для записи
    out.open("D:\\hello.txt"); // окрываем файл для записи
    out.close();            // закрываем файл
 
    std::ifstream in;       // поток для чтения
    in.open("D:\\hello.txt"); // окрываем файл для чтения
    in.close();             // закрываем файл
 
    std::fstream fs;        // поток для чтения-записи
    fs.open("D:\\hello.txt"); // окрываем файл для чтения-записи
    fs.close();             // закрываем файл
    return 0;
}
1.3.5. Чтение и запись текстовых файлов
Потоки для работы с текстовыми файлами представляют объекты, для которых не задан режим открытия ios::binary.
Для записи в файл к объекту ofstream или fstream применяется оператор << (как и при выводе на консоль) [5]:
#include
#include
int main()
{
    std::ofstream out;          // поток для записи
    out.open("D:\\hello.txt"); // окрываем файл для записи
    if (in.is_open())
    {
        out << "Hello World!" << std::endl;
    }
Данный способ перезаписывает файл заново. Если надо дозаписать текст в конец файла, то для открытия файла нужно использовать режим ios::app [5]:
std::ofstream out("D:\\hello.txt", std::ios::app);
if (out.is_open())
{
    out << "Welcome to CPP" << std::endl;
}
out.close();
Если надо считать всю строку целиком или даже все строки из файла, то лучше использовать встроенную функцию getline(), которая принимает поток для чтения и переменную, в которую надо считать текст [5]:
#include
#include
#include
int main()
{
    std::string line;
    std::ifstream in("D:\\hello.txt"); // окрываем файл для чтения
    if (in.is_open())
    {
        while (getline(in, line))
        {
            std::cout << line << std::endl;
        }
    }
    in.close();     // закрываем файл
    std::cout << "End of program" << std::endl;
    return 0;
}

1.3.6. Переопределение операторов ввода и вывода
Операторы ввода >> и вывода << прекрасно работают для примитивных типов данных, таких как int или double. В то же время для использования их с объектами классов необходимо переопределять эти операторы.
Оператор <<
Обычно первый параметр оператора << представляет ссылку на неконстантный объект ostream. Данный объект не должен представлять константу, так как запись в поток изменяет его состояние. Причем параметр представляет именно ссылку, так как нельзя копировать объект класса ostream.
Второй параметр оператора определяется как ссылка на константу объекта класса, который надо вывести в поток.
Для совместимости с другими операторами переопределяемый оператор должен возвращать значение параметра ostream.
Также следует отметить, что операторы ввода и вывода не должны быть членами в классе, а определяются вне класса как обычные функции [5].
#include
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·Оператор >>
Первый параметр оператора >>, как правило, представляет ссылку на объект istream, с которого осуществляется чтение. Второй параметр представляет ссылку на неконстантный объект, в который надо считать данные.
Обычно в качестве результата операторы возвращают ссылку на поток ввода istream из первого параметра [5].
#include
#include
struct Person
{
    std::string name;
    int age;
};
std::istream& operator >> (std::istream& in, Person& p)
{
    in >> p.name >> p.age;
    return in;
}
int main()
{
    Person bob;
    std::cout << "Input name and age: ";
    std::cin >> bob;
    std::cout << "Name: " << bob.name << "\tAge: " << bob.age << std::endl;
    return 0;
}






Runtime_error: Division by zero!
The End...

Глава 2. C#
Язык C# появился в 2000 году, в результате работы большой группы разработчиков компании Microsoft, возглавляемой Андерсом Хейлсбергом (Anders Hejlsberg) для внедрения новых компонентных технологий и решений в области обмена сообщениями и данными, а также создания Internet-приложений (COM+, ASP+, ADO+, SOAP, Biztalk Framework) [2, 4]. В пособии использовались частично материалы их [4].

2.1. Переменные
Для хранения данных в программе применяются переменные. Переменная представляет именованную область памяти, в которой хранится значение определенного типа. Переменная имеет тип, имя и значение. Тип определяет, какого рода информацию может хранить переменная.
Перед использованием любую переменную надо определить. Синтаксис определения переменной выглядит следующим образом:
Вначале идет тип переменной, потом ее имя. В качестве имени переменной может выступать любое произвольное название, которое удовлетворяет следующим требованиям:
имя должно содержать не более 255 символов;
имя может содержать любые цифры, буквы и символ подчеркивания, при этом первый символ в имени должен быть буквой или символом подчеркивания;
в имени не должно быть знаков пунктуации и пробелов;
имя не может быть ключевым словом языка C#. Таких слов не так много, и при работе в Visual Studio среда разработки подсвечивает ключевые слова синим цветом.
Хотя имя переменой может быть любым, но следует давать переменным описательные имена, которые будут говорить об и предназначении.
Например, определим простейшую переменную:
string name;
В данном случае определена переменная name, которая имеет тип string, то есть переменная представляет строку. Поскольку определение переменной представляет собой инструкцию, то после него ставится точка с запятой.
При этом следует учитывать, что C# является регистрозависимым языком, поэтому следующие два определения переменных будут представлять две разные переменные:
string name;
string Name;
name = "Tom";
Так как переменная name представляет тип string, то есть строку, то мы можем присвоить ей строку в двойных кавычках. Причем переменной можно присвоить только то значение, которое соответствует ее типу.
В дальнейшем с помощью имени переменной мы сможем обращаться к той области памяти, в которой хранится ее значение.
Также мы можем сразу при определении присвоить переменной значение.
Данный примем называется инициализацией:
string name = "Tom";
Отличительной чертой переменных является то, что в программе можно многократно менять их значение. Например, создадим небольшую программу, в которой определим переменную, поменяем ее значение и выведем его на консоль:
using System;
 namespace HelloApp
{
    class Program
    {
        static void Main(string[] args)
        {
            string name = "Tom";  // определяем переменную и инициализируем ее
             Console.WriteLine(name);    // Tom
             name = "Bob";       // меняем значение переменной
            Console.WriteLine(name);    // Bob
             Console.Read();
        }
    }
}

2.1.1. Численные литералы
Литералы представляют неизменяемые значения (иногда их еще называют константами). Литералы можно передавать переменным в качестве значения. Литералы бывают логическими, целочисленными, вещественными, символьными и строчными. И отдельный литерал представляет ключевое слово null.
Логические литералы
Есть две логических константы - true (истина) и false (ложь):
Console.WriteLine(true);
Console.WriteLine(false);
Целочисленные литералы представляют положительные и отрицательные целые числа, например, 1, 2, 3, 4, -7, -109. Целочисленные литералы могут быть выражены в десятичной, шестнадцатеричной и двоичной форме.
Числа в двоичной форме предваряются символами 0b, после которых идет набор из нулей и единиц:
Console.WriteLine(0b11);         // 3
Console.WriteLine(0b1011);      // 11
Console.WriteLine(0b100001);    // 33
Для записи числа в шестнадцатеричной форме применяются символы 0x, после которых идет набор символов от 0 до 9 и от A до F, которые собственно представляют число:
Console.WriteLine(0x0A);    // 10
Console.WriteLine(0xFF);    // 255
Console.WriteLine(0xA1);    // 16
2.1.2. Вещественные литералы
Вещественные литералы представляют вещественные числа. Этот тип литералов имеет две формы. Первая форма - вещественные числа с фиксированной запятой, при которой дробную часть отделяется от целой части точкой.
Также вещественные литералы могут определяться в экспоненциальной форме MEp, где M мантисса, E - экспонента, которая фактически означает "*10^" (умножить на десять в степени), а p порядок.
2.1.3. Символьные литералы
Символьные литералы представляют одиночные символы. Символы заключаются в одинарные кавычки.
Символьные литералы бывают нескольких видов. Прежде всего это обычные символы: 2’, А’.
Специальную группу представляют управляющие последовательности Управляющая последовательность представляет символ, перед которым ставится обратный слеш. И данная последовательность интерпретируется определенным образом. Наиболее часто используемые последовательности:
'\n' - перевод строки;
'\t' – табуляция;
'\' - обратный слеш.
И если компилятор встретит в тексте последовательность \t, то он будет воспринимать эту последовательность не как слеш и букву t, а как табуляцию - то есть длинный отступ.
Также символы могут определяться в виде шестнадцатеричных кодов, также заключенный в одинарные кавычки.
Еще один способ определения символов представляет использования шестнадцатеричных кодов ASCII. Для этого в одинарных кавычках указываются символы '\x', после которых идет шестнадцатеричный код символа из таблицы ASCII.
Например, литерал '\x78' представляет символ "x":
Console.WriteLine('\x78');    // x
Console.WriteLine('\x5A');    // Z
И последний способ определения символьных литералов представляет применение кодов из таблицы символов Unicode. Для этого в одинарных кавычках указываются символы '\u', после которых идет шестнадцатеричный код Unicode. Например, код '\u0411' представляет кириллический символ 'Б':
Console.WriteLine('\u0420');    // Р
Console.WriteLine('\u0421');    // С
2.1.4. Строковые литералы
Строковые литералы представляют строки. Строки заключаются в двойные кавычки:
Console.WriteLine("hello");
Console.WriteLine("фыва");
Console.WriteLine("hello word");
Если внутри строки необходимо вывести двойную кавычку, то такая внутренняя кавычка предваряется обратным слешем:
Console.WriteLine("Компания \"Рога и копыта\"");
Также в строках можно использовать управляющие последовательности. Например, последовательность '\n' осуществляет перевод на новую строку:
Console.WriteLine("Привет \nмир");
При выводе на консоль слово "мир" будет перенесено на новую строку: null представляет ссылку, которая не указывает ни на какой объект. То есть по сути отсутствие значения.

2.1.5 Типы данных
Как и во многих языках программирования, в C# есть своя система типов данных, которая используется для создания переменных. Тип данных определяет внутреннее представление данных, множество значений, которые может принимать объект, а также допустимые действия, которые можно применять над объектом.
В языке C# есть следующие примитивные типы данных:
bool: хранит логическое значение.
byte: хранит целое число от 0 до 255 и занимает 1 байт.
sbyte: хранит целое число от -128 до 127 и занимает 1 байт
short: хранит целое число от -32768 до 32767 и занимает 2 байта.
ushort: хранит целое число от 0 до 65535 и занимает 2 байта.
int: хранит целое число от -2147483648 до 2147483647 и занимает 4 байта.
uint: хранит целое число от 0 до 4294967295 и занимает 4 байта.
long: хранит целое число от –9 223 372 036 854 775 808 до 9 223 372 036 854 775 807 и занимает 8 байт.
ulong: хранит целое число от 0 до 18 446 744 073 709 551 615 и занимает 8 байт.
float: хранит число с плавающей точкой от -3.4*1038 до 3.4*1038 и занимает 4 байта
double: хранит число с плавающей точкой от ±5.0*10-324 до ±1.7*10308 и занимает 8 байта.
decimal: хранит десятичное дробное число. Если употребляется без десятичной запятой, имеет значение от 0 до +/–79 228 162 514 264 337 593 543 950 335; если с запятой, то от 0 до +/–7,9228162514264337593543950335 с 28 разрядами после запятой и занимает 16 байт.
char: хранит одиночный символ в кодировке Unicode и занимает 2 байта. string: хранит набор символов Unicode.
object: может хранить значение любого типа данных и занимает 4 байта на 32-разрядной платформе и 8 байт на 64-разрядной платформе.
Например, определим несколько переменных разных типов и выведем их значения на консоль:
using System;
 namespace HelloApp
{
    class Program
    {
        static void Main(string[] args)
        {
            string name = "Tom";
            int age = 33;
            bool isEmployed = false;
            double weight = 78.65;
            Console.WriteLine($"Имя: {name}");
            Console.WriteLine($"Возраст: {age}");
            Console.WriteLine($"Вес: {weight}");
            Console.WriteLine($"Работает: {isEmployed}");
        }
    }
}

Для вывода данных на консоль здесь применяется интерполяция: перед строкой ставится знак $ и после этого мы можем вводить в строку в фигурных скобках значения переменных.
Использование суффиксов
При присвоении значений надо иметь в виду следующую тонкость: все вещественные литералы рассматриваются как значения типа double. И чтобы указать, что дробное число представляет тип float или тип decimal, необходимо к литералу добавлять суффикс: F/f - для float и M/m - для decimal.
float a = 3.14F;
float b = 30.6f; 
decimal c = 1005.8M;
decimal d = 334.8m;
Подобным образом все целочисленные литералы рассматриваются как значения типа int. Чтобы явным образом указать, что целочисленный литерал представляет значение типа uint, надо использовать суффикс U/u, для типа long - суффикс L/l, а для типа ulong - суффикс UL/ul:
uint a = 10U;
long b = 20L;
ulong c = 30UL;
2.2. Операции
2.2.1. Арифметические операции
Операции представляют определенные действия над операндами - участниками операции. В качестве операнда может выступать переменной или какое-либо значение (например, число). Операции бывают унарными (выполняются над одним операндом), бинарными - над двумя операндами и тернарными - выполняются над тремя операндами. Рассмотрим все виды операций.
Бинарные арифметические операции:
+ (операция сложения двух чисел):
int x = 10;
int z = x + 12; // 22
- (операция вычитания двух чисел):
int x = 10;
int z = x - 6; // 4
* (операция умножения двух чисел):
int x = 10;
int z = x * 5; // 50
/ (операция деления двух чисел):
int x = 10;
int z = x / 5; // 2 
double a = 10;
double b = 3;
double c = a / b; // 3.33333333
При делении стоит учитывать, что если оба операнда представляют целые числа, то результат также будет округляться до целого числа:
double z = 10 /  4; //результат равен 2
Несмотря на то, что результат операции в итоге помещается в переменную типа double, которая позволяет сохранить дробную часть, но в самой операции участвуют два литерала, которые по умолчанию рассматриваются как объекты int, то есть целые числа, и результат то же будет целочисленный.
Для выхода из этой ситуации необходимо определять литералы или переменные, участвующие в операции, именно как типы double или float:
double z = 10.0 /  4.0; //результат равен 2.5
% (операция получение остатка от целочисленного деления двух чисел):
double x = 10.0;
double z = x % 4.0; //результат равен 2
++ (операция инкремента)
Инкремент бывает префиксным: ++x - сначала значение переменной x увеличивается на 1, а потом ее значение возвращается в качестве результата операции.
И также существует постфиксный инкремент: x++ - сначала значение переменной x возвращается в качестве результата операции, а затем к нему прибавляется 1.
int x1 = 5;
int z1 = ++x1; // z1=6; x1=6
Console.WriteLine($"{x1} - {z1}"); 
int x2 = 5;
int z2 = x2++; // z2=5; x2=6
Console.WriteLine($"{x2} - {z2}");
-- (операция декремента или уменьшения значения на единицу). Также существует префиксная форма декремента (--x) и постфиксная (x--).
int x1 = 5;
int z1 = --x1; // z1=4; x1=4
Console.WriteLine($"{x1} - {z1}"); 
int x2 = 5;
int z2 = x2--; // z2=5; x2=4
Console.WriteLine($"{x2} - {z2}");
При выполнении сразу нескольких арифметических операций следует учитывать порядок их выполнения. Приоритет операций от наивысшего к низшему:
Инкремент, декремент
Умножение, деление, получение остатка
Сложение, вычитание
Для изменения порядка следования операций применяются скобки.
Рассмотрим набор операций:
nt a = 3;
int b = 5;
int c = 40;
int d = c---b*a;    // a=3  b=5  c=39  d=25
Console.WriteLine($"a={a}  b={b}  c={c}  d={d}");
Здесь мы имеем дело с тремя операциями: декремент, вычитание и умножение. Сначала выполняется декремент переменной c, затем умножение b*a, и в конце вычитание. То есть фактически набор операций выглядел так:
int d = (c--)-(b*a);
Но с помощью скобок мы могли бы изменить порядок операций, например, следующим образом:
int a = 3;
int b = 5;
int c = 40;
int d = (c-(--b))*a;    // a=3  b=4  c=40  d=108
Console.WriteLine($"a={a}  b={b}  c={c}  d={d}");
2.2.2. Поразрядные операции
Особый класс операций представляют поразрядные операции. Они выполняются над отдельными разрядами числа. В этом плане числа рассматриваются в двоичном представлении, например, 2 в двоичном представлении 10 и имеет два разряда, число 7 - 111 и имеет три разряда.
&(логическое умножение)
Умножение производится поразрядно, и если у обоих операндов значения разрядов равно 1, то операция возвращает 1, иначе возвращается число 0. Например:
int x1 = 2; //010
int y1 = 5;//101
Console.WriteLine(x1&y1); // выведет 0             
int x2 = 4; //100
int y2 = 5; //101
Console.WriteLine(x2 & y2); // выведет 4
В первом случае у нас два числа 2 и 5. 2 в двоичном виде представляет число 010, а 5 - 101. Поразрядно умножим числа (0*1, 1*0, 0*1) и в итоге получим 000.
Во втором случае у нас вместо двойки число 4, у которого в первом разряде 1, так же как и у числа 5, поэтому в итоге получим (1*1, 0*0, 0 *1) = 100, то есть число 4 в десятичном формате.
| (логическое сложение)
Похоже на логическое умножение, операция также производится по двоичным разрядам, но теперь возвращается единица, если хотя бы у одного числа в данном разряде имеется единица. Например:
int x1 = 2; //010
int y1 = 5;//101
Console.WriteLine(x1|y1); // выведет 7 - 111
int x2 = 4; //100
int y2 = 5;//101
Console.WriteLine(x2 | y2); // выведет 5 – 101
^ (логическое исключающее ИЛИ)
Также эту операцию называют XOR, нередко ее применяют для простого шифрования:
int x = 45; // Значение, которое надо зашифровать - в двоичной форме 101101
int key = 102; //Пусть это будет ключ - в двоичной форме 1100110
int encrypt = x ^ key; //Результатом будет число 1001011 или 75
Console.WriteLine("Зашифрованное число: " +encrypt); 
int decrypt = encrypt ^ key; // Результатом будет исходное число 45
Console.WriteLine("Расшифрованное число: " + decrypt);
Здесь опять же производятся поразрядные операции. Если у нас значения текущего разряда у обоих чисел разные, то возвращается 1, иначе возвращается 0. Таким образом, мы получаем из 9^5 в качестве результата число 12. И чтобы расшифровать число, мы применяем ту же операцию к результату.
~ (логическое отрицание или инверсия)
Еще одна поразрядная операция, которая инвертирует все разряды: если значение разряда равно 1, то оно становится равным нулю, и наоборот.
int x = 9;
Console.WriteLine(~x);
Операции сдвига
Операции сдвига также производятся над разрядами чисел. Сдвиг может происходить вправо и влево.
x<x>>y - сдвигает число x вправо на y разрядов. Например, 16>>1 сдвигает число 16 (которое в двоичном представлении 10000) на один разряд вправо, то есть в итоге получается 1000 или число 8 в десятичном представлении.
Таким образом, если исходное число, которое надо сдвинуть в ту или другую строну, делится на два, то фактически получается умножение или деление на два. Поэтому подобную операцию можно использовать вместо непосредственного умножения или деления на два.
2.2.3. Операции присваивания
Операции присвоения устанавливают значение. В операциях присвоения участвуют два операнда, причем левый операнд может представлять только модифицируемое именованное выражение, например, переменную
В C# имеется базовая операция присваивания =, которая присвоивает значение правого операнда левому операнду: int number = 23;
Здесь переменной number присваивается число 23. Переменная number представляет левый операнд, которому присваивается значение правого операнда, то есть числа 23.
Также можно выполнять множественно присвоение сразу нескольких переменным одновременно:
int a, b, c;
a = b = c = 34;
Операции присвоения имеют низкий приоритет. И вначале будет вычисляться значение правого операнда и только потом будет идти присвоение этого значения левому операнду. Например:
int a, b, c;
a = b = c = 34 * 2 / 4; // 17
Сначала будет вычисляться выражение 34 * 2 / 4, затем полученное значение будет присвоено переменным.
Кроме базовой операции присвоения в C# есть еще ряд операций:
+=: (присваивание после сложения). Присваивает левому операнду сумму левого и правого операндов: выражение A += B равнозначно выражению A = A + B
-=: (присваивание после вычитания). Присваивает левому операнду разность левого и правого операндов: A -= B эквивалентно A = A - B
*=: (присваивание после умножения). Присваивает левому операнду произведение левого и правого операндов: A *= B эквивалентно A = A * B
/=: (присваивание после деления). Присваивает левому операнду частное левого и правого операндов: A /= B эквивалентно A = A / B
%=: (присваивание после деления по модулю). Присваивает левому операнду остаток от целочисленного деления левого операнда на правый: A %= B эквивалентно A = A % B
&=: (присваивание после поразрядной конъюнкции). Присваивает левому операнду результат поразрядной конъюнкции его битового представления с битовым представлением правого операнда: A &= B эквивалентно A = A & B
|=: (присваивание после поразрядной дизъюнкции). Присваивает левому операнду результат поразрядной дизъюнкции его битового представления с битовым представлением правого операнда: A |= B эквивалентно A = A | B
^=: (присваивание после операции исключающего ИЛИ). Присваивает левому операнду результат операции исключающего ИЛИ его битового представления с битовым представлением правого операнда: A ^= B эквивалентно A = A ^ B
<<=: (присваивание после сдвига разрядов влево). Присваивает левому операнду результат сдвига его битового представления влево на определенное количество разрядов, равное значению правого операнда: A <<= B эквивалентно A = A << B
>>=: (присваивание после сдвига разрядов вправо). Присваивает левому операнду результат сдвига его битового представления вправо на определенное количество разрядов, равное значению правого операнда: A >>= B эквивалентно A = A >> B
Применение операций присвоения:
int a = 10;
a += 10;        // 20
a -= 4;         // 16
a *= 2;         // 32
a /= 8;         // 4
a <<= 4;      // 64
a >>= 2;      // 16
2.2.4. Преобразование базовых типов данных
Применим операцию сложения к данным разных типов:
byte a = 4;
int b = a + 70;
Результатом операции является число 74, как и ожидается.
Но теперь попробуем применить сложение к двум объектам типа byte:
byte a = 4;
byte b = a + 70;  // ошибка
Здесь поменялся только тип переменной, которая получает результат сложения - с int на byte. Однако при попытке скомпилировать программу мы получим ошибку на этапе компиляции. И если мы работаем в Visual Studio, среда подчеркнет вторую строку красной волнистой линией, указывая, что в ней ошибка.
При операциях мы должны учитывать диапазон значений, которые может хранить тот или иной тип. Но в данном случае число 74, которое мы ожидаем получить, вполне укладывается в диапазон значений типа byte, тем не менее мы получаем ошибку.
Дело в том, что операция сложения (да и вычитания) возвращает значение типа int, если в операции участвуют целочисленные типы данных с разрядностью меньше или равно int (то есть типы byte, short, int). Поэтому результатом операции a + 70 будет объект, который имеет длину в памяти 4 байта. Затем этот объект мы пытаемся присвоить переменной b, которая имеет тип byte и в памяти занимает 1 байт.
И чтобы выйти из этой ситуации, необходимо применить операцию преобразования типов:
byte a = 4;
byte b = (byte)(a + 70);
Операция преобразования типов предполагает указание в скобках того типа, к которому надо преобразовать значение.
Преобразования могут сужающие (narrowing) и расширяющие (widening). Расширяющие преобразования расширяют размер объекта в памяти.
byte a = 4;
int b = a + 70;
В операции сложения в данном случае участвуют два операнда типа int. Но один из операндов - переменная a представляет тип byte. Поэтому компилятор будет расширять переданное значение типа byte до типа int, то есть в памяти это значение получит 4 байта, а не 1.
Сужающие преобразования, наоборот, сужают значение до типа меньшей разядности.
byte a = 4;
byte b = (byte)(a + 70);
Полученное в результате операции значение типа int сужается до объекта типа byte и в памяти в место 4 байт получает только 1. Несмотря на то, что сумма (число 10) укладывается в диапазон типа byte, Visual Studio все равно отобразит ошибку.
Явные и неявные преобразования
Если в случае с расширяющими преобразованиями компилятор за нас выполнял все преобразования данных, то есть преобразования были неявными (implicit conversion), то при явных преобразованиях (explicit conversion) мы сами должны применить операцию преобразования (операция ()). Суть операции преобразования типов состоит в том, что перед значением указывается в скобках тип, к которому надо привести данное значение:
int a = 4;
int b = 6;
byte c = (byte)(a+b);

2.2.5. Условные выражения
Отдельный набор операций представляет условные выражения. Такие операции возвращают логическое значение, то есть значение типа bool: true, если выражение истинно, и false, если выражение ложно. К подобным операциям относятся операции сравнения и логические операции.
Операции сравнения
В операциях сравнения сравниваются два операнда и возвращается значение типа bool - true, если выражение верно, и false, если выражение неверно.
== (Cравнивает два операнда на равенство). Если они равны, то операция возвращает true, если не равны, то возвращается false:
int a = 10;
int b = 4;
bool c = a == b; // false
!= (сравнивает два операнда и возвращает true, если операнды не равны, и false, если они равны).
int a = 10;
int b = 4;
bool c = a != b;    // true
bool d = a!=10;     // false
< (операция "меньше чем"). Возвращает true, если первый операнд меньше второго, и false, если первый операнд больше второго:
int a = 10;
int b = 4;
bool c = a < b; // false
> (операция "больше чем"). Сравнивает два операнда и возвращает true, если первый операнд больше второго, иначе возвращает false:
int a = 10;
int b = 4;
bool c = a > b;     // true
bool d = a > 25;    // false
<= (операция "меньше или равно"). Сравнивает два операнда и возвращает true, если первый операнд меньше или равен второму. Иначе возвращает false.
int a = 10;
int b = 4;
bool c = a <= b;     // false
bool d = a <= 25;    // true

>= (операция "больше или равно"). Сравнивает два операнда и возвращает true, если первый операнд больше или равен второму, иначе возвращается false:
int a = 10;
int b = 4;
bool c = a >= b;     // true
bool d = a >= 25;    // false

2.2.6. Логические операции
| (операция логического сложения или логическое ИЛИ). Возвращает true, если хотя бы один из операндов возвращает true.
bool x1 = (5 > 6) | (4 < 6);
// 5 > 6 - false, 4 < 6 - true, поэтому возвращается true
bool x2 = (5 > 6) | (4 > 6);
// 5 > 6 - false, 4 > 6 - false, поэтому возвращается false
& (операция логического умножения или логическое И). Возвращает true, если оба операнда одновременно равны true.
bool x1 = (5 > 6) & (4 < 6);
// 5 > 6 - false, 4 < 6 - true, поэтому возвращается false
bool x2 = (5 < 6) & (4 < 6);
// 5 < 6 - true, 4 < 6 - true, поэтому возвращается true
|| (операция логического сложения). Возвращает true, если хотя бы один из операндов возвращает true.
bool x1 = (5 > 6) || (4 < 6);
// 5 > 6 - false, 4 < 6 - true, поэтому возвращается true
bool x2 = (5 > 6) || (4 > 6);
// 5 > 6 - false, 4 > 6 - false, поэтому возвращается false
&& (операция логического умножения). Возвращает true, если оба операнда одновременно равны true.
bool x1 = (5 > 6) && (4 < 6);
// 5 > 6 - false, 4 < 6 - true, поэтому возвращается false
bool x2 = (5 < 6) && (4 < 6);
// 5 > 6 - true, 4 > 6 - true, поэтому возвращается true
! (операция логического отрицания.) Производится над одним операндом и возвращает true, если операнд равен false. Если операнд равен true, то операция возвращает false:
bool a = true;
bool b = !a;    // false
^ (операция исключающего ИЛИ). Возвращает true, если либо первый, либо второй операнд (но не одновременно) равны true, иначе возвращает false:
bool x5 = (5 > 6) ^ (4 < 6);
// 5 > 6 - false, 4 < 6 - true, поэтому возвращается true
bool x6 = (50 > 6) ^ (4 / 2 < 3);
// 50 > 6 - true, 4/2 < 3 - true, поэтому возвращается false
Здесь две пары операций | и || (а также & и &&) выполняют похожие действия, однако же они не равнозначны.
В выражении z=x|y; будут вычисляться оба значения - x и y.
В выражении же z=x||y; сначала будет вычисляться значение x, и если оно равно true, то вычисление значения y уже смысла не имеет, так как у нас в любом случае уже z будет равно true. Значение y будет вычисляться только в том случае, если x равно false
То же самое касается пары операций &/&&. В выражении z=x&y; будут вычисляться оба значения - x и y.
В выражении же z=x&&y; сначала будет вычисляться значение x, и если оно равно false, то вычисление значения y уже смысла не имеет, так как у нас в любом случае уже z будет равно false. Значение y будет вычисляться только в том случае, если x равно true
Поэтому операции || и && более удобны в вычислениях, так как позволяют сократить время на вычисление значения выражения, и тем самым повышают производительность. А операции | и & больше подходят для выполнения поразрядных операций над числами.

2.3. Условные конструкции
Условные конструкции - один из базовых компонентов многих языков программирования, которые направляют работу программы по одному из путей в зависимости от определенных условий.
2.3.1. Конструкция if/else
Конструкция if/else проверяет истинность некоторого условия и в зависимости от результатов проверки выполняет определенный код:
int num1 = 8;
int num2 = 6;
if(num1 > num2)
{    Console.WriteLine($"Число {num1} больше числа {num2}"); }
После ключевого слова if ставится условие. И если это условие выполняется, то срабатывает код, который помещен далее в блоке if после фигурных скобок. В качестве условий выступают ранее рассмотренные операции сравнения.
В данном случае у нас первое число больше второго, поэтому выражение num1 > num2 истинно и возвращает true, следовательно, управление переходит к строке 
Console.WriteLine("Число {num1} больше числа {num2}");
Но что, если мы захотим, чтобы при несоблюдении условия также выполнялись какие-либо действия? В этом случае мы можем добавить блок else:
int num1 = 8;
int num2 = 6;
if(num1 > num2)
{    Console.WriteLine($"Число {num1} больше числа {num2}");}
else
{    Console.WriteLine($"Число {num1} меньше числа {num2}");}
Но при сравнении чисел мы можем насчитать три состояния: первое число больше второго, первое число меньше второго и числа равны. Используя конструкцию else if, мы можем обрабатывать дополнительные условия:
int num1 = 8;
int num2 = 6;
if(num1 > num2)
{    Console.WriteLine($"Число {num1} больше числа {num2}"); }
else if (num1 < num2)
{    Console.WriteLine($"Число {num1} меньше числа {num2}");}
else
{    Console.WriteLine("Число num1 равно числу num2");}
Также мы можем соединить сразу несколько условий, используя логические операторы:
int num1 = 8;
int num2 = 6;
if(num1 > num2 && num1==8)
{    Console.WriteLine($"Число {num1} больше числа {num2}");}
В данном случае блок if будет выполняться, если num1 > num2 равно true и num1==8 равно true.
2.3.2. Конструкция switch
Конструкция switch/case аналогична конструкции if/else, так как позволяет обработать сразу несколько условий:
Console.WriteLine("Нажмите Y или N");
string selection = Console.ReadLine();
switch (selection)
{
    case "Y":
        Console.WriteLine("Вы нажали букву Y");
        break;
    case "N":
        Console.WriteLine("Вы нажали букву N");
        break;
    default:
        Console.WriteLine("Вы нажали неизвестную букву");
        break;
}
После ключевого слова switch в скобках идет сравниваемое выражение. Значение этого выражения последовательно сравнивается со значениями, помещенными после оператора сase. И если совпадение будет найдено, то будет выполняться определенный блок сase.
В конце каждого блока сase должен ставиться один из операторов перехода: break, goto case, return или throw. Как правило, используется оператор break. При его применении другие блоки case выполняться не будут.
Однако если мы хотим, чтобы, наоборот, после выполнения текущего блока case выполнялся другой блок case, то мы можем использовать вместо break оператор goto case:
int number = 1;
switch (number)
{
    case 1:
        Console.WriteLine("case 1");
        goto case 5; // переход к case 5
    case 3:
        Console.WriteLine("case 3");
        break;
    case 5:
        Console.WriteLine("case 5");
        break;
    default:
        Console.WriteLine("default");
        break;
}
Если мы хотим также обработать ситуацию, когда совпадения не будет найдено, то можно добавить блок default, как в примере выше.
Применение оператора return позволит выйти не только из блока case, но и из вызывающего метода. То есть, если в методе Main после конструкции switch..case, в которой используется оператор return, идут какие-либо операторы и выражения, то они выполняться не будут, а метод Main завершит работу.
Оператор throw применяется для выброса ошибок
2.3.3. Тернарная операция
Тернарную операция имеет следующий синтаксис: [первый операнд - условие] ? [второй операнд] : [третий операнд]. Здесь сразу три операнда. В зависимости от условия тернарная операция возвращает второй или третий операнд: если условие равно true, то возвращается второй операнд; если условие равно false, то третий. Например:
int x=3;
int y=2;
Console.WriteLine("Нажмите + или -");
string selection = Console.ReadLine();
 
int z = selection=="+"? (x+y) : (x-y);
Console.WriteLine(z);
Здесь результатом тернарной операции является переменная z. Если мы выше вводим "+", то z будет равно второму операнду - (x+y). Иначе z будет равно третьему операнду.

2.4. Циклы
Циклы являются управляющими конструкциями, позволяя в зависимости от определенных условий выполнять некоторое действие множество раз. В C# имеются следующие виды циклов:
for
foreach
while
do...while
2.4.1. Цикл for
Цикл for имеет следующее формальное определение:
for ([инициализация счетчика]; [условие]; [изменение счетчика])
{
    // действия
}
Рассмотрим стандартный цикл for:
for (int i = 0; i < 9; i++)
{    Console.WriteLine($"Квадрат числа {i} равен {i*i}"); }
Первая часть объявления цикла - int i = 0 - создает и инициализирует счетчик i. Счетчик необязательно должен представлять тип int. Это может быть и другой числовой тип, например, float. И перед выполнением цикла его значение будет равно 0. В данном случае это то же самое, что и объявление переменной.
Вторая часть - условие, при котором будет выполняться цикл. Пока условное выражение возвращает true, будет выполняться цикл. В данном случае цикл будет выполняться, пока счетчик i не достигнет 9.
И третья часть - приращение счетчика на единицу. Опять же нам необязательно увеличивать на единицу. Можно уменьшать: i--.
В итоге блок цикла сработает 9 раз, пока значение i не станет равным 9. И каждый раз это значение будет увеличиваться на 1.
Нам необязательно указывать все условия при объявлении цикла. Например, мы можем написать так:
int i = 0;
for (; ;)
{    Console.WriteLine($"Квадрат числа {++i} равен {i * i}"); }
Формально определение цикла осталось тем же, только теперь блоки в определении у нас пустые: for (; i <;). У нас нет инициализированной переменной-счетчика, нет условия, поэтому цикл будет работать вечно - бесконечный цикл.
Мы также можем опустить ряд блоков:
int i = 0;
for (; i<9;)
{    Console.WriteLine($"Квадрат числа {++i} равен {i * i}"); }
Этот пример по сути эквивалентен первому примеру: у нас также есть счетчик, только создан он вне цикла. У нас есть условие выполнения цикла. И есть приращение счетчика уже в самом блоке for.
2.4.2. Цикл do
В цикле do сначала выполняется код цикла, а потом происходит проверка условия в инструкции while. И пока это условие истинно, цикл повторяется. Например:
int i = 6;
do
{
    Console.WriteLine(i);
    i--;
}
while (i > 0);
Здесь код цикла сработает 6 раз, пока i не станет равным нулю. Но важно отметить, что цикл do гарантирует хотя бы единократное выполнение действий, даже если условие в инструкции while не будет истинно. То есть мы можем написать:
int i = -1;
do
{
    Console.WriteLine(i);
    i--;
}
while (i > 0);
Хотя у нас переменная i меньше 0, цикл все равно один раз выполнится.
2.4.3. Цикл while
В отличие от цикла do цикл while сразу проверяет истинность некоторого условия, и если условие истинно, то код цикла выполняется:
int i = 6;
while (i > 0)
{
    Console.WriteLine(i);
    i--;
}
2.4.4. Операторы continue и break
Иногда возникает ситуация, когда требуется выйти из цикла, не дожидаясь его завершения. В этом случае мы можем воспользоваться оператором break.
Например:
for (int i = 0; i < 9; i++)
{
    if (i == 5)
        break;
    Console.WriteLine(i);
}
Хотя в условии цикла сказано, что цикл будет выполняться, пока счетчик i не достигнет значения 9, в реальности цикл сработает 5 раз. Так как при достижении счетчиком i значения 5, сработает оператор break, и цикл завершится.
Теперь поставим себе другую задачу. А что если мы хотим, чтобы при проверке цикл не завершался, а просто пропускал текущую итерацию. Для этого мы можем воспользоваться оператором continue:
for (int i = 0; i < 9; i++)
{
    if (i == 5)
        continue;
    Console.WriteLine(i);
}
В этом случае цикл, когда дойдет до числа 5, которое не удовлетворяет условию проверки, просто пропустит это число и перейдет к следующей итерации.
2.5. Массивы
2.5.1. Одномерные массивы
Массив представляет набор однотипных переменных. Объявление массива похоже на объявление переменной за тем исключением, что после указания типа ставятся квадратные скобки:
тип_переменной[] название_массива;
Например, определим массив целых чисел:
int[] numbers;
После определения переменной массива мы можем присвоить ей определенное значение:
int[] nums = new int[4];
Здесь вначале мы объявили массив nums, который будет хранить данные типа int. Далее используя операцию new, мы выделили память для 4 элементов массива: new int[4]. Число 4 еще называется длиной массива. При таком определении все элементы получают значение по умолчанию, которое предусмотренно для их типа.
Для типа int значение по умолчанию - 0.
Также мы сразу можем указать значения для этих элементов:
int[] nums2 = new int[4] { 1, 2, 3, 5 };
 int[] nums3 = new int[] { 1, 2, 3, 5 };
 int[] nums4 = new[] { 1, 2, 3, 5 };
 int[] nums5 = { 1, 2, 3, 5 };
Все перечисленные выше способы будут равноценны.
Для обращения к элементам массива используются индексы. Индекс представляет номер элемента в массиве, при этом нумерация начинается с нуля, поэтому индекс первого элемента будет равен 0. А чтобы обратиться к четвертому элементу в массиве, нам надо использовать индекс 3, к примеру: nums[3]. Используем индексы для получения и установки значений элементов массива:
int[] nums = new int[4];
nums[0] = 1;
nums[1] = 2;
nums[2] = 3;
nums[3] = 5;
Console.WriteLine(nums[3]);  // 5
И так как у нас массив определен только для 4 элементов, то мы не можем обратиться, например, к шестому элементу: nums[5] = 5;. Если мы так попытаемся сделать, то мы получим исключение IndexOutOfRangeException.

2.5.2. Перебор массивов. Цикл foreach
Цикл foreach предназначен для перебора элементов в контейнерах, в том числе в массивах. Формальное объявление цикла foreach:
foreach (тип_данных название_переменной in контейнер)

Например:
int[] numbers = new int[] { 1, 2, 3, 4, 5 };
foreach (int i in numbers)
{
    Console.WriteLine(i);
}
Здесь в качестве контейнера выступает массив данных типа int. Поэтому мы объявляем переменную с типом int
Подобные действия мы можем сделать и с помощью цикл for:
int[] numbers = new int[] { 1, 2, 3, 4, 5 };
for (int i = 0; i < numbers.Length; i++)
{
    Console.WriteLine(numbers[i]);
}
В то же время цикл for более гибкий по сравнению с foreach. Если foreach последовательно извлекает элементы контейнера и только для чтения, то в цикле for мы можем перескакивать на несколько элементов вперед в зависимости от приращения счетчика, а также можем изменять элементы:
int[] numbers = new int[] { 1, 2, 3, 4, 5 };
for (int i = 0; i < numbers.Length; i++)
{
    numbers[i] = numbers[i] * 2;
    Console.WriteLine(numbers[i]);
}
2.5.3. Многомерные массивы
Массивы бывают многомерными. В предыдущих примерах мы создавали одномерные массивы, а теперь создадим двухмерный:
int[] nums1 = new int[] { 0, 1, 2, 3, 4, 5 };
 int[,] nums2 = { { 0, 1, 2 }, { 3, 4, 5 } };
Визуально оба массива можно представить следующим образом:
Одномерный массив nums1
0
1
2
3
4
5

Двухмерный массив nums2
0
1
2

3
4
5

Поскольку массив nums2 двухмерный, он представляет собой простую таблицу. Объявление трехмерного массива могло бы выглядеть так:
int[,,] nums3 = new int[2, 3, 4];
Все возможные способы определения двухмерных массивов:
int[,] nums1;
int[,] nums2 = new int[2, 3];
int[,] nums3 = new int[2, 3] { { 0, 1, 2 }, { 3, 4, 5 } };
int[,] nums4 = new int[,] { { 0, 1, 2 }, { 3, 4, 5 } };
int[,] nums5 = new [,]{ { 0, 1, 2 }, { 3, 4, 5 } };
int[,] nums6 = { { 0, 1, 2 }, { 3, 4, 5 } };
Определенную сложность может представлять перебор многомерного массива. Прежде всего надо учитывать, что длина такого массива - это совокупное количество элементов.
int[,] mas = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }, { 10, 11, 12 } };
foreach (int i in mas)
 Console.Write($"{i} ");
Console.WriteLine();
В данном случае длина массива mas равна 12. И цикл foreach выводить все элементы массива в строку:
Но что если мы хотим отдельно пробежаться по каждой строке в таблице? В этом случае надо получить количество элементов в размерности. В частности, у каждого массива есть метод GetUpperBound(dimension), который возвращает индекс последнего элемента в определенной размерности. И если мы говорим непосредственно о двухмерном массиве, то первая размерность (с индексом 0) по сути это и есть таблица. И с помощью выражения mas.GetUpperBound(0) + 1 можно получить количество строк таблицы, представленной двухмерным массивом. А через mas.Length / rows можно получить количество элементов в каждой строке:
int[,] mas = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }, { 10, 11, 12 } };
 
int rows = mas.GetUpperBound(0) + 1;
int columns = mas.Length / rows;
for (int i = 0; i < rows; i++)
{
    for (int j = 0; j < columns; j++)
    {
        Console.Write($"{mas[i, j]} \t");
    }
    Console.WriteLine();
}
2.6. Структуры
Кроме базовых элементарных типов данных и перечислений в C# имеется и составной тип данных, который называется структурой. Структуры могут содержать в себе обычные переменные и методы.
Для примера [5] создадим структуру Book, в которой будут храниться переменные для названия, автора и года издания книги. Кроме того, структура будет содержать метод для вывода информации о книге на консоль:
struct Book
{
    public string name;
    public string author;
    public int year;
     public void Info()
    {
        Console.WriteLine($"Книга '{name}' (автор {author}) была издана в {year} году");
    }
}
Чтобы можно было использовать переменные и методы структуры из любого места программы мы ставим перед переменными и методом модификатор доступа public
Используем структуру на практике:
using System;
namespace Structures
{
    class Program
    {
        static void Main(string[] args)
        {
            Book book;
            book.name = "Война и мир";
            book.author = "Л. Н. Толстой";
            book.year = 1869;
            //Выведем информацию о книге book на экран
            book.Info();
 
            Console.ReadLine();
        }
    }
     struct Book
    {
        public string name;
        public string author;
        public int year;
        public void Info()
        {
            Console.WriteLine($"Книга '{name}' (автор {author}) была издана в {year} году");
        }
    }
}
Структуру можно задать как внутри пространства имен (как в данном случае), так и внутри класса, но не внутри метода.
По сути структура Book представляет новый тип данных. Мы также можем использовать массив структур:
Book[] books=new Book[3];
books[0].name = "Война и мир";
books[0].author = "Л. Н. Толстой";
books[0].year = 1869;
books[1].name = "Преступление и наказание";
books[1].author = "Ф. М. Достоевский";
books[1].year = 1866;
books[2].name = "Отцы и дети";
books[2].author = "И. С. Тургенев";
books[2].year = 1862;
foreach (Book b in books)
{
    b.Info();
}
2.7. Работа со строками
2.7.1. Строки и класс System.String
В языке C# строковые значения представляет тип string, а вся функциональность работы с данным типом сосредоточена в классе System.String. Собственно string является псевдонимом для класса System.String. Объекты этого класса представляют текст как последовательность символов Unicode. Максимальный размер объекта String может составлять в памяти 2 ГБ, или около 1 миллиарда символов.
Создавать строки можно, как используя переменную типа string и присваивая ей значение, так и применяя один из конструкторов класса String:
string s1 = "hello";
string s2 = null;
Используя свойство Length, как и в обычном массиве, можно получить длину строки.
Основные методы строк
Основная функциональность класса String раскрывается через его методы, среди которых можно выделить следующие:
Compare: сравнивает две строки с учетом текущей культуры (локали) пользователя
CompareOrdinal: сравнивает две строки без учета локали
Contains: определяет, содержится ли подстрока в строке
Concat: соединяет строки
CopyTo: копирует часть строки или всю строку в другую строку
EndsWith: определяет, совпадает ли конец строки с подстрокой
Format: форматирует строку
IndexOf: находит индекс первого вхождения символа или подстроки в строке
Insert: вставляет в строку подстроку
Join: соединяет элементы массива строк
LastIndexOf: находит индекс последнего вхождения символа или подстроки в строке
Replace: замещает в строке символ или подстроку другим символом или подстрокой
Split: разделяет одну строку на массив строк
Substring: извлекает из строки подстроку, начиная с указанной позиции
ToLower: переводит все символы строки в нижний регистр
ToUpper: переводит все символы строки в верхний регистр
Trim: удаляет начальные и конечные пробелы из строки
2.7.2. Операции со строками
Конкатенация строк или объединение может производиться как с помощью операции +, так и с помощью метода Concat:
string s1 = "hello";
string s2 = "world";
string s3 = s1 + " " + s2; // результат: строка "hello world"
string s4 = String.Concat(s3, "!!!"); // результат: строка "hello world!!!"
Console.WriteLine(s4);
Для сравнения строк применяется статический метод Compare [4]:
string s1 = "hello";
string s2 = "world";
int result = String.Compare(s1, s2);
if (result<0)
{    Console.WriteLine("Строка s1 перед строкой s2");}
else if (result > 0)
{    Console.WriteLine("Строка s1 стоит после строки s2");}
else
{    Console.WriteLine("Строки s1 и s2 идентичны"); }
// результатом будет "Строка s1 перед строкой s2"
Поиск в строке
С помощью метода IndexOf мы можем определить индекс первого вхождения отдельного символа или подстроки в строке [4]:
string s1 = "hello world";
char ch = 'o';
int indexOfChar = s1.IndexOf(ch); // равно 4
Console.WriteLine(indexOfChar);
string subString = "wor";
int indexOfSubstring = s1.IndexOf(subString); // равно 6
Console.WriteLine(indexOfSubstring);
Подобным образом действует метод LastIndexOf, только находит индекс последнего вхождения символа или подстроки в строку.
Разделение строк
С помощью функции Split мы можем разделить строку на массив подстрок. В качестве параметра функция Split принимает массив символов или строк, которые и будут служить разделителями. Например, подсчитаем количество слов в сроке, разделив ее по пробельным символам:
string text = "И поэтому все так произошло";
string[] words = text.Split(new char[] { ' ' });
foreach (string s in words)
{     Console.WriteLine(s); }
Для обрезки начальных или концевых символов используется функция Trim:
string text = " hello world ";
 text = text.Trim(); // результат "hello world"
text = text.Trim(new char[] { 'd', 'h' }); // результат "ello worl"
Для вставки одной строки в другую применяется функция Insert:
string text = "Хороший день";
string subString = "замечательный ";
text = text.Insert(8, subString);
Console.WriteLine(text);
Удалить часть строки помогает метод Remove [4]:
Чтобы заменить один символ или подстроку на другую, применяется метод Replace:

2.7.3. Форматирование
При выводе строк в консоли с помощью метода Console.WriteLine мы можем применять форматирование вместо конкатенации:
class Program
{
    static void Main(string[] args)
    {
        Person person = new Person { Name = "Tom", Age = 23 };
 
        Console.WriteLine("Имя: {0}  Возраст: {1}", person.Name, person.Age);
        Console.Read();
    }
}
class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}
В строке "Имя: {0} Возраст: {1}" на место {0} и {1} затем будут вставляться в порядке следования person.Name и person.Age
То же самое мы можем сделать с помощью метода String.Format:
string output = String.Format("Имя: {0}  Возраст: {1}", person.Name, person.Age);
Console.WriteLine(output);
Метод Format принимает строку с плейсхолдерами типа {0}, {1} и т.д., а также набор аргументов, которые вставляются на место данных плейсхолдеров. В итоге генерируется новая строка.
В методе Format могут использоваться различные спецификаторы и описатели, которые позволяют настроить вывод данных. Рассмотрим основные описатели.
Все используемые форматы:
С / с - задает формат денежной единицы, указывает количество десятичных разрядов после запятой;
D / d - целочисленный формат, указывает минимальное количество цифр;
E / e - экспоненциальное представление числа, указывает количество десятичных разрядов после запятой;
G / g - задает более короткий из двух форматов: F или E;
F / f - формат дробных чисел с фиксированной точкой, указывает количество десятичных разрядов после запятой;
P / p - также задает формат дробных чисел с фиксированной точкой, определяет количество разрядов после запятой;
X / x - шестнадцатеричный формат числа;
C / c - задает формат денежной единицы, указывает количество десятичных разрядов после запятой;
D / d - Целочисленный формат, указывает минимальное количество цифр
E / e - экспоненциальное представление числа, указывает количество десятичных разрядов после запятой;
F / f - формат дробных чисел с фиксированной точкой, указывает количество десятичных разрядов после запятой;
G / g - задает более короткий из двух форматов: F или E;
N / n - также задает формат дробных чисел с фиксированной точкой, определяет количество разрядов после запятой;
P / p - задает отображения знака процентов рядом с число, указывает количество десятичных разрядов после запятой;
X / x - шестнадцатеричный формат числа.
Для форматирования целочисленных значение применяется описатель "d":
Для форматирования дробных чисел используется описатель F, число после которого указывает, сколько знаков будет использоваться после разделителя между целой и дробной частью. Если исходное число - целое, то к нему добавляются разделитель и нули.
Описатель "P" задает отображение процентов. Используемый с ним числовой спецификатор указывает, сколько знаков будет после запятой:
decimal number = 0.15345m;
Console.WriteLine("{0:P1}", number);// 15.3%
Настраиваемые форматы
Используя знак #, можно настроить формат вывода. Например, нам надо вывести некоторое число в формате телефона +х (ххх)ххх-хх-хх: [4]
long number = 19876543210;
string result = String.Format("{0:+# (###) ###-##-##}", number);
Console.WriteLine(result); // +1 (987) 654-32-10
Имя: Том Возраст: 23
2.8. Обработка исключений
При выполнении программы могут возникать ошибки, которые трудно предусмотреть или предвидеть, а иногда и вовсе невозможно. Например, при передачи файла по сети может неожиданно оборваться сетевое подключение. такие ситуации называются исключениями. Язык C# предоставляет разработчикам возможности для обработки таких ситуаций. Для этого в C# предназначена конструкция try...catch...finally.
При возникновении исключения среда CLR ищет блок catch, который может обработать данное исключение. Если такого блока не найдено, то пользователю отображается сообщение о необработанном исключении, а дальнейшее выполнение программы останавливается. И чтобы подобной остановки не произошло, и надо использовать блок try..catch. Например [4]:
static void Main(string[] args)
{
    int[] a = new int[4];
    try
    {
        a[5] = 4; // тут возникнет исключение, так как у нас в массиве только 4 элемента
        Console.WriteLine("Завершение блока try");
    }
    catch (Exception ex)
    {        Console.WriteLine("Ошибка: " + ex.Message);    }
    finally
    {        Console.WriteLine("Блок finally");    }
    Console.ReadLine();
}
При использовании блока try...catch..finally вначале выполняются все инструкции между операторами try и catch. Если между этими операторами вдруг возникает исключение, то обычный порядок выполнения останавливается и переходит к инструкции сatch. В данном случае у нас явно возникнет исключение в блоке try, так как мы пытаемся присвоить значение шестому элементу массива в то время, как в массиве всего 4 элемента. И дойдя до строки a[5] = 4;, выполнение программы остановится и перейдет к блоку catch
Инструкция catch имеет следующий синтаксис: catch (тип_исключения имя_переменной). В нашем случае объявляется переменная ex, которая имеет тип Exception. Но если возникшее исключение не является исключением типа, указанного в инструкции сatch, то оно не обрабатывается, а программа просто зависает или выбрасывает сообщение об ошибке.

2.9. Объектно-ориентированное программирование
2.9.1. Классы и объекты
Описанием объекта является класс, а объект представляет экземпляр этого класса. По умолчанию проект консольного приложения уже по умолчанию содержит один класс Program, с которого и начинается выполнение программы.
По сути класс представляет новый тип, который определяется пользователем. Класс определяется с помощью ключевого слова сlass:
class Person
{ }
Класс можно определять внутри пространства имен, вне пространства имен, внутри другого класса. Как правило, классы помещаются в отдельные файлы. Но в данном случае поместим новый класс в файле, где располагается класс Program. То есть файл Program.cs будет выглядеть следующим образом:
using System;
namespace HelloApp
{
    class Person
    {
    }
    class Program
    {
        static void Main(string[] args)
        {
        }
    }
}
Вся функциональность класса представлена его членами - полями (полями называются переменные класса), свойствами, методами, событиями. Например, определим в классе Person поля и метод [4]:
using System;
{
    class Person
    {
        public string name; // имя
        public int age;     // возраст
 
        public void GetInfo()
        {
            Console.WriteLine($"Имя: {name}  Возраст: {age}");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Person tom;
 
            Console.Read();
        }
    }
}
В данном случае класс Person представляет человека. Поле name хранит имя, а поле age - возраст человека. А метод GetInfo выводит все данные на консоль. Чтобы все данные были доступны вне класса Person переменные и метод определены с модификатором public.
2.9.2. Конструкторы
Кроме обычных методов в классах используются также и специальные методы, которые называются конструкторами.
Конструкторы вызываются при создании нового объекта данного класса. Конструкторы выполняют инициализацию объекта.
Если в классе не определено ни одного конструктора, то для этого класса автоматически создается конструктор без параметров.
Выше класс Person не имеет никаких конструкторов. Поэтому для него автоматически создается конструктор по умолчанию. И мы можем использовать этот конструктор. В частности, создадим один объект класса Person [4]:
class Program
{
    static void Main(string[] args)
    {
        Person tom = new Person();
        tom.GetInfo();      // Имя: Возраст: 0
        tom.name = "Tom";
        tom.age = 34;
        tom.GetInfo();  // Имя: Tom Возраст: 34
          
        Console.Read();
    }
}
Для создания объекта Person используется выражение new Person(). Оператор New выделяет память для объекта Person. И затем вызывается конструктор по умолчанию, который не принимает никаких параметров. В итоге после выполнения данного выражения в памяти будет выделен участок, где будут храниться все данные объекта Person. А переменная tom получит ссылку на созданный объект.


2.10. Разработка приложений по формированию запросов и отчётов с использованием баз данных

Покажем на следующем примере порядок разработки приложений в которых формируются запросы и отчёты с использованием баз данных (приложение разработано )
2.10.1. Создание проекта
Откроем Visual Studio и создадим новый проект Windows Forms. В примере будет использоваться Visual Studio 2017 community.
Запускаем Visual Studio. На начальной странице в верхней панели управления выберем «Файл» -> «Создать проект».


Откроется окно «Создание проекта». В левой панели выберем «Установленные» -> «Шаблоны» -> «Другие языки» -> «Visual C#». Если Visual C# не установлен, то его можно установить, кликнув по ссылке в этом же окне «Открыть установщик Visual Studio».

Теперь выберем тип проекта «Приложение Windows Forms (.Net Framework)», в строке «Имя» назовем проект «LocalDBExample», и нажимаем кнопку «ОК».

Откроется окно проекта, которое выглядит следующим образом:


2.10.2. Создание интерфейса приложения

Сделаем нашу форму активной, просто щелкнув по ней левой клавишей мыши. В окне «свойства» изменим поле «Text». Теперь форма будет иметь название «LocalDBExample» вместо «Form1».

С панели элементов перетащим элемент «TabControl» на форму. Если панель еще не открыта, то нужно выбрать ее из вкладки «Вид».

Изменим значение свойства «Dock» табконтрола на значение «Fill», чтобы растянуть элемент на весь экран. Чтобы добавить вкладки в табконтрол, выберем свойство «TapPages» и нажмем на кнопку «». Откроется окно «Редактор коллекции TabPage».

Добавим еще две вкладки, кнопкой «Добавить». Теперь в свойствах каждой вкладки нужно присвоить название. Для этого выберем свойство «Text» для tabPage1, и введем название «SELECT». Остальные вкладки назовем «INSERT», «UPDATE» и «DELETE» соответственно. В результате, табконтрол должен выглядеть так:

На вкладку «SELECT» поместим элемент ListBox и установим его параметру «Dock» значение «Fill».

Перейдем на вкладку «INSERT». Добавим следующие элементы управления: Два элемента Label, два элемента TextBox, и один Button. Label – это простой элемент для вывода текста. TextBox предназначен для ввода, а Button – это стандартная кнопка, по нажатию, на которую, будет происходить добавление данных в базу. В элементы Label поместим текст «Имя продукта» и «Цена». Кнопку назовем «Добавить». Для того чтобы изменить текст внутри элемента, необходимо изменить его свойство «Text». Расположим элементы следующим образом:

Аналогично оформим вкладку «UPDATE» следующим образом:

И вкладку «DELETE»:


2.10.3. Создание базы данных
LocalDB – это компонент системы управления базами данных MS SQL Server, созданный непосредственно для разработчиков. При добавлении localDB в проект Visual Studio, в том случае, если необходимые компоненты не будут установлены, Visual Studio сама предложит установить эти компоненты прямо по ходу работы.
Чтобы добавить базу данных в проект, в обозревателе решений нужно правой кнопкой мыши щелкнуть по названию проекта (LocalDBExample). Далее из выпадающего меню нужно выбрать «Добавить» и затем «Создать элемент».
1
Откроется окно, где нужно выбрать элемент «База данных, основанная на службах», и присвоить ему имя. Назовем базу данных «ExampleData» и нажмем «Добавить».

Видим, что в обозревателе решений появились файлы «ExampleData.mdf» и «ExampleData_log.ldf».

Выполняем двойной щелчок по «ExampleData.mdf» и в обозревателе серверов видим нашу базу данных.

Чтобы создать в базе данных новую таблицу, в обозревателе решений в каталоге базы данных ExampleData.mdf нажмем правой кнопкой на папку «Таблицы». Затем нажмем «Добавить новую таблицу». В результате откроется конструктор новой таблицы.

Таким образом, в конструкторе открылись две вкладки: «Проектирование» и «T-SQL». T-SQL – это структурированный язык запросов, с помощью которого происходит управление базами данных. Он незначительно, но все же отличается от стандартного языка SQL.
На вкладке «T-SQL» в строке «CREATE TABLE [dbo].[Table]» изменим название таблицы следующим образом: «CREATE TABLE [dbo].[Products]».
По умолчанию в таблице предложено создать поле «Id», добавим еще два поля: «Name» и «Price», куда будут добавляться наименования продуктов и цена на них.
Выберем в проектировании таблицы поле «Id», теперь в окне свойств выберем «спецификация идентификтора» и в параметр «(Идентификатор)» установим значение «True». Теперь при добавлении данных, не нужно указывать id, он автоматически будет увеличиваться на единицу. Мы видим что на вкладке T-SQL к полю Id добавился параметр «IDENTITY».

Добавим на вкладке проектирования поле Name, и установим тип данных nvarchar(50). Это означает, что значением в этом поле будет строка с максимально допустимым количеством символов в ней – 50. Теперь добавим поле Price, и установим такой же тип данных.

На вкладке проектирования нажмем кнопку «Обновить». Откроется следующее окно:

Нажмем «Обновить базу данных». Теперь, чтобы увидеть нашу таблицу в обозревателе серверов, нужно правой кнопкой нажать на папку «Таблицы» и затем нажать «Обновить».

Выполним щелчок правой клавишей по таблице Products и выберем «Показать таблицу данных».

Заполним таблицу данными. Возьмем к примеру товары из продуктового магазина: кофе, яблоко, печенье, колбаса, жвачка, конфеты. Укажем им цену: 300, 30, 100, 400, 20, 250 соответственно. Поле Id заполнять не нужно! Чтобы изменения сохранились, нужно нажать на кнопку «Сохранить все».




2.10.4. Подключение к базе данных
Выделим нашу главную форму (LocalDBExample), щелкнув по ней ЛКМ. Теперь в окне свойств формы нажмем на значок в виде молнии, для того, чтобы открыть список событий, с которыми форма может взаимодействовать. Далее выберем метод «Load» и выполним в двойной щелчок мышкой по этой строке.

В результате, Visual Studio создаст метод Form1.Load(), который будет выполнять действия при загрузке формы.

Добавим необходимые библиотеки для работы с базами данных:
using System.Data;
using System.Data.SqlClient;

Для работы с базой данных, необходимо к ней подключиться через строку подключения. Создадим глобальную переменную «SqlConnection sqlConnection».

Теперь необходимо получить строку подключения из свойств базы данных и присвоить ее переменной connectionString. В обозревателе сервером нужно выделить базу данных ExampleData одинарным щелчком. Затем в окне свойств найти параметр «Строка подключения», скопировать его содержимое и в методе Form1_Load инициализировать переменную connectionString. Так как строка подключения содержит в себе символы «» (кавычки) и \ (слеш), нужно перед каждым таким символом поставить знак \ (слеш). В результате, строка подключения выглядит следующим образом:

Теперь напишем обработчик исключений:
try
{
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString(),ex.Source.ToString(), MessageBoxButtons.OK);
}
finally
{
}

Код, который последует далее, необходимо писать в теле этого обработчика (try).
Создадим подключение и откроем его следующим образом:
sqlConnection = new SqlConnection(connectionString);
sqlConnection.Open();

2.10.5. Чтение данных
Для чтения данных из базы, необходим объект SqlReader. Объявим его глобально:
SqlDataReader sqlReader = null;

Теперь создадим команду, в которую укажем запрос к базе данных:
SqlCommand command = new SqlCommand("SELECT * FROM [Products]", sqlConnection);

Объявим sqlReader:
sqlReader = command.ExecuteReader();
И далее, с помощью цикла while, sqlReader “пробежит” по таблице продуктов. Необходимо вывести данные в listBox с вкладки SELECT. Удобно и быстро это сделать через пробелы:

while (sqlReader.Read())
{
listBox1.Items.Add(Convert.ToString(sqlReader["Id"]) + " " +
Convert.ToString(sqlReader["Name"]) + " " +
Convert.ToString(sqlReader["Price"])
);
}

В блоке finally обработчика исключений закроем sqlReader:
if (sqlReader != null)
sqlReader.Close();

2.10.6. Закрытие базы данных
После выполнения программы будет правильным закрыть соединение с базой данных, поэтому пропишем обработчик события FormClosing для формы.
Также, как и для «OnLoad», находим в списке обработчиков FormClosing, и выполняем двойной щелчок. В коде обработчика закроем соединение с базой данных:
if (sqlConnection != null && sqlConnection.State != ConnectionState.Closed)
sqlConnection.Close();
В результате, метод выглядит так:

Запустим программу и увидим результат:


2.10.7. Добавление записей в базу данных

Так как подключение к базе данных уже происходит при загрузке формы LocalDBExample, нам не нужно подключаться повторно. Перейдем на вкладку INSERT и выполним двойной щелчок по кнопке «Добавить». Visual Studio создаст метод, который будет обрабатывать нажатие этой кнопки.

Пропишем туда новую команду:
SqlCommand command = new SqlCommand("INSERT INTO [Products] (Name, Price)VALUES(@Name,@Price)", sqlConnection);
Теперь свяжем наши данные из базы с элементами TextBox:

Нужно учесть вариант, в котором пользователь оставит поля пустыми. Для этого на вкладку INSERT добавим еще один Label, в котором будет выводиться информация об ошибке. Присвоим его свойству Visible значение false.

Теперь в обработчик нажатия кнопки добавим условный оператор, который будет проверять, заполнены ли поля, и выводить сообщение в label в обратном случае:
if (!string.IsNullOrEmpty(textBox1.Text) && !string.IsNullOrWhiteSpace(textBox1.Text) &&
!string.IsNullOrEmpty(textBox2.Text) && !string.IsNullOrWhiteSpace(textBox2.Text))
{
НАШ КОД
}
else
{
label7.Visible = true;
label7.Text = "Поля 'Имя' и 'Цена' должны быть заполнены!";
}

И перед выполнением выделенного кода, нужно проверить свойство visible у label7, и если оно равно true, то заменить на false;
if (label7.Visible) label7.Visible = false;

Для добавления в базу новых данных осталось только выполнить написанную команду:
command.ExecuteNonQuery();

Для того, чтобы можно было увидеть изменения на вкладке SELECT, не выходя из программы, добавим на вкладку SELECT еще одну кнопку, и назовем ее «Обновить»:

В ее обработчике нужно очистить вкладку SELECT, а затем снова загрузить туда данные из базы точно так же, как это было сделано в методе Form1_Load.
listBox1.Items.Clear();
if (sqlReader != null)
sqlReader.Close();
string connectionString = "Data Source=(LocalDB)\\MSSQLLocalDB;" +
"Atta
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·ng(sqlReader["Price"])
);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString(),ex.Source.ToString(), MessageBoxButtons.OK);
}
finally
{
if (sqlReader != null)
sqlReader.Close();
}
}

Важно не забыть, перед этим закрыть уже существующее подключение к базе данных:
if (sqlReader != null)
sqlReader.Close();


Запустим программу и перейдем на вкладку INSERT. В поле «Имя продукта» занесем апельсин, а в поле «Цена» напишем 40.

Нажмем кнопку добавить, перейдем на вкладку SELECT, и нажмем «Обновить».

Как мы видим, в таблицу продуктов добавился апельсин. В обозревателе серверов правой кнопкой нажмем на базу данных и выберем обновить. Затем откроем таблицу продуктов:

Видим, что добавился апельсин.

2.10.8. Корректировка записей в базе данных
Перейдем на вкладку UPDATE. Выполним двойной щелчок по кнопке «Изменить». Здесь нужно проверить наличие идентификатора и заполнены ли поля «Имя продукта» и «Цена». Также как и на вкладке UPDATE, добавим Label на вкладку UPDATE.

Выполним проверку, не пусты ли поля в обработчике события кнопки «Изменить»:
if (label8.Visible) label8.Visible = false;

if (!string.IsNullOrEmpty(textBox4.Text) && !string.IsNullOrWhiteSpace(textBox4.Text) &&
!string.IsNullOrEmpty(textBox3.Text) && !string.IsNullOrWhiteSpace(textBox3.Text) &&
!string.IsNullOrEmpty(textBox5.Text) && !string.IsNullOrWhiteSpace(textBox5.Text))
{

}
else
{
label8.Visible = true;
label8.Text = "Заполните все поля!";
}

Напишем команду для обновления данных:
SqlCommand command = new SqlCommand("UPDATE [Products] SET [Name] = @Name, [Price] = @Price WHERE [Id] = @Id", sqlConnection);
Свяжем ее с полями TextBox:
command.Parameters.AddWithValue("Id", textBox5.Text);
command.Parameters.AddWithValue("Name", textBox4.Text);
command.Parameters.AddWithValue("Price", textBox3.Text);
И выполним:
command.ExecuteNonQuery();

Запустим приложение, перейдем на вкладку UPDATE, и изменим данные по идентификатору 3. В поле «Имя» запишем банан, а в поле «Цена» - 30.

Нажмем кнопку «Изменить» и затем обновим вывод на вкладке SELECT:

Видим, что вместо печенья в строку три занесен банан.
2.10.9. Удаление записей из базы данных
Также как и в предыдущих примерах, добавим Label на вкладку DELETE, и присвоим свойству Visible значение false.
Вызовем обработчик события кнопки «Удалить» и пропишем туда проверку заполнения полей:
if (label9.Visible) label8.Visible = false;

if (!string.IsNullOrEmpty(textBox6.Text) && !string.IsNullOrWhiteSpace(textBox6.Text))
{

}
else
{
label9.Visible = true;
label9.Text = "Заполните поле 'Id'!";
}

Теперь напишем новую команду и выполним ее:
SqlCommand command = new SqlCommand("DELETE FROM [Products]" +
" WHERE [Id] = @Id", sqlConnection);
command.Parameters.AddWithValue("Id", textBox6.Text);
command.ExecuteNonQuery();

Запустим программу и удалим запись в таблице продуктов под номером 3:

После нажатия на кнопку «Удалить», обновим список на вкладке SELECT, и увидим, что запись под номером 3 удалена.


2.10.10. Установка ReportViewer
Формирование отчетов в Visual Studio может выполняться разными способами, в том числе и без специализированных элементов управления. Рассмотрим элемент управления ReportViewer. Он используется для размещения детализированных отчетов в проектах приложений Windows.
Начнем с установки ReportViewer в проект. Выберем вкладку «Сервис» в панели управления, и из выпадающего списка «Расширения и обновления».

Откроется окно расширений. В меню слева выберем пункт «В сети». Теперь найдем нужные компоненты через строку поиска, напишем туда «report».

Теперь нужно скачать Microsoft Rdlc Report Designer for Visual Studio. После завершения установки закроем окно и закроем Visual Studio, для того чтобы скачанное расширение установилось. После закрытия студии откроется следующее окно:

Нажимаем «Изменить» и дожидаемся окончания установки.
В обозревателе решений правой кнопкой выберем пункт «Ссылки» и затем «Управление пакетами NuGet». В появившемся окне выберем вкладку «Обзор». В строке поиска введем запрос «reportviewercontrol».

Скачаем версию для .Net Windows Forms.

В панели элементов правой кнопкой выберем «Общие» и затем «Выбрать элементы». Откроется следующее окно:

Для указания пути к установленной библиотеке нажмем «Обзор». Откроется окно для указания пути. В папке проекта откроем папку packages, затем папку «Microsoft.ReportingServices.ReportViewerControl.Winforms.140.1000.523», затем «lib», затем «net40», и выберем файл «Microsoft.ReportViewer.WinForms.dll». Нажмем «Открыть».

Видим, что в панели элементов появился элемент ReportViewer.

2.10.11. Формирование отчетов
Создадим еще одну форму. В обозревателе решений правой кнопкой нажмем на название проекта, выберем «Добавить», и выберем «Создать элемент». Из списка выберем элемент «Форма WindowsForms». Теперь на форму добавим элемент управления ReportViewer и закрепи ее в родительском контейнере.

В обозревателе решений правой кнопкой нажмем на название проекта, выберем пункт «Добавить» и далее «Создать элемент». Из списка выберем мастер отчетов. Откроется мастер отчетов:

В мастере настройки источника данных нажимаем «Далее».

Нажимаем «Далее».

Нажимаем «Далее». Ставим галочку на пункте «Таблицы» и нажимаем «Готово».

Теперь из доступных полей нужно мышкой перетащить поля в область «Значения» и нажать «Далее».

После этого завершаем мастер установки, нажимая «Далее» и «Готово» в конце.

Теперь отчет выглядит так:

Перейдем на форму 2, и элементу ReportViewer в выпадающем меню, в пункте «Choose report» укажем наш созданный отчет.

На вкладку SELECT формы 1 добавим кнопку «Показать отчет», а в ее обработчике события пропишем следующий код:
new Form2().Show();

Выровняем данные в отчете по центру, добавим новое текстовое поле с названием отчета над таблицей, запустим приложение, и нажмем на кнопку «Показать отчет».


2.11. Файлы
В начале рассмотрим основные возможности.
В С# есть пространство имен System.IO, в котором реализованы все необходимые нам классы для работы с файлами. Чтобы подключить это пространство имен, необходимо в самом начале программы добавить строку using System.IO. Для использования кодировок еще добавим пространство:
using System.Text;
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO;
Для создания пустого файла, в классе File есть метод Create(). Он принимает один аргумент – путь. Ниже приведен пример создания пустого текстового файла new_file.txt на диске D:
static void Main(string[] args) {   File.Create("D:\\new_file.txt");}
Если файл с таким именем уже существует, он будет переписан на новый пустой файл.
Метод WriteAllText() создает новый файл (если такого нет), либо открывает существующий и записывает текст, заменяя всё, что было в файле:
static void Main(string[] args) {   File. WriteAllText("D:\\new_file.txt", "текст");}
Метод AppendAllText() работает, как и метод WriteAllText() за исключением того, что новый текст дописывается в конец файла, а не переписывает всё что было в файле: 
static void Main(string[] args) {   File.AppendAllText("D:\\new_file.txt", "текст метода AppendAllText ()"); //допишет текст в конец файла }
Метод Delete() удаляет файл по указаному пути: static void Main(string[] args) {   File.Delete("d:\\test.txt"); //удаление файла }
Кроме того, чтобы читать/записывать данные в файл с С# можно использовать потоки.
Поток – это абстрактное представление данных (в байтах), которое облегчает работу с ними. В качестве источника данных может быть файл, устройство ввода-вывода, принтер.
Класс Stream является абстрактным базовым классом для всех потоковых классов в Си-шарп. Для работы с файлами нам понадобится класс FileStream(файловый поток).
FileStream - представляет поток, который позволяет выполнять операции чтения/записи в файл.
static void Main(string[] args) { FileStream file = new FileStream("d:\\test.txt", FileMode.Open , FileAccess.Read); //открывает файл только на чтение }
Режимы открытия FileMode:
- Append – открывает файл (если существует) и переводит указатель в конец файла (данные будут дописываться в конец), или создает новый файл. Данный режим возможен только при режиме доступа FileAccess.Write. - Create - создает новый файл(если существует – заменяет).
- CreateNew – создает новый файл (если существует – генерируется исключение). - Open - открывает файл (если не существует – генерируется исключение). - OpenOrCreate – открывает файл, либо создает новый, если его не существует. - Truncate – открывает файл, но все данные внутри файла затирает (если файла не существует – генерируется исключение).
static void Main(string[] args) {    FileStream file1 = new FileStream("d:\\file1.txt", FileMode.CreateNew); //создание нового файла    FileStream file2 = new FileStream("d:\\file2.txt", FileMode.Open); //открытие существующего файла    FileStream file3 = new FileStream("d:\\file3.txt", FileMode.Append); //открытие файла на дозапись в конец файла }
Режим доступа FileAccess: - Read – открытие файла только на чтение. При попытке записи генерируется исключение.
- Write - открытие файла только на запись. При попытке чтения генерируется исключение.
- ReadWrite - открытие файла на чтение и запись.
Для чтения данных из потока нам понадобится класс StreamReader. В нем реализовано множество методов для удобного считывания данных. Ниже приведена программа, которая выводит содержимое файла на экран: static void Main(string[] args) {    FileStream file1 = new FileStream("d:\\test.txt", FileMode.Open); //создаем файловый поток    StreamReader reader = new StreamReader(file1); // создаем «потоковый читатель» и связываем его с файловым потоком     Console.WriteLine(reader.ReadToEnd()); //считываем все данные с потока и выводим на экран    reader.Close(); //закрываем поток    Console.ReadLine(); }
Метод ReadToEnd() считывает все данные из файла. ReadLine() – считывает одну строку (указатель потока при этом переходит на новую строку, и при следующем вызове метода будет считана следующая строка). Свойство EndOfStream указывает, находится ли текущая позиция в потоке в конце потока (достигнут ли конец файла). Возвращает true или false.
Для записи данных в поток используется класс StreamWriter. Пример записи в файл:
static void Main(string[] args) {    FileStream file1 = new FileStream("d:\\test.txt", FileMode.Create); //создаем файловый поток   StreamWriter writer = new StreamWriter(file1); //создаем «потоковый писатель» и связываем его с файловым потоком     writer.Write("текст"); //записываем в файл    writer.Close(); //закрываем поток. Не закрыв поток, в файл ничего не запишется  }
Метод WriteLine() записывает в файл построчно (то же самое, что и простая запись с помощью Write(), только в конце добавляется новая строка).
Нужно всегда помнить, что после работы с потоком, его нужно закрыть (освободить ресурсы), использовав метод Close().
Кодировка, в которой будут считываться/записываться данные указывается при создании StreamReader/StreamWriter:

static void Main(string[] args) {    FileStream file1 = new FileStream("d:\\test.txt", FileMode.Open);     StreamReader reader = new StreamReader(file1, Encoding.Unicode);    StreamWriter writer = new StreamWriter(file1, Encoding.UTF8); }
Кроме того, при использовании StreamReader и StreamWriter можно не создавать отдельно файловый поток FileStream, а сделать это сразу при создании StreamReader/StreamWriter:
static void Main(string[] args) {     StreamWriter writer = new StreamWriter("d:\\test.txt"); //указываем путь к файлу, а не поток     writer.WriteLine("текст");    writer.Close();  }
Папка создаётся с помощью статического метода CreateDirectory() класса Directory:
static void Main(string[] args) {   Directory.CreateDirectory("d:\\new_folder");}
Для удаления папок используется метод Delete(): static void Main(string[] args) {    Directory.Delete("d:\\new_folder"); //удаление пустой папки }
Если папка не пустая, необходимо указать параметр рекурсивного удаления - true:
static void Main(string[] args) {    Directory.Delete("d:\\new_folder", true); //удаление папки, и всего, что внутри }

Далее рассмотрим боле подробно.
Для работы с файлами предназначена пара классов File и FileInfo. С их помощью мы можем создавать, удалять, перемещать файлы, получать их свойства и многое другое.
Некоторые полезные методы и свойства класса FileInfo:
CopyTo(path): копирует файл в новое место по указанному пути path.
Create(): создает файл.
Delete(): удаляет файл.
MoveTo(destFileName): перемещает файл в новое место.
Свойство Directory: получает родительский каталог в виде объекта DirectoryInfo
Свойство DirectoryName: получает полный путь к родительскому каталогу.
Свойство Exists: указывает, существует ли файл.
Свойство Length: получает размер файла.
Свойство Extension: получает расширение файла.
Свойство Name: получает имя файла.
Свойство FullName: получает полное имя файла.
Класс File реализует похожую функциональность с помощью статических методов:
Copy(): копирует файл в новое место.
Create(): создает файл.
Delete(): удаляет файл.
Move: перемещает файл в новое место.
Exists(file): определяет, существует ли файл.
Получение информации о файле
string path = @"C:\apache\hta.txt";
FileInfo fileInf = new FileInfo(path);
if (fileInf.Exists)
{
    Console.WriteLine("Имя файла: {0}", fileInf.Name);
    Console.WriteLine("Время создания: {0}", fileInf.CreationTime);
    Console.WriteLine("Размер: {0}", fileInf.Length);
}
Удаление файла
string path = @"C:\apache\hta.txt";
FileInfo fileInf = new FileInfo(path);
if (fileInf.Exists)
{
   fileInf.Delete();
   // альтернатива с помощью класса File
   // File.Delete(path);
}
Перемещение файла
string path = @"C:\apache\hta.txt";
string newPath = @"C:\SomeDir\hta.txt";
FileInfo fileInf = new FileInfo(path);
if (fileInf.Exists)
{
   fileInf.MoveTo(newPath);      
   // альтернатива с помощью класса File
   // File.Move(path, newPath);
}
Копирование файла
string path = @"C:\apache\hta.txt";
string newPath = @"C:\SomeDir\hta.txt";
FileInfo fileInf = new FileInfo(path);
if (fileInf.Exists)
{
   fileInf.CopyTo(newPath, true);     
   // альтернатива с помощью класса File
   // File.Copy(path, newPath, true);
}
Метод CopyTo класса FileInfo принимает два параметра: путь, по которому файл будет копироваться, и булевое значение, которое указывает, надо ли при копировании перезаписывать файл (если true, как в случае выше, файл при копировании перезаписывается). Если же в качестве последнего параметра передать значение false, то если такой файл уже существует, приложение выдаст ошибку.
Метод Copy класса File принимает три параметра: путь к исходному файлу, путь, по которому файл будет копироваться, и булевое значение, указывающее, будет ли файл перезаписываться.

2.11.1. Чтение и запись файла. Класс FileStream
Класс FileStream представляет возможности по считыванию из файла и записи в файл. Он позволяет работать как с текстовыми файлами, так и с бинарными.
Рассмотрим наиболее важные его свойства и методы:
Свойство Length: возвращает длину потока в байтах
Свойство Position: возвращает текущую позицию в потоке
Метод Read: считывает данные из файла в массив байтов. Принимает три параметра: int Read(byte[] array, int offset, int count) и возвращает количество успешно считанных байтов. Здесь используются следующие параметры:
array - массив байтов, куда будут помещены считываемые из файла данные
offset представляет смещение в байтах в массиве array, в который считанные байты будут помещены
count - максимальное число байтов, предназначенных для чтения. Если в файле находится меньшее количество байтов, то все они будут считаны.
Метод long Seek(long offset, SeekOrigin origin): устанавливает позицию в потоке со смещением на количество байт, указанных в параметре offset.
Метод Write: записывает в файл данные из массива байтов. Принимает три параметра: Write(byte[] array, int offset, int count)
array - массив байтов, откуда данные будут записываться в файла
offset - смещение в байтах в массиве array, откуда начинается запись байтов в поток
count - максимальное число байтов, предназначенных для записи
FileStream представляет доступ к файлам на уровне байтов, поэтому, например, если вам надо считать или записать одну или несколько строк в текстовый файл, то массив байтов надо преобразовать в строки, используя специальные методы. Поэтому для работы с текстовыми файлами применяются другие классы.
В то же время при работе с различными бинарными файлами, имеющими определенную структуру FileStream может быть очень даже полезен для извлечения определенных порций информации и ее обработки.
Посмотрим на примере считывания-записи в текстовый файл:
Console.WriteLine("Введите строку для записи в файл:");
string text = Console.ReadLine();
// запись в файл
using (FileStream fstream = new FileStream(@"C:\SomeDir\noname\note.txt", FileMode.OpenOrCreate))
{
    // преобразуем строку в байты
    byte[] array = System.Text.Encoding.Default.GetBytes(text);
    // запись массива байтов в файл
    fstream.Write(array, 0, array.Length);
    Console.WriteLine("Текст записан в файл");
}
// чтение из файла
using (FileStream fstream = File.OpenRead(@"C:\SomeDir\noname\note.txt"))
{
    // преобразуем строку в байты
    byte[] array = new byte[fstream.Length];
    // считываем данные
    fstream.Read(array, 0, array.Length);
    // декодируем байты в строку
    string textFromFile = System.Text.Encoding.Default.GetString(array);
    Console.WriteLine("Текст из файла: {0}", textFromFile);
}
Console.ReadLine();
Разберем этот пример. И при чтении, и при записи используется оператор using. Оператор using позволяет создавать объект в блоке кода, по завершению которого вызывается метод Dispose у этого объекта, и, таким образом, объект уничтожается. В данном случае в качестве такого объекта служит переменная fstream.
Объект fstream создается двумя разными способами: через конструктор и через один из статических методов класса File.
Здесь в конструктор передается два параметра: путь к файлу и перечисление FileMode. Данное перечисление указывает на режим доступа к файлу и может принимать следующие значения:
Append: если файл существует, то текст добавляется в конец файл. Если файла нет, то он создается. Файл открывается только для записи.
Create: создается новый файл. Если такой файл уже существует, то он перезаписывается
CreateNew: создается новый файл. Если такой файл уже существует, то он приложение выбрасывает ошибку
Open: открывает файл. Если файл не существует, выбрасывается исключение
OpenOrCreate: если файл существует, он открывается, если нет - создается новый
Truncate: если файл существует, то он перезаписывается. Файл открывается только для записи.
Статический метод OpenRead класса File открывает файл для чтения и возвращает объект FileStream.
Конструктор класса FileStream также имеет ряд перегруженных версий, позволяющий более точно настроить создаваемый объект. Все эти версии можно посмотреть на msdn.
И при записи, и при чтении применяется объект кодировки Encoding.Default из пространства имен System.Text. В данном случае мы используем два его метода: GetBytes для получения массива байтов из строки и GetString для получения строки из массива байтов.
В итоге введенная нами строка записывается в файл note.txt. По сути это бинарный файл (не текстовый), хотя если мы в него запишем только строку, то сможем посмотреть в удобочитаемом виде этот файл, открыв его в текстовом редакторе. amWriter.
Произвольный доступ к файлам
Нередко бинарные файлы представляют определенную стрктуру. И, зная эту структуру, мы можем взять из файла нужную порцию информации или наоброт записать в определенном месте файла определенный набор байтов. Например, в wav-файлах непосредственно звуковые данные начинаются с 44 байта, а до 44 байта идут различные метаданные - количество каналов аудио, частота дискретизации и т.д.
С помощью метода Seek() мы можем управлять положением курсора потока, начиная с которого производится считывание или запись в файл. Этот метод принимает два параметра: offset (смещение) и позиция в файле.
Позиция в файле описывается тремя значениями:
SeekOrigin.Begin: начало файла
SeekOrigin.End: конец файла
SeekOrigin.Current: текущая позиция в файле
Курсор потока, с которого начинается чтение или запись, смещается вперед на значение offset относительно позиции, указанной в качестве второго параметра. Смещение может отрицательным, тогда курсор сдвигается назад, если положительное - то вперед.
Рассмотрим на примере:
using System.IO;
using System.Text;
class Program
{
    static void Main(string[] args)
    {
        string text = "hello world";
        // запись в файл
        using (FileStream fstream = new FileStream(@"D:\note.dat", FileMode.OpenOrCreate))
        {
            // преобразуем строку в байты
            byte[] input = Encoding.Default.GetBytes(text);
            // запись массива байтов в файл
            fstream.Write(input, 0, input.Length);
            Console.WriteLine("Текст записан в файл");
            // перемещаем указатель в конец файла, до конца файла- пять байт
            fstream.Seek(-5, SeekOrigin.End); // минус 5 символов с конца потока
            // считываем четыре символов с текущей позиции
            byte[] output = new byte[4];
            fstream.Read(output, 0, output.Length);
            // декодируем байты в строку
            string textFromFile = Encoding.Default.GetString(output);
            Console.WriteLine("Текст из файла: {0}", textFromFile); // worl
            // заменим в файле слово world на слово house
            string replaceText = "house";
            fstream.Seek(-5, SeekOrigin.End); // минус 5 символов с конца потока
            input = Encoding.Default.GetBytes(replaceText);
            fstream.Write(input, 0, input.Length);
            // считываем весь файл
            // возвращаем указатель в начало файла
            fstream.Seek(0, SeekOrigin.Begin);
            output = new byte[fstream.Length];
            fstream.Read(output, 0, output.Length);
            // декодируем байты в строку
            textFromFile = Encoding.Default.GetString(output);
            Console.WriteLine("Текст из файла: {0}", textFromFile); // hello house
        }
        Console.Read();
    }
}
2.11.2. StreamReader и StreamWriter
Класс StreamReader позволяет нам легко считывать весь текст или отдельные строки из текстового файла. Среди его методов можно выделить следующие:
Close: закрывает считываемый файл и освобождает все ресурсы.
Peek: возвращает следующий доступный символ, если символов больше нет, то возвращает -1.
Read: считывает и возвращает следующий символ в численном представлении. Имеет перегруженную версию:Read(char[] array, int index, int count), где array - массив, куда считываются символы, index - индекс в массиве array, начиная с которого записываются считываемые символы, и count - максимальное количество считываемых символов
ReadLine: считывает одну строку в файле.
ReadToEnd: считывает весь текст из файла.
Считаем текст из файла различными способами:
string path= @"C:\SomeDir\hta.txt";
try
{
    Console.WriteLine("******считываем весь файл********");
    using (StreamReader sr = new StreamReader(path))
    {
        Console.WriteLine(sr.ReadToEnd());
    }
    Console.WriteLine();
    Console.WriteLine("******считываем построчно****
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·считываем блоками********");
    using (StreamReader sr = new StreamReader(path, System.Text.Encoding.Default))
    {
        char[] array = new char[4];
        // считываем 4 символа
        sr.Read(array, 0, 4);
 
        Console.WriteLine(array);          
    }
}
catch (Exception e)
{
    Console.WriteLine(e.Message);
}
Как и в случае с классом FileStream здесь используется конструкция using.
В первом случае мы разом считываем весь текст с помощью метода ReadToEnd().
Во втором случае считываем построчно через цикл while: while ((line = sr.ReadLine()) != null) - сначала присваиваем переменной line результат функции sr.ReadLine(), а затем проверяем, не равна ли она null. Когда объект sr дойдет до конца файла и больше строк не останется, то метод sr.ReadLine() будет возвращать null.
В третьем случае считываем в массив четыре символа.
Обратите внимание, что в последних двух случаях в конструкторе StreamReader указывалась кодировка System.Text.Encoding.Default.
Свойство Default класса Encoding получает кодировку для текущей кодовой страницы ANSI. Также через другие свойства мы можем указать другие кодировки. Если кодировка не указана, то при чтении используется UTF8. Иногда важно указывать кодировку, так как она может отличаться от UTF8, и тогда мы получим некорректный вывод.
Запись в файл и StreamWriter
Для записи в текстовый файл используется класс StreamWriter. Свою функциональность он реализует через следующие методы:
Close: закрывает записываемый файл и освобождает все ресурсы.
Flush: записывает в файл оставшиеся в буфере данные и очищает буфер.
Write: записывает в файл данные простейших типов, как int, double, char, string и т.д.
WriteLine: также записывает данные, только после записи добавляет в файл символ окончания строки
Рассмотрим запись в файл на примере:
string readPath= @"C:\SomeDir\hta.txt";
string writePath = @"C:\SomeDir\ath.txt";
string text = "";
try
{
    using (StreamReader sr = new StreamReader(readPath, System.Text.Encoding.Default))
    {
        text=sr.ReadToEnd();
    }
    using (StreamWriter sw = new StreamWriter(writePath, false, System.Text.Encoding.Default))
    {
        sw.WriteLine(text);
    }
    using (StreamWriter sw = new StreamWriter(writePath, true, System.Text.Encoding.Default))
    {
        sw.WriteLine("Дозапись");
        sw.Write(4.5);
    }
}
catch (Exception e)
{
    Console.WriteLine(e.Message);
}
Здесь сначала мы считываем файл в переменную text, а затем записываем эту переменную в файл, а затем через объект StreamWriter записываем в новый файл.
Класс StreamWriter имеет несколько конструкторов. Здесь мы использовали один из них: new StreamWriter(writePath, false, System.Text.Encoding.Default). В качестве первого параметра передается путь к записываемому файлу. Второй параметр представляет булевую переменную, которая определяет, будет файл дозаписываться или перезаписываться. Если этот параметр равен true, то новые данные добавляются в конце к уже имеющимся данным. Если false, то файл перезаписывается. И если в первом случае файл перезаписывается, то во втором делается дозапись в конец файла.
Третий параметр указывает кодировку, в которой записывается файл.




2.11.3. Работа с бинарными файлами. BinaryWriter и BinaryReader
Для работы с бинарными файлами предназначена пара классов BinaryWriter и BinaryReader. Эти классы позволяют читать и записывать данные в двоичном формате.
Основные метода класса BinaryWriter
Close(): закрывает поток и освобождает ресурсы.
Flush(): очищает буфер, дописывая из него оставшиеся данные в файл.
Seek(): устанавливает позицию в потоке.
Write(): записывает данные в поток.
Основные метода класса BinaryReader
Close(): закрывает поток и освобождает ресурсы.
ReadBoolean(): считывает значение bool и перемещает указатель на один байт.
ReadByte(): считывает один байт и перемещает указатель на один байт.
ReadChar(): считывает значение char, то есть один символ, и перемещает указатель на столько байтов, сколько занимает символ в текущей кодировке.
ReadDecimal(): считывает значение decimal и перемещает указатель на 16 байт.
ReadDouble(): считывает значение double и перемещает указатель на 8 байт.
ReadInt16(): считывает значение short и перемещает указатель на 2 байта.
ReadInt32(): считывает значение int и перемещает указатель на 4 байта.
ReadInt64(): считывает значение long и перемещает указатель на 8 байт.
ReadSingle(): считывает значение float и перемещает указатель на 4 байта.
ReadString(): считывает значение string.
Каждая строка предваряется значением длины строки, которое представляет 7-битное целое число.
С чтением бинарных данных все просто: соответствующий метод считывает данные определенного типа и перемещает указатель на размер этого типа в байтах, например, значение типа int занимает 4 байта, поэтому BinaryReader считает 4 байта и переместит указать на эти 4 байта.
Посмотрим на реальной задаче применение этих классов. Попробуем с их помощью записывать и считывать из файла массив структур:
struct State
{
    public string name;
    public string capital;
    public int area;
    public double people;
    public State(string n, string c, int a, double p)
    {
        name = n;
        capital = c;
        people = p;
        area = a;
    }
}
class Program
{
    static void Main(string[] args)
    {
        State[] states = new State[2];
        states[0] = new State("Германия", "Берлин",  357168,  80.8);
        states[1] = new State("Франция", "Париж", 640679, 64.7);
 
        string path= @"C:\SomeDir\states.dat";
        try
        {
            // создаем объект BinaryWriter
            using (BinaryWriter writer = new BinaryWriter(File.Open(path, FileMode.OpenOrCreate)))
            {
                // записываем в файл значение каждого поля структуры
                foreach (State s in states)
                {
                    writer.Write(s.name);
                    writer.Write(s.capital);
                    writer.Write(s.area);
                    writer.Write(s.people);
                }
            }
            // создаем объект BinaryReader
            using (BinaryReader reader = new BinaryReader(File.Open(path, FileMode.Open)))
            {
                // пока не достигнут конец файла
                // считываем каждое значение из файла
                while (reader.PeekChar() > -1)
                {
                    string name = reader.ReadString();
                    string capital = reader.ReadString();
                    int area = reader.ReadInt32();
                    double population = reader.ReadDouble();
 
                    Console.WriteLine("Страна: {0}  столица: {1}  площадь {2} кв. км   численность населения: {3} млн. чел.",
                        name, capital, area, population);
                }
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
        Console.ReadLine();
    }
}
Есть структура State с некоторым набором полей. В основной программе создаем массив структур и записываем с помощью BinaryWriter. Этот класс в качестве параметра в конструкторе принимает объект Stream, который создается вызовом File.Open(path, FileMode.OpenOrCreate).
Затем в цикле пробегаемся по массиву структур и записываем каждое поле структуры в поток. В том порядке, в каком эти значения полей записываются, в том порядке они и будут размещаться в файле.
Затем считываем из записанного файла. Конструктор класса BinaryReader также в качестве параметра принимает объект потока, только в данном случае устанавливаем в качестве режима FileMode.Open: new BinaryReader(File.Open(path, FileMode.Open))
В цикле while считываем данные. Чтобы узнать окончание потока, вызываем метод PeekChar(). Этот метод считывает следующий символ и возвращает его числовое представление. Если символ отсутствует, то метод возвращает -1, что будет означать, что мы достигли конца файла.
В цикле последовательно считываем значения поле структур в том же порядке, в каком они записывались.
Таким образом, классы BinaryWriter и BinaryReader очень удобны для работы с бинарными файлами, особенно когда нам известна структура этих файлов. В то же время для хранения и считывания более комплексных объектов, например, объектов классов, лучше подходит другое решение - сериализация.







2.12. Сборка мусора
При использовании ссылочных типов, например, объектов классов, для них также будет отводиться место в стеке, только там будет храниться не значение, а адрес на участок памяти в хипе или куче, в котором уже и буду находиться сами значения данного объекта. И если объект класса перестает использоваться, то при очистке стека ссылка на участок памяти также очищается, однако это не приводит к немедленной очистке самого участка памяти в куче. Впоследствии сборщик мусора (garbage collector) увидит, что на данный участок памяти больше нет ссылок, и очистит его.
Например:
class Program
{
    static void Main(string[] args)
    {
        Test();
    }
     private static void Test()
    {
        Country country = new Country();
        country.x = 10;
        country.y = 15;
    }
}
class Country
{
    public int x;
    public int y;
}
В методе Test создается объект Country. С помощью оператора new в куче для хранения объекта CRL выделяет участок памяти. А в стек добавляет адрес на этот участок памяти. В главном методе Main мы вызываем метод Test. И после того, как Test отработает, место в стеке очищается, а сборщик мусора очищает ранее выделенный под хранение объекта country участок памяти.
Сборщик мусора не запускается сразу после удаления из стека ссылки на объект, размещенный в куче. Он запускается в то время, когда среда CLR обнаружит в этом потребность, например, когда программе требуется дополнительная память.
Как правило, объекты в куче располагаются неупорядочено, между ними могут иметься пустоты. Куча довольно сильно фрагментирована. Поэтому после очистки памяти в результате очередной сборки мусора оставшиеся объекты перемещаются в один непрерывный блок памяти. Вместе с этим происходит обновление ссылок, чтобы они правильно указывали на новые адреса объектов.
Так же надо отметить, что для крупных объектов существует своя куча - Large Object Heap. В эту кучу помещаются объекта, размер которых больше 85 000 байт. Особенность этой кучи состоит в том, что при сборке мусора сжатие памяти не проводится по причине больших издержек, связанных с размером объектов.
Несмотря на то что, на сжатие занятого пространства требуется время, да и приложение не сможет продолжать работу, пока не отработает сборщик мусора, однако благодаря подобному подходу также происходит оптимизация приложения. Теперь чтобы найти свободное место в куче среде CLR не надо искать островки пустого пространства среди занятых блоков. Ей достаточно обратиться к указателю кучи, который указывает на свободный участок памяти, что уменьшает количество обращений к памяти.
Кроме того, чтобы снизить издержки от работы сборщика мусора, все объекты в куче разделяются по поколениям. Всего существует три поколения объектов: 0, 1 и 2-е.
К поколению 0 относятся новые объекты, которые еще ни разу не подвергались сборке мусора. К поколению 1 относятся объекты, которые пережили одну сборку, а к поколению 2 - объекты, прошедшие более одной сборки мусора.
Ко Очгда сборщик мусора приступает к работе, он сначала анализирует объекты из поколению 0. Те объекты, которые остаются актуальными после очистки, повышаются до поколения 1.
Если после обработки объектов поколения 0 все еще необходима дополнительная память, то сборщик мусора приступает к объектам из поколения 1. Те объекты, на которые уже нет ссылок, уничтожаются, а те, которые по-прежнему актуальны, повышаются до поколения 2.
Поскольку объекты из поколения 0 являются более молодыми и нередко находятся в адресном пространстве памяти рядом друг с другом, то их удаление проходит с наименьшими издержками.
Класс System.GC
Функционал сборщика мусора в библиотеке классов .NET представляет класс System.GC. Через статические методы данный класс позволяет обращаться к сборщику мусора. Как правило, надобность в применении этого класса отсутствует. Наиболее распространенным случаем его использования является сборка мусора при работе с неуправляемыми ресурсами, при интенсивном выделении больших объемов памяти, при которых необходимо такое же быстрое их освобождение.
Рассмотрим некоторые методы и свойства класса System.GC:
Метод AddMemoryPressure информирует среду CLR о выделении большого объема неуправляемой памяти, которую надо учесть при планировании сборки мусора. В связке с этим методом используется метод RemoveMemoryPressure, который указывает CLR, что ранее выделенная память освобождена, и ее не надо учитывать при сборке мусора.
Метод Collect приводит в действие механизм сборки мусора. Перегруженные версии метода позволяют указать поколение объектов, вплоть до которого надо произвести сборку мусора
Метод GetGeneration(Object) позволяет определить номер поколения, к которому относится переданый в качестве параметра объект
Метод GetTotalMemory возвращает объем памяти в байтах, которое занято в управляемой куче
Метод WaitForPendingFinalizers приостанавливает работу текущего потока до освобождения всех объектов, для которых производится сборка мусора
Работать с методами System.GC очень просто:
// .................................
long totalMemory = GC.GetTotalMemory(false);
 
GC.Collect();
GC.WaitForPendingFinalizers();
//......................................
С помощью перегруженных версий метода GC.Collect можно выполнить более точную настройку сборки мусора. Так, его перегруженная версия принимает в качестве параметра число - номер поколения, вплоть до которого надо выполнить очистку.
Например, GC.Collect(0) - удаляются только объекты поколения 0.
Еще одна перегруженная версия принимает еще и второй параметр - перечисление GCCollectionMode. Это перечисление может принимать три значения:
Default: значение по умолчанию для данного перечисления (Forced)
Forced: вызывает немедленное выполнение сборки мусора
Optimized: позволяет сборщику мусора определить, является ли текущий момент оптимальным для сборки мусора
Например, немедленная сборка мусора вплоть до первого поколения объектов:
GC.Collect(1, GCCollectionMode.Forced);






Глава 3. Лабораторный практикум

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

3.1. Примеры программ на С++ (Microsoft Visual Studio 2010)
3.1.1. Числовые типы, оператор присваивания
Поменять местами значение целых переменных х и у, не используя дополнительные переменные.

Решение:

#include
using namespace std;
int main()
{
double a, b;
cin >> a >> b;
a += b;
b = a - b;
a = a - b;
cout << a << ' ' << b << endl;
system("pause");
return 0;
}
3.1.2. Алгоритмы линейной структуры
Алгоритм линейной структуры  алгоритм, в котором блоки выполняются последовательно друг за другом, в порядке, заданном схемой. Такой порядок выполнения называется естественным.
Вычислить площадь треугольника со сторонами a, b, c по формуле Герона: 13 EMBED Equation.3 1415, где 13 EMBED Equation.3 1415.

Решение:

#include
using namespace std;
int main()
{
double a, b, c;
cin >> a >> b >> c;
double p = (a + b + c) / 2;
cout << "S = " << sqrt(p * (p - a) * (p - b) * (p - c)) << endl;
system("pause");
return 0;
}

Вычислить для усеченного конуса площадь поверхности 13 EMBED Equation.3 1415 и объем 13 EMBED Equation.3 1415.

Решение:

#include
using namespace std;
int main()
{
const double pi = 3.14159265358979323846;
double R, r, h, l;
cout << "R = ";
cin >> R;
cout << "r = ";
cin >> r;
cout << "h = ";
cin >> h;
cout << "l = ";
cout << "s = " << pi * (R + r) * l + pi * R * R + pi * r * r << endl
<< "V = " << (pi * (R * R + r * r + R * r) * h) / 3 << endl;
system("pause");
return 0;
}

Вычислить координаты центра тяжести трех материальных точек с массами 13 EMBED Equation.3 1415 и координатами 13 EMBED Equation.3 141513 EMBED Equation.3 141513 EMBED Equation.3 1415 по формулам: 13 EMBED Equation.3 1415; 13 EMBED Equation.3 1415.
Решение:

#include
using namespace std;
int main()
{
double m1, m2, m3;
double x1, x2, x3;
double y1, y2, y3;
cout << "Xc = " << (m1 * x1 + m2 * x2 + m3 * x3) / (m1 + m2 + m3) << endl
<< "Yc = " << (m1 * y1 + m2 * y2 + m3 * y3) / (m1 + m2 + m3) << endl;
system("pause");
return 0;
}



Вычислить высоты треугольника со сторонами а, b, c, организуя ввод данных из блока данных и вывод результатов с их наименованиями.

Решение:

#include
using namespace std;
int main()
{
double a, b, c;
cin >> a >> b >> c;
double p = (a + b + c) / 2;
double S = sqrt(p * (p - a) * (p - b) * (p - c));
cout << "H(a) = " << (2 * S) / a << endl
<< "H(b) = " << (2 * S) / b << endl
<< "H(c) = " << 2 * S / c << endl;
system("pause");
return 0;
}
3.1.3. Алгоритмы разветвляющей структуры
Вычислить:
13 EMBED Equation.3 1415
Решение:
#include
using namespace std;
int main()
{
double a, x, b;
cout << "X = ";
cin >> x;
cout << "a = ";
cin >> a;
cout << "b = ";
cin >> b;
if ((a > x) || (a == x))
cout << "Z = " << sin(x) << endl;
else if ((a < x) && (x < b))
cout << "Z = " << cos(x) << endl;
else if ((x > b) || (x == b))
cout << "Z = " << tan(x) << endl;
system("pause");
return 0;
}
Найти квадрат наибольшего из двух чисел a и b и отпечатать
N = 1, если наибольшим является а, и признак N = 2  в противном случае.


Решение:

#include
using namespace std;
int main()
{
int a, b;
cin >> a >> b;
if (a * a > b * b)
cout << "N = 1" << endl;
else
cout << "N = 2" << endl;
system("pause");
return 0;
}

Определить, попадает ли точка с координатами х, у в круг радиуса r (уравнение окружности13 EMBED Equation.3 1415). Вывести признак N = 1, если точка находится внутри круга, и признак N = 0, если точка находиться вне круга.

Составить программу, выполняющую упорядочение трех чисел A, B, C, таким образом, чтобы при выполнении ее в ячейке с символическим адресом A находилось наименьшее число, в ячейке B  среднее, в ячейке C  наибольшее.

Решение:

#include
using namespace std;
int main()
{
double a, b, c;
cin >> a >> b >> c;
//можно просто рассмотреть все 6 возможных случаев
if ((b >= a) && (b >= c) && (a >= c)) swap(a, b);
else if ((b >= a) && (b >= c) && (c >= a)) { swap(a, b); swap(b, c); }
//cout << b << " " << c << " " << a << endl;
else if ((c >= a) && (c >= b) && (a >= b)) { swap(a, c); swap(b, a); }
//cout << c << " " << a << " " << b << endl;
else if ((c >= a) && (c >= b) && (b >= a)) swap(a, c);
//cout << c << " " << b << " " << a << endl;
else if ((a >= b) && (a >= c) && (c >= b)) swap(b, c);
//cout << a << " " << c << " " << b << endl;

system("pause");
return 0;
}


Записать указанное действие в виде одного условного оператора:
а) у = 13 EMBED Equation.3 1415

Решение:

#include
using namespace std;
int main()
{

double x;
cin >> x;
cout << "Y = " << ((0 < x) && (x < 2) ? cos(x) * cos(x) : 1 - sin(x) * sin(x)) << endl;
system(“pause”);
return 0;
}

б) переменной х присвоить корень уравнения 13 EMBED Equation.3 1415.

Решение:

#include
using namespace std;
int main()
{

double x;
cin >> x;
double y = asin(log(x))
system(“pause”);
return 0;
}

в) перераспределить значение переменных х и у так, чтобы в х оказалось большее из этих значений, а в у  меньшее;

Решение:
#include
using namespace std;
int main()
{
double x, y;
cin >> x >> y;
if (x < y)
swap(x, y);
cout << "x = " << x << endl
<< "y = " << y << endl;
system(“pause”);
return 0;
}


г) d = max (a, b, c);

Решение:

double max(double first, double second, double third)
{
if ((first > second) && (first > third))
return first;
else if (second > third)
return second;
else
return third;
}

double a, b, c;
cin >> a >> b >> c;
cout << "d = " << max(a, b, c) << endl;

д) z = 13 EMBED Equation.3 1415
Решение:

double x, y;
cin >> x >> y;
if (x < 0)
cout << "Z = " << max(x, y) << endl;
else if (x >= 0)
cout << "Z = " << min(x, y) << endl;

е) переменной k присвоить номер четверти плоскости, в которой находится точка с координатами х и у (ху13 EMBED Equation.3 14150);

Решение:

double x, y;
cin >> x >> y;
if ((x > 0) && (y > 0))
cout << "k = 1" << endl;
else if ((x < 0) && (y > 0))
cout << "k = 2" << endl;
else if ((x < 0) && (y < 0))
cout << "k = 3" << endl;
else if ((y < 0) && (x > 0))
cout << "k = 4" << endl;

Записать программу для решения задачи:
а) по номеру у (у> 0) некоторого года определить с  номер его столетия (учесть, что, к примеру, началом XX столетия был 1901);

Решение:
#include using namespace std;
int main()
{
int y;
cin >> y;
int result = 1, year = 100;
while (year < y)
{
result++;
year += 100;
}
cout << result << endl;
system("pause");
return 0;
}

б) 13 EMBED Equation.3 1415;


Решение:

#include
using namespace std;
double max(double first, double second, double third)
{
if ((first > second) && (first > third))
return first;
else if (second > third)
return second;
else
return third;
}
double min(double first, double second, double third)
{
if ((first < second) && (first < third))
return first;
else if (second < third)
return second;
else
return third;
}
int main()
{
double mx, mn, x, y, z;
cin >> x >> y >> z;
mx = max(x, y, z);
mn = min(x, y, z);

cout << "u = " << (mx * mx - pow(2, x) * mn) / (sin(2) + (mx / mn)) << endl;
system("pause");
return 0;
}

в) если уравнение ax2 + bx +c = 0 (a13 EMBED Equation.3 14150) имеет вещественные корни, то логической переменной t присвоить значение True, а переменным xl и х2  сами корни, иначе переменной t присвоить False, а значение переменных xl и х2 не менять;

Решение:
#include
using namespace std;
int main()
{
double x1, x2, D, a, b, c;
bool t = true;
cin >> a >> b >> c;
D = b * b - 4 * a * c;

if (D < 0)
{
t = false;
cout << boolalpha << "t = " << t << "\nКорней нет.\n";
}
else if (D == 0)
{
x1 = (-b + sqrt(D)) / 2 * a;
cout << boolalpha << "t = " << t << "\nx1 = " << x1 << endl;
}
else
{
x1 = (-b + sqrt(D)) / 2 * a;
x2 = (-b - sqrt(D)) / 2 * a;
cout << boolalpha << "t = " << t
<< "\nx1 = " << x1
<< "\nx2 = " << x2 << endl;
}

system("pause");
return 0;
}

г) считая, что стандартные функции sin и cos применимы только к аргументам из отрезка [0, 13 EMBED Equation.3 1415], вычислить у = sin х для произвольного числа х;

Решение:

#include
using namespace std;
const double pi = 3.14159265358979;
int main()
{
double x = 0;
double res;
cin >> x;

while (abs(x) >= 2 * pi)
{
if (x > 0)
x -= 2 * pi;
else
x += 2 * pi;
}
if ((x > 0) && (x <= pi / 2))
res = sin(x);
if ((x > pi / 2) && (x <= pi))
res = sin(x - pi / 2);
if ((x > pi && x) <= (3 * pi / 2))
res = -sin(x - pi);
if ((x > 3 * pi / 2) && (x < 2 * pi))
res = -sin(x - 3 * pi / 2);
cout << "sin(x) = " << res << endl;
system("pause");
return 0;
}

д) значения переменных а, b и c поменять местами так, чтобы оказалось а13 EMBED Equation.3 1415b13 EMBED Equation.3 1415c.

Решение:

#include
using namespace std;
int main()
{
double a, b, c;
cin >> a >> b >> c;
if ((a >= b) && (a >= c) && (b >= c)) cout << a << " " << b << " " << c << endl;
else if ((b >= a) && (b >= c) && (a >= c)) cout << b << " " << a << " " << c << endl;
else if ((b >= a) && (b >= c) && (c >= a)) cout << b << " " << c << " " << a << endl;
else if ((c >= a) && (c >= b) && (a >= b)) cout << c << " " << a << " " << b << endl;
else if ((c >= a) && (c >= b) && (b >= a)) cout << c << " " << b << " " << a << endl;
else if ((a >= b) && (a >= c) && (c >= b)) cout << a << " " << c << " " << b << endl;
system("pause");
return 0;
}

3.1.4. Алгоритмы циклической структуры
Вычислить значения функции 13 EMBED Equation.3 1415, если Х задано массивом, состоящим из 40 элементов.
Решение:

#include
#include
#include
using namespace std;
int main()
{
srand(time(0));
SetConsoleCP(1251);
SetConsoleOutputCP(1251);

double x[40], y[40];
double a, b, c, e;
cin >> a >> b >> c >> e;

/*cout << "Ввод массива X:";
for (int index = 0; index < 40; index++)
cin >> x[index];*/

for (int index = 0; index < 40; index++)
x[index] = rand() % (50);

for (int index = 0; index < 40; index++)
y[index] = a * pow(e, b * x[index] + c * x[index] * x[index]);

system("pause");
return 0;
}

Вычислить и вывести на печать положительные значения функции у=sin (nx)  cos (n/x) при n = 1, 2, , 50.

Решение:

#include
using namespace std;
int main()
{
double x;
cin >> x;

for (int n = 1; n < 50; n++)
{
double y = sin(n * x) - cos(n / x);
if (y > 0)
cout << y << " ";
}
cout << endl;

system("pause");
return 0;
}

Вычислить значения функции z = xk/k, большие а, если k=1, 2, .

Решение:

#include
using namespace std;
int main()
{
double x, a;
cout << "x = ";
cin >> x;
cout << "a = ";
cin >> a;
for (int k = 1; ; k++) //конечное k не указано
{
double z = pow(x, k) / k;
if (z > a)
cout << z << " ";
}
cout << endl;
system("pause");
return 0;
}

Вычислить значения функции у = а3/(а2 + х2) при х, изменяющемся от 0 до 3 с шагом 0,1.

Решение:

#include

using namespace std;

int main()
{
double a;
cin >> a;
for (double x = 0; x < 3; x += 0.1)
cout << "y = " << pow(a, 3) / (pow(a, 2) + x * x) << endl;

system("pause");
return 0;
}

Напечатать таблицу значений аргумента х и функции
у(х) = а3/(а2 + х2) при значении х, изменяющихся от 0 до 3 с шагом 0,1.

Решение:

#include

using namespace std;

int main()
{
double a;
cin >> a;
for (double x = 0; x <= 3; x += 0.1)
cout << "y(" << x << ") = " << pow(a, 3) / (a * a + x * x) << endl;
system("pause");
return 0;
}

Составить программу для вычисления значения функции у = 13 EMBED Equation.3 1415 при одновременном изменении аргументов t от 2 до 3 с шагом 0,2 и х от 1 до 2 для а = 2,1.

Решение:

#include

using namespace std;

int main()
{
double e;
cin >> e;

for (double t = 2.0, x = 1.0, a = -1.0; t <= 3; t += 0.2, x += 0.2, a += 0.2)
cout << "y = " << sqrt(t + 1) * pow(e, -a * x * t) * cos(t - a) << endl;

system("pause");
return 0;
}

Составить программу вычисления n! (1 . 2 . 3 . 4. ... . n):

Решение:

#include

using namespace std;

int main()
{
int n, result = 1;
cin >> n;

if (n < 0)
cout << "Incorrect" << endl;
else
{
for (int num = 2; num <= n; num++)
result *= num;

cout << n << "! = " << result << endl;
}
system("pause");
return 0;
}

Составить программу, вычисляющую экстремальное значение функции 13 EMBED Equation.3 1415 при изменении аргумента х от 0 до 4 с шагом h.

Решение:

#include

using namespace std;

int main()
{
double a, b, c, e, h, max = 0;
cin >> a >> b >> c >> e;

cout << "h = ";
cin >> h;


for (double x = 0; x <= 4; x += h)
{
double current = abs(a) * pow(e, b * x + c * x * x);
if (current > max)
max = current;
}
cout << max << endl;

system("pause");
return 0;
}


Вычислить:
а) у = (2n 1)! = 13 EMBED Equation.3 1415 13 EMBED Equation.3 1415, n >0;

Решение:

#include
using namespace std;
int main()
{
int n, result = 1;
cin >> n;
n = n * 2 - 1;
for (int num = 1; num <= n; num += 2)
result *= num;

cout << "y = " << result << endl;
system("pause");
return 0;
}

б) у = (2n)! = 13 EMBED Equation.3 141513 EMBED Equation.3 1415, n >0;

n *= 2;
for (int num = 2; num < n; num += 2)
result *= num;

в) у = n!, n > 0.

for (int num = 1; num <= n; num++)
result *= num;




Вычислить: у = 13 EMBED Equation.3 1415.

Решение:
#include
int main()
{
double result = 99.0;
for (double current = 96.0; current >= 0.0; current -= 3.0)
result = sqrt(result) + current;
std::cout << sqrt(result) << std::endl;

std::system("pause");
return 0;
}

Определить, является ли заданное натуральное число совершенным, т.е. равным сумме всех своих делителей, кроме самого этого числа (например, число 6 совершенно: 6=1+2+3).

Решение:

#include
using namespace std;
bool isPerfect(int number)
{
int test = 1;
for (int subNum = 2; subNum < number; subNum++)
if (number % subNum == 0)
test += subNum;

return number == test;
}

int main()
{
int number;
cin >> number;
if (isPerfect(number))
cout << number << " is perfect." << endl;
else
cout << number << " NOT perfect." << endl;

system("pause");
return 0;
}

Дано целое n >2. Напечатать простые числа из диапазона [2, n].

Решение:

#include
using namespace std;
bool isSimple(int number)
{
if (number == 2)
return true;

if (number % 2 == 0)
return false;

int to = number / 2;
for (int Dnum = 3; Dnum < to; Dnum += 2)
if (number % Dnum == 0)
return false;

return true;
}

int main()
{
int n;
cin >> n;

for (int number = 2; number < n; number++)
if (isSimple(number))
cout << number << " ";
cout << endl;

system("pause");
return 0;
}

Найти сумму цифр заданного натурального числа.

Решение:

#include

using namespace std;

int main()
{
int number;
cin >> number;

int result = 0;
while (number != 0)
{
result += number % 10;
number /= 10;
}
cout << result << endl;

system("pause");
return 0;
}

Вычислить k  количество точек с целочисленными координатами, попадающих в круг радиуса R (R>0) с центром в начале координат.

Решение:

#include
using namespace std;
int main()
{
int radius;
cin >> radius;
cout << "k = " << int(radius) * 4 + pow(2, int(radius) - 1) * 4 << endl;
system("pause");
return 0;
}




Напечатать в возрастающем порядке все трехзначные числа, в десятичной записи которых нет одинаковых цифр.

Решение:

#include
#include
using namespace std;
vector Digit(10);
bool notCopyDig(int number)
{
while (number != 0)
{
Digit[number % 10] += 1;
number /= 10;
}

bool result = true;
for (int index = 0; index < 10; index++)
{
if (Digit[index] > 1)
result = false;
Digit[index] = 0;
}

return result;
}

int main()
{
for (int number = 100; number < 1000; number++)
if (notCopyDig(number))
cout << number << ' ';
cout << endl;

system("pause");
return 0;
}


Даны целое n и вещественные числа 13 EMBED Equation.3 1415 Рассматривая пары 13 EMBED Equation.3 1415 как координаты точек на плоскости, определить радиус наименьшего круга (с центром в начале координат), внутрь которого попадают все эти точки.

Решение:

#include
#include
using namespace std;


int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
int n;
cout << "Введите число N: ";
cin >> n;

double max = 0, current;
for (int count = 0; count < n * 2; count++)
{
if (count % 2 == 0)
cout << "Введите координаты " << count / 2 + 1 << " точки: ";
cin >> current;
if (abs(current) > max)
max = abs(current);
}

cout << ceil(max) << endl;

system("pause");
return 0;
}

Напечатать все простые делители натурального числа.

Решение:

#include
using namespace std;
bool isSimple(int number)
{
if (number == 2)
return true;

if (number % 2 == 0)
return false;

int to = number / 2;
for (int Dnum = 3; Dnum < to; Dnum += 2)
if (number % Dnum == 0)
return false;
return true;
}

int main()
{
int number;
cin >> number;

for (int div = 2; div < number / 2; div++)
if ((number % div == 0) && (isSimple(div)))
cout << div << " ";
cout << endl;
system("pause");
return 0;
}








18. Уравнение (предложена М.В. Дякиным).
Дана последовательность 13 EMBED Equation.3 1415, 13 EMBED Equation.3 1415  натуральное число. Квадратные скобки 13 EMBED Equation.3 1415 обозначают в формуле взятие целой части (округление до ближайшего меньшего целого числа). Обозначим 13 EMBED Equation.3 1415.
Написать программу, которая для заданного натурального 13 EMBED Equation.3 1415 13 EMBED Equation.3 1415 решает уравнение 13 EMBED Equation.3 1415,
где 13 EMBED Equation.3 1415 - обозначение числа 13 EMBED Equation.3 1415 - факториал: 13 EMBED Equation.3 1415.
Программа должна найти и сообщить:
1) точное значение x в виде несократимой дроби;
2) сумму цифр числителя и сумму цифр знаменателя этой дроби.
Образец вывода результата:
Число 6, числитель дроби X=10, знаменатель дроби X=63.
Сумма цифр числителя =1, сумма цифр знаменателя =9.

Решение:

#include
#include
using namespace std;
int bigA(int n)
{
int result = 1;
for (int index = 1; index <= n; index++)
result = result * (int(index / 2) + 2 * int(sqrt(index)));

return result;
}
int factorial(int n)
{
int result = 1;
for (int num = 2; num <= n; num++)
result *= num;
return result;
}
int NOD(int first, int second)
{
if (first < second)
swap(first, second);

for (int div = second; div >= 2; div--)
if ((first % div == 0) && (second % div == 0))
return div;

return -1;
}
int sumOfDigits(int number)
{
int result = 0;
while (number != 0)
{
result += number % 10;
number /= 10;
}

return result;
}

int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);

int n;
cout << "Введите число N : ";
cin >> n;

int A = bigA(n), N = factorial(n);
int div = NOD(A, N);
if (div != -1)
{
A /= div;
N /= div;
}
cout << "Число " << N / A << ", числитель дроби X = " << N << ", знаменатель дроби X = " << A << '.' << endl << "Сумма цифр числителя = " << sumOfDigits(N) << ", сумма цифр знаменателя = " << sumOfDigits(A) << ".\n";

system("pause");
return 0;
}

19. Задача «Кучи и яма» (предложена А.Б. Дернятиным).
Имеются яма и несколько куч (не более пяти) кирпичей. Разрешается перекладывать кирпичи из куч в яму по следующему правилу: если количество кирпичей в куче больше, чем в яме, то можно переложить столько кирпичей, сколько находится в яме в данный момент. Требуется разработать алгоритм, который позволяет уложить в яму как можно больше кирпичей.
Образец вывода результатов:
К1=150001 К2=81234 Я=70000 было
К1=150001 К2=11234 Я=140000 в яму из кучи 2й
К1=10001 К2=11234 Я=280000 в яму из кучи 1й

Решение:
#include
#include
#include

using namespace std;

ostream& operator<<(ostream& os, vector& vec)
{
int len = vec.size();
for (int index = 0; index < len; index++)
os << "K" << index + 1 << " = " << vec[index] << " ";
return os;
}
int NextIndex(vector& TestVec, int pit)
{
int len = TestVec.size();
int min = -1, minIndex = -1;


for (int index = 0; index < len; index++)
if (((min == -1) || (min > TestVec[index])) && (TestVec[index] > pit))
{
min = TestVec[index];
minIndex = index;
}

if (minIndex == -1)
return -1;
else
return minIndex;
}

int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);

int NumOfpile;
cout << "Введите количество куч : ";
cin >> NumOfpile;

vector pile(NumOfpile);
int pit;

for (int index = 0; index < NumOfpile; index++)
{
cout << "Введите количество камней в " << index + 1 << "ой куче: ";
cin >> pile[index];
}
cout << "Введите количество камней в яме : ";
cin >> pit;


cout << pile << "Я = " << pit << "\tбыло" << endl;;
int next = NextIndex(pile, pit);
while (next != -1)
{
pile[next] -= pit;
pit *= 2;
cout << pile << "Я = " << pit << "\tв яму из " << next + 1 << "ой кучи." << endl;
next = NextIndex(pile, pit);
}

cout << pit << endl;
system("pause");
return 0;
}


20. Представления натурального числа (предложена Д.Я.Шараевым)
Известно, что любое натуральное число N (0Пример. N=4. S=2. (12+12+12+12=4, 22=4)

Решение:

#include
#include
#include //для std::sort()
#include
using namespace std;
bool find(vector>& vec, vector& ff)
{
int len = vec.size();
for (int index = 0; index < len; index++)
if (vec[index] == ff)
return true;
return false;
}

int main()
{
SetConsoleCP(121);
SetConsoleOutputCP(1251);

int n;
cout << "Введите число N : ";
cin >> n;
vector> Indexz;

int Hn = int(sqrt(n)), index = 0;
for (int index1 = 0; index1 <= Hn; index1++)
for (int index2 = 0; index2 <= Hn; index2++)
for (int index3 = 0; index3 <= Hn; index3++)
for (int index4 = 0; index4 <= Hn; index4++)
if (index4 * index4 + index3 * index3 + index2 * index2 + index1 * index1 == n)
{
vector help;
help.push_back(index1);
help.push_back(index2);
help.push_back(index3);
help.push_back(index4);
sort(help.begin(), help.end());

if (!(find(Indexz, help)))
Indexz.push_back(help);
}

int line = Indexz.size();
cout << "N = " << n << " S = " << line << endl;

for (int index = 0; index < line; index++)
{
for (int jindex = 0; jindex < 4; jindex++)
if (Indexz[index][jindex] != 0)
cout << Indexz[index][jindex] << "^2 + ";
cout << "= " << n << endl;
}
system("pause");
return 0;
}




3.1.5. Алгоритмы работы с рядами
При работе с рядами обычно составляют рекуррентную формулу, которая задает значение i+1-го члена ряда (Y(i+1)) через значения предыдущих членов, чаще  i-го члена ряда (Y(i)). Обычно используют отношение i+1-го члена к i-му члену, подставляют их значения, и после преобразований получается рекуррентная формула.
Пример. Вычислить значение членов бесконечного ряда 13 EMBED Equation.3 1415 точностью до члена 13 EMBED Equation.3 1415. Считать, что требуемая точность (
·) достигнута, если очередное слагаемое по модулю меньше указанной точности и все последующие слагаемые можно уже не учитывать. Определим рекуррентную формулу Y(i+1)/Y(i)=(x(i+1)/(i+1)!)/(xi/i!)=x/i. Получим рекуррентную формулу Y(i+1)=Y(i)*x/(i+1).
Вычислить сумму членов для следующих рядов с точностью до 10-4:
а) 13 EMBED Equation.3 1415

Решение:

typedef unsigned long long ull;
ull fac(int n)
{
ull result = 1;
for (int cou = 2; cou <= n; cou++)
result *= cou;
return result;
}
int n;
cin >> n;

double x;
cin >> x;
long double result = 1 + x;
for (int num = 2; num <= n; num++)
result += (x * x) / fac(num);
cout << "z = " << round(result * 10000) / 10000 /*округление до 4 знаков*/
<< endl;

б) 13 EMBED Equation.3 1415
Для вычисления текущего значения члена ряда использовать рекуррентную формулу 13 EMBED Equation.3 1415, где n  номер члена ряда. Начальное значение у принять равным 13 EMBED Equation.3 1415;
Решение:

int m;
double x;
cin >> x >> m;
double result = 1, lastNumer = m * x, lastDenum = fac(m + 1);
for (int decM = 1, incM = 2; decM < n; decM++, incM++)
{
result += lastNumer / lastDenum;
lastNumer *= x * (m - decM);
lastDenum *= m + incM;
}
cout << "z = " << round(result * 10000) / 10000 /*округление до 4 знаков*/ << endl;

в) 13 EMBED Equation.3 1415;
Решение:

double result = 0;
for (int numer = 1, firstDec = 2, secondDec = 3; numer < n; numer++, firstDec++, secondDec++)
result += numer / (firstDec + secondDec);
cout << "z = " << round(result * 10000) / 10000 /*округление до 4 знаков*/ << endl;

г) 13 EMBED Equation.3 1415;
Решение:

double x;
cin >> x;
double result = cos(x);
for (int mn = 2; mn <= n; mn++)
result += cos(mn * x) / (mn * mn);
cout << "z = " << round(result * 10000) / 10000 /*округление до 4 знаков*/ << endl;

д) 13 EMBED Equation.3 1415;.
Решение:

double x;
cin >> x;
double result = 0;
for (int counter = 1, inc = 1; counter <= n; counter++, inc = counter * 2 + 1)
result += pow(x + 1, inc) / (pow(inc * (x + 1), inc));
cout << "z = " << round(result * 10000) / 10000 /*округление до 4 знаков*/ << endl;

е) 13 EMBED Equation.3 1415;
Решение:

double x;
double result = 0;
for (int to_n = 1, fir = 1, sec = 3; to_n <= n; to_n++, fir += 2, sec += 2)
result += cos(2 * n * x) / (fir * sec);
cout << "z = " << round(result * 10000) / 10000 /*округление до 4 знаков*/ << endl;

ж) 13 EMBED Equation.3 1415.
Решение:

double x;
cin >> x;
double result = pow(x, n);
for (int im = 2; im <= n + 1; im++)
result += (1 / im) * pow(x, n - im);
cout << "z = " << round(result * 10000) / 10000 /*округление до 4 знаков*/ << endl;


Текущий член ряда вычислять, используя рекуррентную формулу.
Составить программу вычисления значений членов убывающей последовательности 13 EMBED Equation.3 1415 с точностью до10-4.

Решение:

double x;
int n;
cin >> n;
cin >> x;

double PrevNum = x, PrevDenum = 1;
cout << x << "^1" << " / (fac(1)) = " << round(x * 10000) / 10000 << endl;
for (int cou = 2; cou <= n; cou++)
{
PrevNum *= x;
PrevDenum *= cou;
cout << x << '^' << cou << " / (fac(" << cou << ")) = " << round(PrevNum / PrevDenum * 10000) / 10000 << endl;
}





Составить программу вычисления членов бесконечного ряда
z =13 EMBED Equation.3 1415
с точностью до10-4.

Решение:

#include
#include

using namespace std;

typedef unsigned long long ull;
ull fac(int n)
{
ull result = 1;
for (int cou = 2; cou <= n; cou++)
result *= cou;
return result;
}

int main()
{
double x, result = 1;
int n;
cin >> n;
cin >> x;
for (int nn = 1; nn <= n; nn++)
result += pow(-1, nn) * (pow(x, 2 * nn) / fac(2 * nn));
cout << round(result * 10000) / 10000 << endl;

system("pause");
return 0;
}

Не используя стандартные функции (за исключением abs), вычислить с точностью до 10-4:
а) 13 EMBED Equation.3 1415
б) 13 EMBED Equation.3 1415
в) 13 EMBED Equation.3 1415
г) 13 EMBED Equation.3 1415



Вычисление f = 10!

Решение:

#include

using namespace std;

typedef unsigned long long ull;
ull fac(int n)
{
ull result = 1;
for (int cou = 2; cou <= n; cou++)
result *= cou;
return result;
}

int main()
{
cout << "fac(10) = " << fac(10) << endl;

system("pause");
return 0;
}

Вычислить:
а) у = cos(x )+ cos(x2) + cos(x3) ++cos(x30);

Решение:

double x, prev;
cin >> x;
prev = x;
double result = 0;
for (int co = 0; co < 30; co++)
{
result += cos(prev);
prev *= x;
}
cout << "y = " << result << endl;

б) у = 1! + 2! + 3! + + n! (n>1);

Решение:

typedef unsigned long long ull;

int n;
cin >> n;

ull prevfac = 1, result = 0;
for (int in = 2; in <= n; in++)
{
result += prevfac;
prevfac *= in;
}
cout << "y = " << result << endl;



в) у  первое из чисел sin(x), sin(sin(x)), sin(sin(sin(x,))), меньшее по модулю 10-4.

Решение:

double x;
cin >> x;
double result = cos(x);
while (abs(result) > 0.0001)
result = cos(result);
cout << "y = " << result << endl;

Числа Фибоначчи («fn») определяются по формулами f0 = f1 = 1;
fn = fn-1 + fn-2 при n = 2, 3, :

а) определить четвертое число Фибоначчи;

Решение:

int first = 1, second = 1;
for (int index = 2; index <= 4; index++)
{
int temp;
temp = second;
second += first;
first = temp;
}
cout << second << endl;

б) вычислить первое число Фибоначчи, большее m (m > 1);

Решение:

int m;
cin >> m;
int first = 1, second = 1;
while (m >= second)
{
int temp;
temp = second;
second += first;
first = temp;
}
cout << second << endl;

в) вычислить s  сумму всех чисел Фибоначчи, которые не превосходят 1000.

Решение:

int sum = 1;
int first = 1, second = 1;
while (second < 1000)
{
sum += second;
int temp;
temp = second;
second += first;
first = temp;
}
cout << sum << endl;

3.1.6. Алгоритмы работы с массивами
Для массива Х, состоящего из 40 элементов, выполнить следующие действия:
а) записать нули в массив;

Решение:

int x[40];
for (int index = 0; index < 40; index++)
x[index] = 0;

б) вывести на печать положительные элементы массива;

Решение:

for (int index = 0; index < 40; index++)
{
x[index] = rand() % (10) - 5;
if (x[index] > 0)
cout << x[index] << " ";
}
cout << endl;

в) вывести на печать первый отрицательный элемент массива и его порядковый номер, полагая, что в массиве есть хотя бы один отрицательный элемент;

Решение:

for (int index = 0; index < 40; index++)
{
x[index] = rand() % (10) - 5;
if (x[index] < 0)
{
cout << "Первый отрицательный элемент = " << x[index]
<< endl << "Его индекс = " << index << endl;
break;
}
}

г) вывести на печать номера элементов, удовлетворяющих условию 0<13 EMBED Equation.3 1415<1;

Решение:

double x[40];
for (int index = 0; index < 40; index++)
cin >> x[index];
for (int index = 0; index < 40; index++)
if ((x[index] > 0) && (x[index] < 1))
cout << x[index] << " ";
cout << endl;

д) записать на место отрицательных элементов массива нули.

Решение:

for (int index = 0; index < 40; index++)
{
x[index] = rand() % (10) - 5;
if (x[index] < 0)
x[index] = 0;
}
for (int index = 0; index < 40; index++)
cout << x[index] << " ";

Вывести на печать элементы целочисленного массива (13 EMBED Equation.3 1415), кратные трем; n 13 EMBED Equation.3 1415 10.

Решение:

#include
using namespace std;
int main()
{
int n;
cin >> n;
int* arr = new int[n];

for (int index = 0; index < n; index++)
{
cin >> arr[index];
if (arr[index] % 3 == 0)
cout << arr[index] << " ";
}
cout << endl;

delete[] arr;

system("pause");
return 0;
}

Вывести на печать номера точек, лежащих в круге с радиусом r. Координаты точек заданы массивами (13 EMBED Equation.3 1415), (13 EMBED Equation.3 1415). Точка принадлежит кругу, если ее расстояние от центра круга не более r.

Решение:

#include
#include
using namespace std;
struct coordinate
{
double x, y;
};

int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);

double r;
coordinate arr[100];
cout << "Введите радиус : ";
cin >> r;
for (int index = 0; index < 100; index++)
{
cout << "Введите X координату " << index + 1 << "ой точки : ";
cin >> arr[index].x;
cout << "Введите Y координату " << index + 1 << "ой точки : ";
cin >> arr[index].y;
}

for (int index = 0; index < 100; index++)
{
if (sqrt(arr[index].x * arr[index].x + arr[index].y * arr[index].y))
cout << index + 1 << " ";
}
cout << endl;

system("pause");
return 0;
}

Составить программу вычисления значения функции z=хуi/(х+ уi), где yi  элементы массива Y {13 EMBED Equation.3 1415}, а аргумент х изменяется одновременно с yi от начального значения а с шагом h.

Решение:

double y[20];
double x, h;
cout << "X = ";
cin >> x;
cout << "h = ";
cin >> h;
for (int index = 0; index < 20; index++)
{
cout << "y[" << index + 1 << "] = ";
cin >> y[index];
}

for (int index = 0; index < 20; index++, x += h)
cout << "z = " << x * y[index] / (x + y[index]) << endl;


Составить программу для вычисления значения функции 13 EMBED Equation.3 1415, где 13 EMBED Equation.3 1415  элемент массива Х = {13 EMBED Equation.3 1415}.

Решение:
double x[20];
for (int index = 0; index < 20; index++)
{
cout << "x[" << index + 1 << "] = ";
cin >> x[index];
}

double z = 0;
for (int index = 0; index < 20; index++)
z += (x[index] * x[index]) / index;
cout << "Z = " << z << endl;
Дана (построчно) вещественная матрица размером 713 EMBED Equation.3 14154. Переставляя ее строки и столбцы, следует добиться того, чтобы наибольший элемент (один из них) оказался в верхнем левом углу.

Решение:

#include
#include
#include

using namespace std;

struct Max
{
double maxElement = 0.0;
int firstIndex = 0, secondIndex = 0;
};
int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
srand(time(0));

double matrix[7][4];
Max maximum;

cout << "Исходная матрица : " << endl;
for (int index = 0; index < 7; index++)
{
for (int jindex = 0; jindex < 4; jindex++)
{
matrix[index][jindex] = rand() % (10); //случайный ввод
//cin >> matrix[index][jindex]; //или так
if (maximum.maxElement < matrix[index][jindex])
{
maximum.maxElement = matrix[index][jindex];
maximum.firstIndex = index;
maximum.secondIndex = jindex;
}
cout << matrix[index][jindex] << " ";
}
cout << endl;
}

cout << endl << "Наибольший элемент матрицы = " << maximum.maxElement << endl << endl;
if (matrix[0][0] != maximum.maxElement) //Если наибольший элемент в верхнем левом углу то больше ничего делать не надо
{
if (maximum.firstIndex != 0) //если наибольший элемент в первой строке то менять строки смысла нет
{
cout << "Меняем первую строку с " << maximum.firstIndex + 1 << " строкой." << endl;
for (int jindex = 0; jindex < 4; jindex++)
swap(matrix[0][jindex], matrix[maximum.firstIndex][jindex]);

for (int index = 0; index < 7; index++)
{
for (int jindex = 0; jindex < 4; jindex++)
cout << matrix[index][jindex] << " ";
cout << endl;
}
}

if (matrix[0][0] != maximum.maxElement) //если после смены строк наибольший элемент в верхнем левом углу то менять столбцы смысла нет
{
cout << "Меняем первый столбец с " << maximum.secondIndex + 1 << " столбцом" << endl;
for (int index = 0; index < 7; index++)
swap(matrix[index][0], matrix[index][maximum.secondIndex]);

for (int index = 0; index < 7; index++)
{
for (int jindex = 0; jindex < 4; jindex++)
cout << matrix[index][jindex] << " ";
cout << endl;
}
}
}

system("pause");
return 0;
}


Определить, является ли заданная целая квадратная матрица
10-го порядка симметричной (относительно главной диагонали).

Решение:

#include
#include
#include
using namespace std;
int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);

double matrix[10][10];
for (int index = 0; index < 10; index++)
for (int jindex = 0; jindex < 10; jindex++)
cin >> matrix[index][jindex];
cout << endl << endl;

for (int index = 0; index < 10; index++)
{
for (int jindex = 0; jindex < 10; jindex++)
cout << matrix[index][jindex] << " ";
cout << endl;
}

bool flag = true;
for (int index = 1; index < 10; index++)
{
for (int jindex = 0; jindex < 10; jindex++)
if (matrix[index][jindex] != matrix[jindex][index])
{
flag = false;
break;
}
if (!flag)
break;
}
if (!flag)
cout << "Матрица не симметрична." << endl;
else
cout << "Матрица симметрична." << endl;

system("pause");
return 0;
}

Элемент матрицы назовем седловой точкой, если он является наименьшим в своей строке и одновременно наибольшим в своем столбце или, наоборот, является наибольшим в своей строке и наименьшим в своем столбце. Для заданной целой матрицы размером 1013 EMBED Equation.3 141515 напечатать индексы всех ее седловых точек.

Решение:

#include
#include
#include
using namespace std;
bool MaxinLine(double mtx[10][15], int findex, int sindex)
{
for (int jindex = 0; jindex < 3; jindex++)
if (jindex == sindex)
continue;
else if (mtx[findex][jindex] >= mtx[findex][sindex])
return false;
return true;
}
bool MaxinColumn(double mtx[10][15], int findex, int sindex)
{
for (int index = 0; index < 3; index++)
if (index == findex)
continue;
else if (mtx[index][sindex] >= mtx[findex][sindex])
return false;
return true;
}
bool MininLine(double mtx[10][15], int findex, int sindex)
{
for (int jindex = 0; jindex < 3; jindex++)
if (jindex == sindex)
continue;
else if (mtx[findex][jindex] <= mtx[findex][sindex])
return false;
return true;
}
bool MininColumn(double mtx[10][15], int findex, int sindex)
{
for (int index = 0; index < 3; index++)
if (index == findex)
continue;
else if (mtx[index][sindex] <= mtx[findex][sindex])
return false;
return true;
}

int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
srand(time(0));

double matrix[10][15];
//for (int index = 0; index < 10; index++)
//{
// for (int jindex = 0; jindex < 15; jindex++)
// {
// //matrix[index][jindex] = rand() % (10);
// cin >> matrix[index][jindex];
// cout << matrix[index][jindex] << ' ';
// }
// cout << endl;
//}
for (int index = 0; index < 10; index++)
for (int jindex = 0; jindex < 15; jindex++)
cin >> matrix[index][jindex];

cout << endl;
for (int index = 0; index < 10; index++)
{
for (int jindex = 0; jindex < 15; jindex++)
{
cout << matrix[index][jindex] << " ";
}
cout << endl;
}

cout << endl << "\"Седловые\" точки: " << endl;
for (int index = 0; index < 10; index++)
for (int jindex = 0; jindex < 15; jindex++)
if (((MaxinLine(matrix, index, jindex)) && (MininColumn(matrix, index, jindex)))
|| ((MininLine(matrix, index, jindex)) && (MaxinColumn(matrix, index, jindex))))
cout << matrix[index][jindex] << " ";
cout << endl;

system("pause");
return 0;
}


Определить, является ли заданная целая квадратная матрица 9-го порядка магическим квадратом, т.е. такой, в которой суммы элементов во всех строках и столбцах одинаковы.

Решение:

#include
#include
#include
using namespace std;
double sumOfLine(double mtx[9][9], int line)
{
double result = 0;
for (int jindex = 0; jindex < 9; jindex++)
result += mtx[line][jindex];
return result;
}
double sumOfColumn(double mtx[9][9], int column)
{
double result = 0;
for (int index = 0; index < 9; index++)
result += mtx[index][column];
return result;
}

int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);

double matrix[9][9];

for (int index = 0; index < 9; index++)
for (int jindex = 0; jindex < 9; jindex++)
matrix[index][jindex] = rand() % (9);

/*for (int index = 0; index < 9; index++)
for (int jindex = 0; jindex < 9; jindex++)
cin >> matrix[index][jindex];*/

cout << "Введенная матрица : " << endl;
for (int index = 0; index < 9; index++)
{
for (int jindex = 0; jindex < 9; jindex++)
{
cout << matrix[index][jindex] << " ";
}
cout << endl;
}
bool flag = true;
double SumL = sumOfLine(matrix, 0);

for (int index = 1; index < 9; index++)
if (SumL != sumOfLine(matrix, index))
{
flag = false;
break;
}
if (flag)
{
double SumC = sumOfColumn(matrix, 0);
for (int jindex = 1; jindex < 9; jindex++)
if (SumC != sumOfColumn(matrix, jindex))
{
flag = false;
break;
}
}

if (flag)
cout << "Матрица - магический квадрат." << endl;
else
cout << "Матрица - не магический квадрат." << endl;

system("pause");
return 0;
}

Составить программу нахождения наибольшего элемента массива Х = {13 EMBED Equation.3 1415}.

Решение:

#include
#include
#include

using namespace std;

int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
double x[40], max;
/*cout << "Массив x[40] = " << endl;
for (int index = 0; index < 40; index++)
{
x[index] = rand() % 10;
if (index == 0)
max = x[index];
else if (max < x[index])
max = x[index];
cout << x[index] << " ";
}*/

for (int index = 0; index < 40; index++)
{
cin >> x[index];
if (index == 0)
max = x[index];
else if (max < x[index])
max = x[index];
}

cout << "Массив x[40] = " << endl;
for (int index = 0; index < 40; index++)
cout << x[index] << " ";
cout << endl;

cout << "Наибольший элемент массива = " << max << endl;

system("pause");
return 0;
}

Дано 100 вещественных чисел. Вычислить разность между максимальным и минимальным из них.

Решение:
#include
#include
#include
using namespace std;
int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
double maximum, minimum, current;
cout << "Последовательность : ";
for (int index = 0; index < 100; index++)
{
current = rand() % 10;
if (index == 0)
{
maximum = current;
minimum = current;
}
else if (current > maximum)
maximum = current;
else if (current < minimum)
minimum = current;
cout << current << ' ';
}

cout << "Разница между максимальным и минимальным элементом последовательности = " << maximum - minimum << endl;
system("pause");
return 0;
}

Дана непустая последовательность различных натуральных чисел, за которой следует 0. Определить порядковый номер наименьшего из них.

Решение:
int indexofMin, currentIndex = 1, current, min = -1;
cin >> current;
while (current != 0)
{
if ((min == -1) || (current < min))
{
min = current;
indexofMin = currentIndex;
}
currentIndex++;
cin >> current;
}

cout << "Индекс наименьшего элемента последовательности - " << indexofMin << endl;

Дана последовательность из 100 целых чисел. Определить три наибольших числа среди них.

Решение:
vector MaxArr;
int current;
for (int index = 0; index < 100; index++)
{
current = rand() % 10;
if (index < 3)
{
MaxArr.push_back(current);
sort(MaxArr.begin(), MaxArr.end());
}
else if (current > MaxArr[0])
{
MaxArr[0] = current;
sort(MaxArr.begin(), MaxArr.end());
}
cout << current << ' ';
}
cout << endl;
cout << MaxArr[0] << ' ' << MaxArr[1] << ' ' << MaxArr[2] << endl;

Дано 200 вещественных чисел. Определить, сколько из них больше своих «соседей», т.е. предыдущего и последующего чисел.

Решение:
vector Th(3);
int result = 0;
for (int index = 0; index < 3; index++)
{
//cin >> Th[index];
Th[index] = rand() % 10;
cout << Th[index] << ' ';
}
for (int index = 3; index < 200 + 1; index++)
{
if ((Th[1] > Th[0]) && (Th[1] > Th[2]))
result++;

Th[0] = Th[1];
Th[1] = Th[2];
if (index != 10)
{
Th[2] = rand() % 10;
//cin >> Th[2];
cout << Th[2] << ' ';
}
}
cout << endl << result << endl;

Задан массив Х = {3,2; 8,5; 20; 40; 8,2}. Написать программу ввода и вывода элементов массива.

Решение:
#include
#include
#include
#include
#include
using namespace std;
int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
srand(time(0));
//Не совсем понял условие задачи
double x[5] = { 3.2, 8.5, 20.0, 40.0, 8.2 };
int command = 3;
while (1)
{
while ((command != 1) && (command != 2))
{
cout << "1 - ввод. 2 - вывод (0 - выйти из программы): ";
cin >> command;
if (command == 0)
{
std::system("pause");
return 1;
}
if (!((command != 1) || (command != 2)))
cout << "Неверный ввод!" << endl;
}
if (command == 1)
{
int index = -1;
while ((index < 0) || (index > 4))
{
cout << "Введите номер элемента, который хотите ввести от 0 до 4 : ";
cin >> index;
if ((index < 0) || (index > 4))
cout << "Неверный ввод!" << endl;
}
cout << "Введите число : ";
cin >> x[index];
}
else
{
int index = -2;
while ((index < 0) || (index > 4))
{
cout << "Введите номер элемента, который хотите вывести от 0 до 4 (-1) - вывести весь массив : ";
cin >> index;
if (index == -1)
break;
if ((index < 0) || (index > 4))
cout << "Неверный ввод!" << endl;
}
if (index == -1)
{
for (int in = 0; in < 5; in++)
cout << x[in] << ' ';
cout << endl;
}
else
cout << x[index] << endl;
}
command = 3;
}

std::system("pause");
return 0;
}

Ввести 20 элементов массива С в диалоговом режиме.

Решение:
double C[20];
for (int index = 0; index < 20; index++)
{
cout << "Введите " << index + 1 << "ый элемент массива: ";
cin >> C[index];
}
cout << "Введенный массив." << endl;
for (int index = 0; index < 20; index++)
cout << C[index] << ' ';
cout << endl;

3.1.7. Обработка символьных данных
Написать программу, которая подсчитывает частоту появления символа А в тексте, состоящем из любого числа строк. Признаком окончания входного набора данных следует считать строку из четырех символов «####».

Решение:
#include
#include
#include
using namespace std;
int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);

string input;
int StopCounter = 0, result = 0;
getline(cin, input);
while (1)
{
int lenghtstr = input.size();
for (int index = 0; index < lenghtstr; index++)
if (input[index] == '#')
{
if (StopCounter == 4)
break;
StopCounter++;
}
else if (input[index] == 'A')
result++;

if (StopCounter == 4)
break;
else
getline(cin, input);
}
cout << result << endl;
system("pause");
return 0;
}

Написать программу редактирования текста, которая заменяет в последовательности символов все восклицательные знаки точками. Признаком окончания вычислений является строка с начальными символами «##».

Решение:

#include
#include
#include
#include
using namespace std;
int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);

vector TextInput;
string CurrentStr;
bool Stop = false;

getline(cin, CurrentStr);
while (1)
{
if ((CurrentStr[0] == '#') && (CurrentStr[1] == '#'))
break;
else
{
int lenghtstr = CurrentStr.size();
for (int index = 0; index < lenghtstr; index++)
if (CurrentStr[index] == '!')
CurrentStr[index] = '.';

TextInput.push_back(CurrentStr);
}
getline(cin, CurrentStr);
}
int Lines = TextInput.size();
for (int index = 0; index < Lines; index++)
cout << TextInput[index] << endl;
system("pause");
return 0;
}

Составить программу определения, является ли заданный текст, правильной записью целого числа (возможно, со знаком).

Решение:

#include
#include
#include
using namespace std;
bool is_digit(char sym)
{
static bool Znak = false;
switch (sym)
{
case '0': return true;
case '1': return true;
case '2': return true;
case '3': return true;
case '4': return true;
case '5': return true;
case '6': return true;
case '7': return true;
case '8': return true;
case '9': return true;
case '-': {
if (!Znak)
{
Znak = true;
return true;
}
else
return false;
}

default: return false;
}
}

int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);

string input;
getline(cin, input);
bool result = true;

int len = input.size();
for (int index = 0; index < len; index++)
if (!is_digit(input[index]))
{
result = false;
break;
}
cout << (result ? "\nВерная запись целого числа." : "\nНЕверная запись целого числа.") << endl;

system("pause");
return 0;
}

Составить программу определения, является ли заданное натуральное число палиндромом, т.е. таким, десятичная запись которого читается одинаково слева направо и справа налево.

Решение:
#include
#include
#include
using namespace std;
int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);

int number;
cin >> number;
int temp = number;
int NEWnumber = 0;
while (temp != 0)
{
NEWnumber = NEWnumber * 10 + temp % 10;
temp /= 10;
}

if (NEWnumber == number)
cout << number << " - палиндром." << endl;
else
cout << number << "- НЕ палиндром." << endl;

system("pause");
return 0;
}
3.1.8. Организация подпрограмм
Написать программу, определяющую частоту появления символов А, В, С и цифры 9 в тексте, состоящем из любого числа строк. Признаком конца набора данных служит строка из пяти символов «13 EMBED Equation.3 1415«. Вычисление частоты повторяемости символа Х в строке текста оформить в виде подпрограммы.

Решение:
#include
#include
#include
using namespace std;
int FindSybm(string& str, char symbol)
{
int result = 0;
int lenght = str.size();
for (int index = 0; index < lenght; index++)
if (str[index] == symbol)
result++;
return result;
}

int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);

string input;
getline(cin, input);
bool stop = false;
int resultA(0), resultB(0), resultC(0), result9(0);

while (1)
{
//Если подразумевается, что внутри очередной строки будет подстрока *****
/*int Ffind = input.find("*****");
if (Ffind != string::npos)
{
input = input.substr(0, Ffind);
resultA += FindSybm(input, 'A');
resultB += FindSybm(input, 'B');
resultC += FindSybm(input, 'C');
result9 += FindSybm(input, '9');
break;
}
else
{
resultA += FindSybm(input, 'A');
resultB += FindSybm(input, 'B');
resultC += FindSybm(input, 'C');
result9 += FindSybm(input, '9');
}*/

//Если подразумевается что очередная строка будет *****
if (input == "*****")
break;
else
{
resultA += FindSybm(input, 'A');
resultB += FindSybm(input, 'B');
resultC += FindSybm(input, 'C');
result9 += FindSybm(input, '9');
}

getline(cin, input);
}
cout << "-------------------------------------------------------" << endl
<< "Количество символов \"A\" = " << resultA << endl
<< "Количество символов \"B\" = " << resultB << endl
<< "Количество символов \"C\" = " << resultC << endl
<< "Количество девяток = " << result9 << endl;

system("pause");
return 0;
}

Составить программу упорядочения трех чисел а, b, c, оформив перестановку двух чисел х и у в виде подпрограммы.

Решение:
#include
using namespace std;
double& MAX(double& first, double& second)
{
if (first < second)
swap(first, second);
return first;
}
int main()
{
double a, b, c;
cin >> a >> b >> c;
MAX(a, MAX(b, c));
cout << a << ' ' << b << ' ' << c << endl;
system("pause");
return 0;
}

Два простых числа называются «близнецами», если они отличаются друг от дуга на 2 (таковы, например, числа 41 и 43). Напечатать все пары «близнецов» из отрезка [3,n], где n  заданное число, большее 2. Определение простого числа оформить подпрограммой.

Решение:
#include
using namespace std;
bool is_simple(int number)
{
if (number % 2 == 0)
return false;
for (int div = 3; div < number / 2; div += 2)
if (number % div == 0)
return false;
return true;
}
int main()
{
int n, prev = 3;
cin >> n;
for (int num = 5; num < n; num += 2)
//четные по-умолчанию НЕ простые. проверять их смысла нет
if (is_simple(num))
{
if (num - prev == 2)
cout << prev << ' ' << num << endl;
prev = num;
}

system("pause");
return 0;
}

Два натуральных числа называются «дружественными», если каждое из них равно сумме всех делителей другого, за исключением его самого (таковы, например, числа 220 и 284). Напечатать все пары «дружественных» чисел, не превосходящих заданное натуральное число. Определение суммы делителей числа оформить подпрограммой.

Решение:

#include
#include
#include
typedef unsigned long long ull;
using namespace std;
int sum_of_div(ull number)
{
int result = 0;
for (int div = 1; div <= number / 2; div++)
if (number % div == 0)
result += div;
return result;
}
int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
ull Inpnumber;
ull copyNum = 0;
cin >> Inpnumber;
for (ull number = 1; number < Inpnumber; number++)
{
ull Hnum = sum_of_div(number);
if ((Hnum != number) && (number == sum_of_div(Hnum)))
{
if (copyNum == Hnum)
continue;

copyNum = number;
cout << number << ' ' << Hnum << endl;
}
}
system("pause");
return 0;
}

3.1.9. Работа с файлами
Написать программу, которая записывает в файл последовательного доступа квадраты и кубы 30 первых натуральных чисел.
Решение:
#include
#include
using namespace std;
int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);

ofstream fout("1.txt");
for (int number = 1; number <= 40; number++)
fout << number << "^2 = " << number * number << " | "
<< number << "^3 = " << number * number * number << endl;
fout.close();
system("pause");
return 0;
}

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

Решение:

#include
#include
#include
#include
using namespace std;
struct Info_about_student
{
string Family;
int Index_of_group;
string Home_Address;
int Room_number;

bool nul = false;
};
istream& operator>>(istream& is, Info_about_student& right)
{
cout << "--------------------------------------" << endl
<< "Фамилия студента: ";
getline(is, right.Family);
if (right.Family == "")
{
right.nul = true;
return is;
}
cout << "Номер группы: ";
cin >> right.Index_of_group;
cout << "Домашний адрес: ";
cin.ignore();
getline(is, right.Home_Address);
cout << "Номер комнаты в общежитии: ";
cin >> right.Room_number;
cin.ignore();
return is;
}
ofstream& operator<<(ofstream& of, Info_about_student& right)
{
of << "Фамилия: " << right.Family << endl
<< "Номер группы: " << right.Index_of_group << endl
<< "Домашний адрес: " << right.Home_Address << endl
<< "Номер комнаты в общежитии: " << right.Room_number << endl
<< "--------------------------------------------------------------" << endl;
return of;
}
int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);

ofstream fout("1.txt");
Info_about_student current;
cin >> current;
while (!current.nul)
{
fout << current;
cin >> current;
}
system("pause");
return 0;
}

Написать программу создания файла «Телефонный справочник» объемом не более 100 абонентов, содержащего следующие сведения об абоненте: фамилия абонента, адрес, номер телефона.

Решение:

#include
#include
#include
#include
using namespace std;
int Nomer_Abonent = 1;
struct abonent
{
string family, nomer, address;
};
istream& operator>>(istream& is, abonent& left)
{
cout << "Ввод " << Nomer_Abonent << " абонента. (осталось не более " << 100 - Nomer_Abonent << ")." << endl;
cout << "Введите фамилию абонента: ";
is >> left.family;
cout << "Введите адрес абонента: ";
is >> left.address;
cout << "Введите номер абонента: ";
is >> left.nomer;
cout << "----------------------------------" << endl;
return is;
}
ofstream& operator<<(ofstream& os, abonent& left)
{
os << Nomer_Abonent++ << ":\t" << left.family << '\t' << left.nomer << '\t' << left.address;
return os;
}
int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);

ofstream fout("Phonebook.txt");
fout << "Номер\tФамилия\tНомер\tАдрес\t" << endl;
abonent current;
char command = 'Y';
while ((command != 'N') && (Nomer_Abonent != 101))
{
cin >> current;
fout << current << endl;
cout << "Вводим дальше (Да - Y, Нет - N): ";
cin >> command;
command = toupper(command);

while ((command != 'Y') && (command != 'N'))
{
cout << "Неверный ввод!" << endl;
cout << "Вводим дальше (Да - Y, Нет - N): ";
cin >> command;
command = toupper(command);
}
}
system("pause");
return 0;
}


3.1.10. Комплексный пример
Данная программа (автор - Шаров Денис) представляет собой совокупность восьми задач. Главная форма состоит из собственно самой формы и 8-ми кнопок управления.
Создание элементов на форме:
Для визуального представления работы программы создадим форму и разместим на ней все необходимые элементы. Воспользуемся для этого панелью элементов (рисунок. 3.1.10.1)

Рисунок 3.1.10.1 Панель элементов

Сама главная форма программы имеет следующий вид (рисунок. 3.1.10.2.)

Рисунок 3.1.10.2. Главная форма программы.

На форме расположено 8 компонентов button в свойсте Text которых указан текст на кнопке для идентификации их для пользователя. Каждая кнопка вызывает дочернюю форму. Для создания дочерней формы необходимо выбрать пункт меню Проект, и выбрать пункт "добавить класс". В появившемся окне седует выбрать вид класса "Форма Windows form" и нажать кнопку "Ок", предворительно указав имя новой формы в соответствующем поле ввода. Каждой форме присваивается уникальное имя. В данной прграмы 8 форм называются соответственно названиям заданий: Chislo, Sekunda, BegStroka, DrawForm, TestMath, Diagram, Transp, morboi. После создания восьмой формы напишем код кнопок для отображения соответсвующих дочерних форм.
Приведем текст исходного кода класса Form1:
#pragma once
#include "Chislo.h" // подключаем форму Chislo
#include "Sekunda.h" // подключаем форму Sekunda
#include "BegStroka.h" // подключаем форму BegStroka
#include "DrawForm.h" // подключаем форму DrawForm
#include "TestMath.h" // подключаем форму TestMath
#include "Diagram.h" // подключаем форму Diagram
#include "Transp.h" // подключаем форму Transp
#include "morboi.h" // подключаем форму morboi

private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
Chislo ^Form2=gcnew Chislo(); //создаем объект класса Chislo Form2
Form2->ShowDialog(); //Выводим форму на экран в виде диалогового окна. Это означает, что главная форма не будет доступна, пока открыта текущая дочерняя
}
Аналогично программируются оставшиеся 7 кнопок.

3.1.10.1. Игра «Угадай число».
Форма "Chislo"
В поле TextBox1 задается число N для формирования случайного положительного целого числа в интервале [0,N], и это число должен угадать игрок. Кнопкой «Загадать» формируется это случайное число. Игрок вводит предполагаемое число в поле textBox2 и нажимает кнопку «Попытка». Если это число больше загаданного, то в поле TextBox3 (Результат) вводится текст подсказки «Перелет». Если это число меньше загаданного, то выводится текст «Недолет». Наконец, при совпадении выводится текст «Угадал». Число использованных попыток выводится в поле TextBox4.
Построение:
Разместим на форме 4 элемента label и в свойстве Text укажем соответствующий текст для идентификации поля при игре. Это будет выглядеть следующим образом:
label1. В свойстве Text укажем «Максимальное загадываемое число N” label2. В свойстве Text укажем «Предполагаемое число” label3. В свойстве Text укажем «Результат” label4. В свойстве Text укажем «Число попыток”.
Для указания условий игры ( максимального загадываемого числа),хода игры и ее результата размеcтим на поле 4 элемента TextBox. Поля Максимальное загадываемое число , которому соответствует TextBox1и Предполагаемое число (TextBox2) останутся без изменений, так как данные в них мы будем вводить собственноручно, а в полях Результат (TextBox3) и Число попыток (TextBox4) укажем свойство Enabled=false, так как программа сама будет выводить результаты игры и внешательсво игрока здесь не понадобится. В дополнении к этому, элементу TextBox4 присвоим свойство Text=0, так как изначально число попыток в начале игры равно 0.
Для того, чтобы программу привести в работу, разместим на форме 4 кнопки и укажим для них соответствующие свойства:
Button1-Text=Загадать;
Button2-Text=Попытка;
Button3 –Text =Очистить;
Button4-Text=Выход.
В конечном итоге форма будет выглядеть следующим образом:

Рисунок 3.1.10.1.1 - Вид формы игры «Угадай число»

Приведем тексты процедур обработки событий:
#pragma once
#include //подключаем библиотеку работы со строками
#include //подключаем библиотеку для работы с псевдослучайными числами
using namespace std; //подключаем пространство имен std для упрощения работы со строками
public ref class Chislo : public System::Windows::Forms::Form
{
public:
int n; //внутри класса Chislo объявим глобальную целочисленную переменную n для хранения загаданного числа
Chislo(void)
{
InitializeComponent();
//
//TODO: добавьте код конструктора
//
}
Процедура обработки клика кнопки "Загадать число":
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
String ^s; //объявление строковой переменной
int i; //объявление целочисленной переменной
s = textBox1->Text; //Запись в переменную s текста из textBox1
srand(time(NULL)); //запуск генератора последовательности псевдослучайных чисел. Точкой отсчета принимается текущее время
try //начало блока обработки исключений. Ниже следует блок, потенциально вызывающий исключение (например, если в текст боксе, а соответственно в переменной s значение 0)
{
i = System::Convert::ToInt32(s); //запись в целочисленную переменную i значения из переменной s
n= rand()%i; //создание псевдослучайного числа от 0 до i в переменной n
}
catch(...) //блок перехвата и обработки исключения
{
MessageBox::Show("ВВЕДЕНЫ НЕКОРЕКТНЫЕ ДАННЫЕ!", "Ошибка!",MessageBoxButtons::OK, MessageBoxIcon::Error); // сообщение об ошибки
return; // выход из процедуры
}
button1->Enabled=false; //блокировка кнопки "загадать число"
button2->Enabled=true; //разблокировка кнопки "попытка"
button3->Enabled=true; //разблокировка кнопки "очистить"
textBox2->Enabled=true; //разблокировка поля ввода textbox2
textBox2->Focus(); //перевод фокуса на поле ввода textbox2
}
Процедура обработки клика кнопки "Попытка":
private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e)
{
int a; //объявление целочисленной переменной
a=Convert::ToInt32(textBox4->Text); //запись в а значения текста textbox4 с явным преобразованием типов
textBox4->Text=Convert::ToString(a+1); //запись в textbox4 значения на единицу большего а
if (Convert::ToInt32(textBox2->Text)==n) { //если текст поля ввода (введенное пользователем число) совпадает с загаданным - n
textBox3->Text="ВЕРНО!!"; //Текст поля ввода textbox3изменяется на "верно"
} else if (Convert::ToInt32(textBox2->Text)>n) //иначе проверяется условие "Если текст textbox2 больше n"
{
textBox3->Text="ПЕРЕЛЕТ"; //Текст поля ввода textbox3изменяется на "перелет"
}else if (Convert::ToInt32(textBox2->Text) {
textBox3->Text="НЕДОЛЕТ"; //Текст поля ввода textbox3изменяется на "недолет"
}
}
Процедура обработки клика кнопки "Очистить":
private: System::Void button3_Click(System::Object^ sender, System::EventArgs^ e)
{
n=0; //обнуления загаданного числа
textBox1->Text="0"; //обнуление первого поля ввода
textBox2->Text="0"; //обнуление второго поля ввода
textBox3->Text=" "; //опустошение третьего поля ввода
textBox4->Text="0"; //обнуление четвертого поля ввода
button1->Enabled=true; //разблокировка кнопки "загадать"
button2->Enabled=false; //блокировка кнопки "попытка"
button3->Enabled=false; //блокировка кнопки "очистить"
textBox2->Enabled=false; //блокировка второго поля ввода
textBox1->Focus(); //перевод фокуса на поле ввода textbox1
}
Процедура обработки клика кнопки "Очистить":
private: System::Void button4_Click(System::Object^ sender, System::EventArgs^ e)
{
this->Close(); //закрытие текущей формы
}
Процедура обработки событий нажатия клавиши в поле ввода textbox1 (для textbox2 аналогично):
private: System::Void textBox1_KeyPress(System::Object^ sender, System::Windows::Forms::KeyPressEventArgs^ e)
{
if (Char::IsDigit(e->KeyChar) == true) return; //если поступившая в обработку клавиша относится к цифрам, выходим из процедуры, пропуская клавишу далее на обработку
if (e->KeyChar == (char)Keys::Back) return; //если поступившая в обработку клавиша относится к клавишам backspace или delete, выходим из процедуры, пропуская клавишу далее на обработку
e->Handled = true; //обход обработки элемента, если клавиша не удовлетворила первым двум условиям (буква)
}

3.1.10.2. Секундомер
Составим программу вывода секундомера. Разместим компоненты на форме. Зададим для таймера значение свойству Interval =1000 миллисекунд (показатель частоты секундомера).



Рисунок 3.1.10.2.1 - Вид формы программы «Секундомер»
Приведем тексты процедур обработки событий:
public ref class Sekunda : public System::Windows::Forms::Form
{
public:
int h;
int m;
int s;
Sekunda(void)
private: System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e) //Процедура обработки события срабатывания таймера через указанный интервал
{
s=s+1;
if (s>59)
{
m=m+1;
s=0;
}
if (m>59)
{
h=m+1;
m=0;
}
textBox1->Text=Convert::ToString(h);
textBox2->Text=Convert::ToString(m);
textBox3->Text=Convert::ToString(s);
}
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) //Процедура обработки клика кнопки "старт"
{
timer1->Enabled=true;
button1->Enabled=false;
button2->Enabled=true;
button3->Enabled=true;
}
private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) //Процедура обработки клика кнопки "финиш"
{
timer1->Enabled=false;
button1->Enabled=true;
button2->Enabled=false;
button3->Enabled=true;
}
private: System::Void button3_Click(System::Object^ sender, System::EventArgs^ e) //Процедура обработки клика кнопки "сброс"
{
h=0; m=0; s=0;
textBox1->Text="0";
textBox2->Text="0";
textBox3->Text="0";
button2_Click(sender,e);
}
private: System::Void button4_Click(System::Object^ sender, System::EventArgs^ e)
//Процедура обработки клика кнопки "выход"
{
this->Close();
}


3.1.10.3. Бегущая строка
Создадим программу вывода бегущей строки, которая выводится в заголовке формы.
На форме программы разместим такие элементы, как:
-TextBox
-hScrollBar (регулятор скорости со свойствами: Minimum=0, Maximum=100)
-Button
-Timer (свойство Interval=100)


Рисунок 3.1.10.3.1 Вид формы «Бегущая трока»

Приведем тексты процедур обработки событий:
#pragma once
#include
using namespace std;
private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e)
{
this->Close();
}
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
if (button1->Text=="Начало")
{
button1->Text="Конец";
textBox1->Enabled=false;
timer1->Enabled=true;
this->Text= textBox1->Text + " ";
}
else
{
button1->Text="Начало";
textBox1->Enabled=true;
timer1->Enabled=false;
}
}
private: System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e)
{
String ^a=this->Text;
Char c;
c=a[0];
this->Text=a->Remove(0,1)+c;
}
private: System::Void hScrollBar1_Scroll(System::Object^ sender, System::Windows::Forms::ScrollEventArgs^ e)
{
timer1->Interval=hScrollBar1->Minimum+hScrollBar1->Maximum-hScrollBar1->Value;
}

3.1.10.4. Рисование на экране
Составим программу для рисования мышкой при нажатой левой кнопке.


Рисунок 3.1.10.4.1 - Форма для рисования

Приведем тексты процедур обработки событий:
#pragma once
#include //подключаем стандартную библиотеку
#include //подключаем библиотеку для работы с псевдослучайными числами
public ref class DrawForm : public System::Windows::Forms::Form
{
public:
int x,y;
private:void clear()
{
int rd=Convert::ToInt32(numericUpDown1->Value),
gr=Convert::ToInt32(numericUpDown2->Value), bl=Convert::ToInt32(numericUpDown3->Value);
Color cl; //переменная типо Color
cl=panel1->BackColor; //запоминаем в переменной cl текущий цвет панели1
this->BackColor=Color::White; //меняем цвет формы на белый
panel1->BackColor=cl; //возвращаем панели её старый цвет
this->BackColor=panel1->BackColor;
panel2->BackColor=Color::FromArgb(rd,gr,bl); //панель два приобретает цвет из трех составляющих
numericUpDown1->Value=0;
numericUpDown2->Value=0;
numericUpDown3->Value=0;
trackBar1->Value=1;
radioButton1->Checked=true;
}
Процедура обработки передвижения мыши по форме:
private: System::Void DrawForm_MouseMove(System::Object^ sender, System:: Windows::Forms::MouseEventArgs^ e)
{
int rd=Convert::ToInt32(numericUpDown1->Value),
gr=Convert::ToInt32(numericUpDown2->Value), bl=Convert::ToInt32(numericUpDown3->Value);
if ( e->Button == System::Windows::Forms::MouseButtons::Left && radioButton1->Checked==true ) //если зажата левая кнопка мыши и включен radioButton1
{
Graphics^ g = Graphics::FromHwnd(this->Handle); //на форме создаем объект класса Graphics
if (trackBar1->Value==1) //если толщина пера равна 1
{
g->DrawLine(gcnew Pen(Color::FromArgb(rd,gr,bl)), x ,y, e->Location.X,e->Location.Y); //рисуем линию из x,y в текущее место расположения курсора
}
else //иначе
{
g->FillEllipse(gcnew SolidBrush(Color::FromArgb(rd,gr,bl)), e->Location.X-1,e->Location.Y-1,trackBar1->Value,trackBar1->Value); //рисуем закрашенный элипс в координатах X-1, Y-1 с радиусом, соответствующем толщине карандаша
}
x=e->Location.X; //запоминаем новые координаты
y=e->Location.Y;
}
}

Процедура обработки зажатия кнопки мыши:
private: System::Void DrawForm_MouseDown(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e)
{
x=e->Location.X; //запоминаем координату мыши Х
y=e->Location.Y; //запоминаем координату мыши Y
}

Процедура обработки изменения значения в numericUpDown1 (остальные аналогично):
private: System::Void numericUpDown1_ValueChanged(System::Object^ sender, System::EventArgs^ e)
{
int rd=Convert::ToInt32(numericUpDown1->Value), gr=Convert::ToInt32(numericUpDown2->Value), bl=Convert::ToInt32(numericUpDown3->Value);
panel2->BackColor=Color::FromArgb(rd,gr,bl);
}

Процедура обработки изменения в radioButton2
private: System::Void radioButton2_CheckedChanged(System::Object^ sender, System::EventArgs^ e)
{
int rd=Convert::ToInt32(numericUpDown1->Value),
gr=Convert::ToInt32(numericUpDown2->Value), bl=Convert::ToInt32(numericUpDown3->Value);
Color cl;
cl=panel1->BackColor;
if ( radioButton2->Checked==true )
{
this->BackColor=Color::FromArgb(rd,gr,bl);
panel1->BackColor=cl;
}
}

Процедура обработки кнопки "очистить"
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
clear();
}

Процедура обработки кнопки "Выход"
private: System::Void button3_Click(System::Object^ sender, System::EventArgs^ e)
{
this->Close();
}

Процедура обработки показа формы на экране:
private: System::Void DrawForm_Shown(System::Object^ sender, System::EventArgs^ e)
{
clear();
}

Процедура обработки кнопки "Справка"
private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e)
{
MessageBox::Show("Автор: Шаров Д. ПИЭ-12. 01.02.2014", "СПРАВКА", MessageBoxButtons::OK, MessageBoxIcon::Asterisk);
}

Процедура обработки кнопки "мне повезет!"
private: System::Void button4_Click(System::Object^ sender, System::EventArgs^ e) {
clear();
numericUpDown1->Value=rand() %255;
numericUpDown2->Value=rand() %255;
numericUpDown3->Value=rand() %255;
radioButton2->Checked=false;
radioButton2->Checked=true;
numericUpDown1->Value=rand()%255;
numericUpDown2->Value=rand()%255;
numericUpDown3->Value=rand()%255;
radioButton1->Checked=true;
trackBar1->Value=rand()%15;

}
3.1.10.5.Тестирование по арифметике
Составим программу тестирования знаний ученика по арифметике. Условия программы:
Кнопкой «Тест» запускается Процедура очистки полей ввода и элементов; запускается счетчик времени; формируются случайные числа, которые выводятся в качестве операндов в виде элементов label1- label8. В элементе label14 находится число секунд, оставшихся до окончания тестирования.
Кнопкой «Проверить» запускается Процедура проверки правильности введенных ответов, и, если ответ ошибочен, оценка снижается на балл и выводится правильный ответ в виде элемента (label9- label12). Счетчик времени останавливается, выводится оценка в label13. Кнопкой «Выход» завершается работа программы.


Рисунок 3.1.10.5.1 - Форма тестирования

Приведем тексты процедур обработки событий:

#pragma once
#include
#include
#include
#include
using namespace std;
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
srand(time(NULL));
label1->Text=Convert::ToString(rand()%100);
label2->Text=Convert::ToString(rand()%100);
label4->Text=Convert::ToString(rand()%100);
label5->Text=Convert::ToString(rand()%100);
label7->Text=Convert::ToString(rand()%10);
label8->Text=Convert::ToString(rand()%10);
label11->Text=Convert::ToString(rand()%9+1);
label10->Text=Convert::ToString(Convert::ToInt32(label11->Text)*(rand()%9+1));
label14->Text="60";
label24->Text="--";
textBox1->Enabled=true;
textBox2->Enabled=true;
textBox3->Enabled=true;
textBox4->Enabled=true;
timer1->Enabled=true;
button1->Enabled=false;
button2->Enabled=true;
}
private: System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e)
{
label14->Text=Convert::ToString(Convert::ToInt32(label14->Text)-1);
if (label14->Text=="0")
{
timer1->Enabled=false;
button2_Click(button2,e);
}
}
private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e)
{
String ^s1,^s2,^s3,^s4;
button1->Enabled=true;
button2->Enabled=false;
label24->Text="5";
label3->Text="ВЕРНО";
label6->Text="ВЕРНО";
label9->Text="ВЕРНО";
label12->Text="ВЕРНО";
textBox1->Enabled=false;
textBox2->Enabled=false;
textBox3->Enabled=false;
textBox4->Enabled=false;
s1=Convert::ToString(Convert::ToUInt32(label1->Text)+Convert::ToUInt32(label2->Text));
s2=Convert::ToString(Convert::ToUInt32(label4->Text)-Convert::ToUInt32(label5->Text));
s3=Convert::ToString(Convert::ToUInt32(label7->Text)*Convert::ToUInt32(label8->Text));
s4=Convert::ToString(Convert::ToUInt32(label10->Text)/Convert::ToUInt32(label11->Text));
if (textBox1->Text!=s1)
{
label3->Text="НЕВЕРНО";
label24->Text=Convert::ToString(Convert::ToUInt32(label24->Text)-1);
}
if (textBox2->Text!=s2)
{
label6->Text="НЕВЕРНО";
label24->Text=Convert::ToString(Convert::ToUInt32(label24->Text)-1);
}
if (textBox3->Text!=s3)
{
label9->Text="НЕВЕРНО";
label24->Text=Convert::ToString(Convert::ToUInt32(label24->Text)-1);
}
if (textBox4->Text!=s4)
{
label12->Text="НЕВЕРНО";
label24->Text=Convert::ToString(Convert::ToUInt32(label24->Text)-1);
}
timer1->Enabled=false;
}

3.1.10.6. Игра «Морской бой»
В форме размещена таблица размером 10 10; ей соответствует массив m(10,10), в котором случайным образом помечены элементы со значением true. Эти элементы задают местоположение кораблей в таблице, которые иг-рок должен потопить, щелкая мышкой по соответствующим ячейкам. Иг¬рок должен задать число всех кораблей перед началом игры в поле numericUpDown1 (“Число вражеских кораблей”).
Создание элементов на форме:
Разместим компоненты: dataGridView1 (со свойствами: Enabled=False, AllowUserToAddRows=false, AllowUserToDeleteRows=false, AllowUserToResizeRows=false, AllowUserToResizeColumns=false), надписи textBox1 (количество потопленных кораблей врага), textBox2 (количество выстрелов), счетчик numericUpDown1 (число вражеских кораблей, Minimum=1, Maximum=100) и две командные кнопки.
Создадим в компоненте dataGridView1 10 столбцов (со свойствами: Width = 25, ReadOnly = true, SortMode = NoSortable) текстового формата и проиндексируем их по порядку английскими буквами (A, B, C, D и т.д.)


Рисунок 3.1.10.6.1 - Вид формы игры «Морской бой»

Приведем тексты процедур обработки событий:
#pragma once
#include
#include
public ref class morboi : public System::Windows::Forms::Form
{
public:
array ^mas; //создаем массив
int cntSht; //создаем счетчик
morboi(void)
{
InitializeComponent();
//
//TODO: добавьте код конструктора
//
mas = gcnew array(10,10); //в созданном массиве генерируем физический массив 10х10
zeromas(); //выполняем процедуру инциализации и очистки массива
}
void zeromas(void)
{
for (int i=0;i<=9;i++)
{
for (int i1=0;i1<=9;i1++)
{
mas[i,i1]=false;
}
}
}
#pragma endregion
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
int k=1,x,y;
srand(time(NULL));
zeromas();
cntSht=0;
numericUpDown1->Enabled=false;
button1->Enabled=false;
textBox1->Text="0";
textBox2->Text="0";
dataGridView1->Enabled=true;
for (int i=0;i<=9;i++)
{
for (int i1=0;i1<=9;i1++)
{
dataGridView1->Rows[i1]->Cells[i]->Value =""; // Convert::ToString(mas[i,i1]);
}
}
while (k<=numericUpDown1->Value)
{
x=rand()%9;
y=rand()%9;
if (mas[x,y]==false)
{
mas[x,y]=true;
k++;
}
}
}
private: System::Void morboi_Load(System::Object^ sender, System::EventArgs^ e)
{
dataGridView1->RowCount=10;
}
private: System::Void dataGridView1_CellClick(System::Object^ sender, System::Windows::Forms::DataGridViewCellEventArgs^ e)
{
int r=e->RowIndex, c=e->ColumnIndex;
if ((e->RowIndex!=-1) && (e->ColumnIndex!=-1))
{
if (dataGridView1->Rows[r]->Cells[c]->Value=="")
{
textBox2->Text=Convert::ToString(Convert::ToInt32(textBox2->Text)+1);
if (r!=-1)
{
if (mas[c, r]==true)
{
dataGridView1->Rows[r]->Cells[c]->Value="X";
cntSht++;
textBox1->Text=Convert::ToString(cntSht);
if (cntSht==numericUpDown1->Value)
{
MessageBox::Show("ПОБЕДА!!!", "Поздравляю!");
numericUpDown1->Enabled=true;
button1->Enabled=true;
dataGridView1->Enabled=false;
}
}
else
{
dataGridView1->Rows[r]->Cells[c]->Value="*";
}
}
}
}
}
private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e)
{
this->Close();
}

3.1.10.7. Вывод диаграммы
Сформируем круговую диаграмму проданных товаров по типам в стоимостном выражении. Разместим пять полей (numericUpDown1-numericUpDown5) для ввода объема продаж товаров по груп¬пам, а так же три кнопки и компонент Chart1. В свойствах компонента Chart1 выберем Series, а укажем ChartType = Pie.

Рисунок 3.1.10.7.1 - .Вид формы с диаграммой.

Приведем тексты процедур обработки событий:
#pragma once
#include
using namespace std;
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
chart1->Series[0]->Points->Clear();
chart1->Series[0]->Points->Add(Convert::ToInt32(textBox1->Text));
chart1->Series[0]->Points->Add(Convert::ToInt32(textBox2->Text));
chart1->Series[0]->Points->Add(Convert::ToInt32(textBox3->Text));
chart1->Series[0]->Points->Add(Convert::ToInt32(textBox4->Text));
chart1->Series[0]->Points->Add(Convert::ToInt32(textBox5->Text));
}
private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e)
{
chart1->Series[0]->Points->Clear();
}
private: System::Void button3_Click(System::Object^ sender, System::EventArgs^ e)
{
this->Close();
}
private: System::Void textBox1_KeyPress(System::Object^ sender, System::Windows::Forms::KeyPressEventArgs^ e)
{
if (Char::IsDigit(e->KeyChar)==true) return;
if (e->KeyChar==(char)Keys::Back) return;
e->Handled=true;
}

3.1.10.8. Перевозка ценных предметов
Нужно перевезти до пяти предметов. Грузоподъемность автомобиля ограничена, а суммарный вес предметов может превышать эту грузоподъемность. Из всех возможных вариантов перевозки нужно выбрать вариант с наибольшей суммарной стоимостью перевозимых предметов суммарным весом в пределах грузоподъемности автомобиля.

Рисунок 3.1.10.8.1 - Вид формы программы «Перевозка грузов»

Приведем тексты процедур обработки событий:
private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e)
{
textBox1->Text="";
textBox2->Text="";
textBox3->Text="";
textBox4->Text="";
textBox5->Text="";
maskedTextBox1->Text="";
maskedTextBox2->Text="";
maskedTextBox3->Text="";
maskedTextBox4->Text="";
maskedTextBox5->Text="";
maskedTextBox6->Text="";
maskedTextBox7->Text="";
maskedTextBox8->Text="";
maskedTextBox9->Text="";
maskedTextBox10->Text="";
maskedTextBox11->Text="";
label1->Text="---";
label2->Text="---";
label3->Text="---";
label4->Text="---";
label5->Text="---";
}
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
int tekst, maxst=0, x1,x2,x3,x4,x5,y1,y2,y3,y4,y5,w,w1,w2,w3,w4,w5,p1,p2,p3,p4,p5;

try
{
w=Convert::ToInt32(maskedTextBox11->Text);
w1=Convert::ToInt32(maskedTextBox1->Text);
w2=Convert::ToInt32(maskedTextBox2->Text);
w3=Convert::ToInt32(maskedTextBox3->Text);
w4=Convert::ToInt32(maskedTextBox4->Text);
w5=Convert::ToInt32(maskedTextBox5->Text),
p1=Convert::ToInt32(maskedTextBox6->Text);
p2=Convert::ToInt32(maskedTextBox7->Text);
p3=Convert::ToInt32(maskedTextBox8->Text);
p4=Convert::ToInt32(maskedTextBox9->Text);
p5=Convert::ToInt32(maskedTextBox10->Text);
}
catch (...)
{
MessageBox::Show("ВВЕДЕНЫ НЕКОРЕКТНЫЕ ДАННЫЕ!", "Ошибка!",MessageBoxButtons::OK, MessageBoxIcon::Error);
return;
}

for (x1=0;x1<=1;x1++)
{
for (x2=0;x2<=1;x2++)
{
for (x3=0;x3<=1;x3++)
{
for (x4=0;x4<=1;x4++)
{
for (x5=0;x5<=1;x5++)
{
if (x1*w1+x2*w2+x3*w3+x4*w4+x5*w5<=w)
{
tekst=x1*p1+x2*p2+x3*p3+x4*p4+x5*p5;
if (maxst<=tekst)
{
maxst=tekst; y1=x1; y2=x2; y3=x3; y4=x4; y5=x5;
}
}
}
}
}
}
}

label1->Text=((y1*p1*w1>0)? "Перевозить":"---");
label2->Text=((y2*p2*w2>0)? "Перевозить":"---");
label3->Text=((y3*p3*w3>0)? "Перевозить":"---");
label4->Text=((y4*p4*w4>0)? "Перевозить":"---");
label5->Text=((y5*p5*w5>0)? "Перевозить":"---");
}
private: System::Void button3_Click(System::Object^ sender, System::EventArgs^ e)
{
this->Close();
}

3.2. Примеры программ на С# (Microsoft Visual Studio 2010)
3.2.1. Игра «Угадай число».
В поле TextBox1 задается число N для формирования случайного положительного целого числа в интервале [0,N], и это число должен угадать игрок. Кнопкой «Загадать» формируется это случайное число. Игрок вводит предполагаемое число в поле textBox3 и нажимает кнопку «Попытка». Если это число больше загаданного, то в поле TextBox3 (Результат) вводится текст подсказки «Перелет». Если это число меньше загаданного, то выводится текст «Недолет». Наконец, при совпадении выводится текст «Угадал». Число использованных попыток выводится в поле TextBox4 (авторы всех программ данного пункта – Боркова Надежда и Смирнова Анастасия).
.
Создание элементов на форме:
Для визуального представления работы программы создадим форму и разместим на ней все необходимые элементы.
Рисунок 3.2.1.1 - Панель элементов

Воспользуемся для этого панелью элементов (Стандартные элементы управления) и разместим на форме 4 элемента Label и в свойстве Text укажем соответствующий текст для идентификации поля при игре.
Это будет выглядеть следующим образом:
Label1. В свойстве Text укажем «Максимальное загадываемое число N;
Label2. В свойстве Text укажем «Предполагаемое число”;
Label3. В свойстве Text укажем «Результат”;
Label4. В свойстве Text укажем «Число попыток”.
Для указания условий игры ( максимального загадываемого числа), хода игры и ее результата размеcтим на поле 4 элемента TextBox. Поля Максимальное загадываемое число , которому соответствует TextBox1и Предполагаемое число (TextBox2) останутся без изменений, так как данные в них мы будем вводить собственноручно, а в полях Результат (TextBox3) и Число попыток (TextBox4) укажем свойство Enabled=false, так как программа сама будет выводить результаты игры и внешательсво игрока здесь не понадобится. В дополнении к этому, элементу TextBox4 присвоим свойство Text=0, так как изначально число попыток в начале игры равно 0.
Для того, чтобы программу привести в работу, разместим на форме 4 кнопки и укажим для них соответствующие свойства:
Button1-Text=Загадать;
Button2-Text=Попытка;
Button3 –Text =Очистить;
Button4-Text=Выход.
В конечном итоге форма будет выглядеть следующим образом:

Рисунок 3.2.1.1.2 - Вид формы игры «Угадай число»

Приведем тексты процедур обработки событий:
namespace ygad_chislo
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
int Ch; //объявляем глобальную переменную Ch типа integer;
private void button1_Click(object sender, EventArgs e)// кнопка «Загадать число»;
{
Random rnd = new Random (DateTime.Now.Millisecond); //объявляем генератор псевдослучайных чисел и указываем для него свойство DateTime.Now.Millisecond, при помощи которого возможно избежать повторения случайных чисел;
Try //оператор try-catch служит для обработки различных исключений;
{
Ch = rnd.Next(1, System.Convert.ToInt32(textBox1.Text));// данный метод возвращает случайное число в указанный диапазон;
}
Catch // при возникновении исключения оператор Catch обрабатывает это исключение;
{
MessageBox.Show("Данные введены некорректно!", "Ошибка",MessageBoxButtons.OK, MessageBoxIcon.Error); // было вызвано исключение выводится сообщение об ошибке;
return; // Выполнение метода при ошибке прекращается;
}
button1.Enabled=false;//так как максимальное загадываемое число мы определили, кнопка «Загадать» нам уже не понадобится, значит ее можно заблокировать;
button2.Enabled=true;// все остальные кнопки останутся доступными на данном этапе
button3.Enabled=true;
textBox2.Enabled=true;
textBox2.Focus(); // Метод  Focus  предоставляет фокус ввода указанному элементу;
}
private void button2_Click(object sender, EventArgs e)// кнопка «Попытка»;
{
int x; // объявляем переменную X типа Integer для данной процедуры;
x=Convert.ToInt32(textBox4.Text); // конвертируем текст в TextBox , после произведенной конвертации записываем этот текст в переменную Х;
textBox4.Text=Convert.ToString(x+1); //увеличиваем переменную X на 1, так как число попыток при каждой попытке угадать увеличивается;
if (Convert.ToInt32(textBox2.Text)==Ch) // если предполагаемое число совпадает с загаданным числом;
{
textBox3.Text="Верно"; // в поле textBox3 («Результат») появится значение «Верно»;
}
else if (Convert.ToInt32(textBox2.Text)>Ch) //если предполагаемое число больше загадываемого числа;
{
textBox3.Text="Перелет"; в поле textBox3 («Результат») появится значение «Перелет»;
}
else if (Convert.ToInt32(textBox2.Text)
{
textBox3.Text="Недолет"; // в поле textBox3 («Результат») появится значение «Недолет»;
}
}
private void button3_Click(object sender, EventArgs e) // кнопка «Очистить». (Данная кнопка очищает поля программы и присваивает им начальные значения);
{
Ch = 0; // загадываемое число станет равным 0;
textBox1.Text = "0"; // значение в поле «Максимальное загадываемое число» станет равным 0;
textBox2.Text = "0"; // значение в поле «Предполагаемое число» станет равным 0;
textBox3.Text = " "; // значение в поле «Результат» станет пустым;
textBox4.Text = "0"; // значение в поле «Число попыток» станет равным 0;
button1.Enabled = true; // кнопка «Загадать» станет доступной;
button2.Enabled = false; // остальные кнопки заблокируются;
button3.Enabled = false;
textBox2.Enabled = false;
textBox1.Focus(); при помощи метода фокус в textBox1 устанавливается каретка ввода;
private void textBox4_KeyPress(object sender, KeyPressEventArgs e)// процедура вызывается при зажатии клавиши и происходит проверка введенного символа на принадлежность к числам;
{
if (Char.IsDigit(e.KeyChar) == true) return; //если введенный символ является числом, то происходим выход из процедуры;
if (e.KeyChar == (char)Keys.Back) return; // если пользователь нажал на клавишу Backspace, то выходим из процедуры;
e.Handled = true;// обход обработки элемента, если введенный символ является буквой;
}
private void button4_Click(object sender, EventArgs e) // кнопка «Выход»;
{
this. Close(); // завершаем работу с приложением.
}

}
}

3.2.2. Секундомер
Составим программу вывода секундомера.
Разместим компоненты на форме. Зададим для таймера значение свойству Interval =1000 миллисекунд (показатель точности секундомера).


Рисунок 3.2.2.1 - Вид формы программы «Секундомер»
Приведем тексты процедур обработки событий:
namespace secundomer
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
int h;
int m;
int s;
private void button1_Click(object sender, EventArgs e) // кнопка «Старт»;
{
timer1.Enabled = true;
button1.Enabled = false;
button2.Enabled = true;
button3.Enabled = true;
}

private void button2_Click(object sender, EventArgs e) // кнопка «Финиш»;
{
timer1.Enabled = false;
button1.Enabled = true;
button2.Enabled = false;
button3.Enabled = true;
}
private void button3_Click(object s ender, EventArgs e) // кнопка «Сброс»;
{
h = 0; m = 0; s = 0;
label1.Text = "0";
label2.Text = "0";
label3.Text = "0";
button2_Click(sender, e); // Событие Click вызывается при нажатии элемента управления Button;
}
private void timer1_Tick(object sender, EventArgs e) // событие происходит по истечении заданного интервала таймера при условии, что таймер включен;
{
s=s+1;// происходит суммирование пройденных секунд при включенном таймере;
if (s>59)
{
m=m+1; // если количество пройденных секунд превысило 59, начинается подсчет минут;
s=0; // количество секунд приравнивается к 0, так как секундомер начинает отсчитывать их снова;
}
if (m>59)
{
h=m+1; // если количество пройденных минут превысило 59, начинается подсчет часов
m=0; // количество минут приравнивается к нулю
}
label1.Text=Convert.ToString(h);
label2.Text=Convert.ToString(m);
label3.Text=Convert.ToString(s);
}
private void button4_Click(object sender, EventArgs e) // кнопка «Выход»
{
this.Close();
}

}
}

3.2.3. Бегущая строка
Создадим программу вывода бегущей строки, которая выводится в заголовке формы.
На форме программы разместим такие элементы, как:
-TextBox
-hScrollBar (регулятор скорости со свойствами: Minimum=0, Maximum=100)
-Button
-Timer (свойство Interval=100)


Рисунок 3.2.3.1 - Вид формы «Бегущая строка»

Приведем тексты процедур обработки событий:
namespace бегущая_строка
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void timer1_Tick(object sender, EventArgs e)
{
timer1.Interval = hScrollBar1.Minimum + hScrollBar1.Maximum - hScrollBar1.Value;//задаем интервал появления текста
this.Text=this.Text.Remove(0, 1)+this.Text[0]; // сцепляем символы текста в прокрутке
}
private void button1_Click(object sender, EventArgs e) // кнопка «Начать»/ «Закончить»;
{
if (button1.Text == "Начать") // Если button1 обладает свойством Text «Начать»
{
timer1.Enabled = true; объект [ Cкачайте файл, чтобы посмотреть ссылку ] вызывает событие прокрутки текста;
this.Text = textBox1.Text + " "; // происходит прокрутка текста, введенного в TextBox с разделением между повторами
button1.Text = "Закончить"; // происходит переименование кнопки, так как прокрутка текста уже запущена;
}
else
{
timer1.Enabled = false; // объект Timer не вызывает событие прокрутки текста
button1.Text = "Начать"; // происходит переименование кнопки для того, чтобы запустить работу программы (прокрутку текста);
}
}
private void button2_Click(object sender, EventArgs e)// кнопка «Выход»
{
this.Close();
}
}
}

3.2.4. Рисование на экране
Составим программу для рисования мышкой при нажатой левой кнопке.


Рисунок 3.2.4.1 - Форма для рисования

Приведем тексты процедур обработки событий:
namespace risovalka
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
int x, y;
private void button3_Click(object sender, EventArgs e)
{
this.Close();
}
private void Otchistit()
{
int red=Convert.ToInt32(numericUpDown1.Value), green=Convert.ToInt32(numericUpDown2.Value), blue=Convert.ToInt32(numericUpDown3.Value);
Color tsvet;
tsvet=panel1.BackColor;
this.BackColor=Color.White; // присваиваем белый цвет панели 1;
panel1.BackColor=tsvet;
this.BackColor=panel1.BackColor;// задается определенный цвет панели 1;
panel2.BackColor=Color.FromArgb(red,green,blue); // задается определенный цвет путем смешения 3 цветов: красного, зеленого и синего;
numericUpDown1.Value=0;
numericUpDown2.Value=0;
numericUpDown3.Value=0;
numericUpDown4.Value=1;
}
private void button1_Click(object sender, EventArgs e)
{
Otchistit();
}
private void button2_Click(object sender, EventArgs e)
{
MessageBox.Show("Работу выполнила: Ковалева Надежда ПИЭ-12", "Автор работы", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
}

private void Form1_MouseMove(object sender, MouseEventArgs e) // описание алгоритма движения мыши;
{
int red=Convert.ToInt32(numericUpDown1.Value), green=Convert.ToInt32(numericUpDown2.Value), blue=Convert.ToInt32(numericUpDown3.Value);
if ( e.Button == System.Windows.Forms.MouseButtons.Left && radioButton2.Checked==true ) // если нажата левая кнопка мыши и выбран цвет карандаша;
{

Graphics g = Graphics.FromHwnd(this.Handle); // происходит рисование карандашом определенного цвета на панели ;
if (numericUpDown4.Value==1)
{
g.DrawLine(new Pen (Color.FromArgb(red,green,blue)), x , y, e.Location.X, e.Location.Y); // рисуем линии карандашом нового(другого) цвета, определяем местоположении на панели начала и конца линии;
}
else
{
g.FillEllipse (new SolidBrush(Color.FromArgb(red,green,blue)), e.Location.X-1,e.Location.Y-1,Convert.ToInt32(numericUpDown4.Value), Convert.ToInt32(numericUpDown4.Value));// чтобы образовалась точка,заливаем внутренние части эллипа таким же цветом. ( Определенная последовательность точек образует в дальнейшем нарисованную линию)
}
x=e.Location.X;
y=e.Location.Y; // определяется положение точек на панели;
}
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
x = e.Location.X;
y = e.Location.Y;
}
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
int red=Convert.ToInt32(numericUpDown1.Value), green=Convert.ToInt32(numericUpDown2.Value), blue=Convert.ToInt32(numericUpDown3.Value);
Color tsvet;
tsvet=panel1.BackColor;
if ( radioButton1.Checked==true )
{
this.BackColor=Color.FromArgb(red,green,blue);
panel1.BackColor=tsvet; // определяем цвет панели;
}
}
private void numericUpDown3_ValueChanged(object sender, EventArgs e)
{
int rd=Convert.ToInt32(numericUpDown1.Value), gr=Convert.ToInt32(numericUpDown2.Value), bl=Convert.ToInt32(numericUpDown3.Value);
panel2.BackColor=Color.FromArgb(rd,gr,bl); // изменяем цвет карандаша;
}
}
}
3.2.5. Тестирование по арифметике
Составим программу тестирования знаний ученика по арифметике. Условия программы:
Кнопкой «Тест» запускается процедура очистки полей ввода и элементов; запускается счетчик времени; формируются случайные числа, которые выводятся в качестве операндов в виде элементов Label1-Label8. В элементе Label 14 находится число секунд, оставшихся до окончания тестирования. Кнопкой «Проверить» запускается процедура проверки правильности введенных ответов, и, если ответ ошибочен, оценка снижается на балл и выводится правильный ответ в виде элемента (Label9-label12). Счетчик времени останавливается, выводится оценка в Label 13. Кнопкой «Выход» завершается работа программы.


Рисунок 3.2.5.1 - Форма тестирования

Приведем тексты процедур обработки событий:
namespace тест_по_арифметике
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Random rnd = new Random(DateTime.Now.Millisecond);
label1.Text = Convert.ToString(rnd.Next(0, 100));
label5.Text = Convert.ToString(rnd.Next(0, 100));
label2.Text = Convert.ToString(rnd.Next(0, 100));
label6.Text = Convert.ToString(rnd.Next(0, 100));
label3.Text = Convert.ToString(rnd.Next(0, 10));
label7.Text = Convert.ToString(rnd.Next(0, 10));
label8.Text = Convert.ToString(rnd.Next(1, 10));
label4.Text = Convert.ToString(rnd.Next(1, 10) * Convert.ToInt32(label8.Text));
label14.Text = "60";
label13.Text = "--";
textBox1.Enabled = true;
textBox2.Enabled = true;
textBox3.Enabled = true;
textBox4.Enabled = true;
timer1.Enabled = true;
button1.Enabled = false;
button2.Enabled = true;
}
private void button3_Click(object sender, EventArgs e)
{
this.Close();
}

private void timer1_Tick(object sender, EventArgs e)
{
label14.Text = Convert.ToString(Convert.ToInt32(label14.Text) - 1);
if (label14.Text == "0")
{
timer1.Enabled = false;
button2_Click(button2, e);
}
}
private void button2_Click(object sender, EventArgs e)
{
String s1, s2, s3, s4;
button1.Enabled = true;
button2.Enabled = false;
label13.Text = "5";
label9.Text = "Правильно";
label10.Text = "Правильно";
label11.Text = "Правильно";
label12.Text = "Правильно";
textBox1.Enabled = false;
textBox2.Enabled = false;
textBox3.Enabled = false;
textBox4.Enabled = false;
s1 = Convert.ToString(Convert.ToInt32(label1.Text) + Convert.ToInt32(label5.Text));
s2 = Convert.ToString(Convert.ToInt32(label2.Text) - Convert.ToInt32(label6.Text));
s3 = Convert.ToString(Convert.ToInt32(label3.Text) * Convert.ToInt32(label7.Text));
s4 = Convert.ToString(Convert.ToInt32(label4.Text) / Convert.ToInt32(label8.Text));
if (textBox1.Text != s1)
{
label9.Text="Ошибка";
label13.Text=Convert.ToString(Convert.ToUInt32(label13.Text)-1);
}
if (textBox2.Text!=s2)
{
label10.Text="Ошибка";
label13.Text=Convert.ToString(Convert.ToInt32(label13.Text)-1);
}
if (textBox3.Text!=s3)
{
label11.Text="Ошибка";
label13.Text=Convert.ToString(Convert.ToInt32(label13.Text)-1);
}
if (textBox4.Text!=s4)
{
label12.Text="Ошибка";
label13.Text=Convert.ToString(Convert.ToInt32(label13.Text)-1);
}
timer1.Enabled=false;
}
}
};

3.2.6. Игра «Морской бой»
В форме размещена таблица размером 1013EMBED Equation.3141510; ей соответствует массив m(10,10), в котором случайным образом помечены элементы со значением true. Эти элементы задают местоположение кораблей в таблице, которые игрок должен потопить, щелкая мышкой по соответствующим ячейкам. Игрок должен задать число всех кораблей перед началом игры в поле numericUpDown1 (“Число вражеских кораблей”).
Создание элементов на форме:
Разместим компоненты: dataGridView1 (со свойствами: Enabled=False, AllowUserToAddRows=false, AllowUserToDeleteRows=false, AllowUserToResizeRows=false, AllowUserToResizeColumns=false), надписи label1 (количество потопленных кораблей врага), label2 (количество выстрелов), счетчик numericUpDown1 (число вражеских кораблей, Minimum=1, Maximum=100) и две командные кнопки.
Создадим в компоненте dataGridView1 10 столбцов (со свойствами: Width = 25, ReadOnly = true, SortMode = NoSortable) текстового формата и проиндексируем их по порядку английскими буквами (A, B, C, D и т.д.)
В описании класса формы объявляем глобальные переменные
bool [,] m = new bool [10,10]; // объявим массив инициации кораблей на игровое поле;
int i; // объявим переменную-счетчик;

Рисунок 3.2.6.1 - Вид формы игры «Морской бой»

Приведем тексты процедур обработки событий:
private void Form1_Load(object sender, EventArgs e)
{
dataGridView1.DefaultCellStyle.BackColor = Color.FromArgb(0, 140, 240); //Устанавливаем цвет ячейки таблицы;
dataGridView1.DefaultCellStyle.SelectionBackColor = Color.FromArgb(26,71,128);
// Устанавливаем цвет выбранной ячейки
for (i = 0; i < dataGridView1.Columns.Count; i++)
{
dataGridView1.RowCount++; // Добавляем строку;
dataGridView1.Rows[i].HeaderCell.Value = Convert.ToString(i+1); // индексируем заголовок строки;
}
}
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex != -1) // определяем, что пользователь кликнул не по заголовку столбца;
{
if (dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value == "") // если ячейка пустая;
if (m[e.ColumnIndex, e.RowIndex] == true) //если в текущей ячейки есть корабль
{
label1.Text = Convert.ToString(Convert.ToInt32(label1.Text) + 1); // увеличиваем количество выстрелов на 1;
dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = "X"; // помечаем ячейку как «потопленную»;
label2.Text = Convert.ToString(Convert.ToInt32(label2.Text) + 1); // увеличиваем количество потопленных кораблей на 1
if (Convert.ToInt32(label2.Text) == numericUpDown1.Value) // если количество потопленных кораблей равно заданному количеству;
{
MessageBox.Show("Вы победили!"); // выводим соообщение о победе;
numericUpDown1.Enabled = true; // разблокриуем окно ввода;
button1.Enabled = true; // разблокируем командную кнопку;
dataGridView1.Enabled = false; // блокируем таблицу;
}
}
else
dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = "*"; //если корабля в ячейке нет, то помечаем её *;
}
}
private void button1_Click(object sender, EventArgs e)
{
int a,x,y; //объявляем счетчики
Random r = new Random(); // создаем генератор случайных чисел;
numericUpDown1.Enabled = false; // блокируем поле ввода;
button1.Enabled = false; // блокируем кнопку;
dataGridView1.Enabled = true; // разблокируем таблицу;
for (i = 0; i < 10; i++)
for (a = 0; a < 10; a++)
dataGridView1.Rows[i].Cells[a].Value = ""; // очищаем таблицу;
for (i = 0; i < numericUpDown1.Value; i++)
{
x = r.Next(0, 10); // создаем случайное число x;
y = r.Next(0, 10); // создаем случайное число y;
if (m[x, y] != true) // если ячейка не имеет значение true;
m[x, y] = true; // ставим ячейке массива значение true;
else i--; // иначе, возвращаемся на шаг назад;
}
i = 0; // обнуляем счетчик;
}
private void button2_Click(object sender, EventArgs e)
{
this.Close(); // завершаем работу приложения;
}

3.2.7. Вывод диаграммы
Сформируем круговую диаграмму проданных товаров по типам в стоимостном выражении.
Разместим пять полей (numericUpDown1-numericUpDown5) для ввода объема продаж товаров по группам, а так же три кнопки и компонент Chart1. В свойствах компонента Chart1 выберем Series, а укажем ChartType = Pie.

Рисунок 3.2.7.1 - Вид формы с диаграммой.

Приведем тексты процедур обработки событий:
private void button1_Click(object sender, EventArgs e)
{
chart1.Series[0].Points.Clear(); //очищаем поле диаграммы

chart1.Series[0].Points.Add(Convert.ToInt32(numericUpDown1.Value)); // создаем первый сектор с размером, соответсвующим параметру Value объекта numericUpDown1;
chart1.Series[0].Points.Add(Convert.ToInt32(numericUpDown2.Value)); // создаем второй сектор с размером, соответсвующим параметру Value объекта numericUpDown2;
chart1.Series[0].Points.Add(Convert.ToInt32(numericUpDown3.Value)); // создаем третий сектор с размером, соответсвующим параметру Value объекта numericUpDown3;
chart1.Series[0].Points.Add(Convert.ToInt32(numericUpDown4.Value)); //создаем четвертый сектор с размером, соответсвующим параметру Value объекта numericUpDown4
chart1.Series[0].Points.Add(Convert.ToInt32(numericUpDown5.Value)); // создаем пятый сектор с размером, соответсвующим параметру Value объекта numericUpDown5;

chart1.Series[0].Points[0].Color = Color.Red; // красим первый сектор в красный цвет;
chart1.Series[0].Points[0].LegendText = label1.Text; // указываем название сектора в легенде;
chart1.Series[0].Points[1].Color = Color.Black; // красим второй сектор в черный цвет
chart1.Series[0].Points[1].LegendText = label2.Text; // указываем название сектора в легенде;
chart1.Series[0].Points[2].Color = Color.Green; // красим третий сектор в зеленый цвет;
chart1.Series[0].Points[2].LegendText = label3.Text; // указываем название сектора в легенде;
chart1.Series[0].Points[3].Color = Color.Yellow; // красим четвертый сектор в желтый цвет;
chart1.Series[0].Points[3].LegendText = label4.Text; //указываем название сектора в легенде;
chart1.Series[0].Points[4].Color = Color.Pink; // красим пятый сектор в розовый цвет;
chart1.Series[0].Points[4].LegendText = label5.Text; // указываем название сектора в легенде;
}
private void button2_Click(object sender, EventArgs e)
{
chart1.Series[0].Points.Clear(); // очищаем поле диаграммы
numericUpDown1.Value = 0; // присваиваем объекту numericUpDown1 значение 0;
numericUpDown2.Value = 0; // присваиваем объекту numericUpDown2 значение 0;
numericUpDown3.Value = 0; // присваиваем объекту numericUpDown3 значение 0;
numericUpDown4.Value = 0; // присваиваем объекту numericUpDown4 значение 0 ;
numericUpDown5.Value = 0; // присваиваем объекту numericUpDown5 значение 0;
private void button3_Click(object sender, EventArgs e)
{
this.Close(); // выходим из программы;
}

3.2.8. Перевозка ценных предметов
Нужно перевезти до пяти предметов. Грузоподъемность автомобиля ограничена, а суммарный вес предметов может превышать эту грузоподъемность. Из всех возможных вариантов перевозки нужно выбрать вариант с наибольшей суммарной стоимостью перевозимых предметов суммарным весом в пределах грузоподъемности автомобиля.

Рисунок 3.2.8.1 - Вид формы программы «Перевозка грузов»
Приведем тексты процедур обработки событий:
namespace Perevozka_gryzov
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button2_Click(object sender, EventArgs e)
{
int x1, x2, x3, x4, x5, p1, p2, p3, p4, p5, w1, w2, w3, w4, w5, y1, y2, y3, y4, y5, st, max, tw;
y1 = 0;
y2 = 0;
y3 = 0;
y4 = 0;
y5 = 0;
p1=Convert.ToInt32(textBox12.Text);
p2=Convert.ToInt32(textBox13.Text);
p3=Convert.ToInt32(textBox14.Text);
p4=Convert.ToInt32(textBox15.Text);
p5=Convert.ToInt32(textBox16.Text);
w1=Convert.ToInt32(textBox6.Text);
w2=Convert.ToInt32(textBox7.Text);
w3=Convert.ToInt32(textBox8.Text);
w4=Convert.ToInt32(textBox9.Text);
w5=Convert.ToInt32(textBox10.Text);
max=0;
tw=Convert.ToInt32(textBox11.Text);
for(x1=0;x1<=1;x1++)
for(x2=0;x2<=1;x2++)
for(x3=0;x3<=1;x3++)
for(x4=0;x4<=1;x4++)
for(x5=0;x5<=1;x5++)
if (x1*w1+x2*w2+x3*w3+x4*w4+x5*w5<=tw)
{
st=x1*p1+x2*p2+x3*p3+x4*p4+x5*p5;
if(st>max)
{
max=st; y1=x1;y2=x2;y3=x3;y4=x4;y5=x5;
}
}
label6.Text = ((y1 > 0) ? "Перевозить": "Не перевозить");
label7.Text = ((y2 > 0) ? "Перевозить": "Не перевозить");
label8.Text = ((y3 > 0) ? "Перевозить": "Не перевозить");
label9.Text = ((y4 > 0) ? "Перевозить": "Не перевозить");
label10.Text = ((y5 > 0) ? "Перевозить": "Не перевозить");
}
private void button1_Click(object sender, EventArgs e)
{
textBox1.Text = "";
textBox2.Text = "";
textBox3.Text = "";
textBox4.Text = "";
textBox5.Text = "";
textBox6.Text = "0";
textBox7.Text = "0";
textBox8.Text = "0";
textBox9.Text = "0";
textBox10.Text = "0";
textBox11.Text = "0";
textBox12.Text = "0";
textBox13.Text = "0";
textBox14.Text = "0";
textBox15.Text = "0";
textBox16.Text = "0";
}
private void textBox16_KeyPress(object sender, KeyPressEventArgs e)
{
if (Char.IsDigit(e.KeyChar) == true) return;
if (e.KeyChar == (char)Keys.Back) return;
e.Handled = true;
}
private void button3_Click(object sender, EventArgs e)
{
this.Close();
}

}
}


3.2.9. Калькулятор срочных вкладов
Реализуем программу, которая подсчитывает доход вкладчика банка за определенный период времени (Рис. 1.). Относительно выбранного банка, процентная ставка меняется. Обычным условие банка является сумма вклада и сроки, который пользователь устанавливает сам.



Рисунок 3.2.9.1 - Вид формы

Разместим компоненты RadioButton (3 шт.), label (5шт.), TextBox (2шт), PictureBox, DataGridView , Button(2шт.), Chart (1шт)

Приведем тексты процедур программы:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace BANK_INCOM//Название вашей программы
{
public partial class Form1 : Form
{
string bank_name;//Название банка
string bank_info;//Информация о банке
double rate;//Процентная ставка банка
double deposite = 0;//Сумма вклада
int date = 0;//Количество месяцев вклада
double incum = 0;//Доход с вклада
double summ = 0;//Сумма вклада с процентами

DataRow row;//Переменная в которую мы будем записывать строки для таблицы
public Form1()
{
InitializeComponent();//Инициализация компонентов
radioButton1.Checked = true;
//Далее даем имена элементам нам необходимым
label3.Text = "Количество месяцев";
//Кнопки
button1.Text = "Подсчет";
button2.Text = "Сброс";
//радио-кнопки
radioButton1.Text = "8%";
radioButton2.Text = "10%";
radioButton3.Text = "12%";
//Текстовые поля
label5.Text = "Сумма по вкладу";
label4.Text = "Заполните поля для подсчета";
//Название графика
chart1.Titles.Add("Сумма процентов по вкладу в рублях");
//Отключаем легенду
chart1.Series["Series1"].IsVisibleInLegend = false;
}

private void Form1_Load(object sender, EventArgs e)
{
radioButton1.AutoCheck = true;//при загрузке формы автоматически включена 1 радио-кнопка
//Создаем таблицу

}

private void button1_Click(object sender, EventArgs e)
{//Обработчик события клика кнопки 1
try//выполнить
{
DataTable table = new DataTable();
table.Clear();
deposite = Convert.ToDouble(textBox1.Text);
date = Convert.ToInt32(textBox2.Text);
incum = (deposite * (date * 30)/365 * (rate));
summ = deposite + incum;
label4.Text =
"Вклад: " + deposite +
"\nМесяцы: " + date +
"\nСтавка: " + rate +
"\nДоход: " + Convert.ToInt32(incum) +
"\nСумма: " + Convert.ToInt32(summ);
label1.Text = bank_name;
label2.Text = bank_info;
//2 колонки Месяц и доход
table.Columns.Add("Месяц");
table.Columns.Add("Проценты");
double AVG = 0;
for (int i = 1; i < date+1; i++)
{
AVG = ((deposite * 30/365 * rate*100) /i);
row = table.NewRow();
row["Месяц"] = i; row["Проценты"] = Convert.ToInt32(AVG);
table.Rows.Add(row);
}
///Составленную таблицу указываем в качестве источника данных
chart1.DataSource = table;
//По горизонтали указываем месяца
chart1.Series["Series1"].XValueMember = "Месяц";
//По вертикали указываем Текущую сумму вклада
chart1.Series["Series1"].YValueMembers = "Проценты";

//привязка графика к источнику данных
chart1.DataBind();
dataGridView1.DataSource = table;
}
catch (Exception)
{//Если что-то пошло не так
label4.Text = "Поля заполнены не корректно";
}
}
///
/// Обработчики событий клика на радио-кнопки
/// Имя банка
/// Процентная ставка
/// Информация о банке (можно дописать для разнообразия)
/// Логотип банка
///


private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
bank_name = "Альфа";
rate = 0.08;
bank_info = "Процент по вкладу:" + rate * 100 + "% годовых";
label1.Text = bank_name;
label2.Text = bank_info;
}

private void radioButton2_CheckedChanged(object sender, EventArgs e)
{
bank_name = "Бета";
rate = 0.1;
bank_info = "Процент по вкладу:" + rate * 100 + "% годовых";
label1.Text = bank_name;
label2.Text = bank_info;
}

private void radioButton3_CheckedChanged(object sender, EventArgs e)
{
bank_name = "Гамма";
rate = 0.12;
bank_info = "Процент по вкладу:" + rate * 100 + "% годовых";
label1.Text = bank_name;
label2.Text = bank_info;
}

private void button2_Click(object sender, EventArgs e)
{//Очистить поле с результатом
label4.Text = "";
}
}
}

3.2.10. Игра “Крестики-Нолики “

Составим программу игры Крестики-Нолики (рисунок. 3.2.10.1).


Рисунок 3.2.10.1 - Вид формы

Разместим на форме следующие компоненты: игровое поле (9 кнопок), кнопка "Start"(для рестарта игры), 3 текстовых поля ( указатель хода, номер игры, счет игры).

Объявление глобальных переменных:
public partial class Form1 : Form
        {
            int i; //счетчик ходов
            int num_game = 0; // номер игры
            int Ovin = 0; // количество побед О
            int Xvin = 0; // количество побед Х
            string[] arr = new string[10]; // массив, который хранит расположение Х и О на игровом поле
            string t = "X"; // переменная которая показывает чей ход происходит
        }

Основная часть программы:

        public string Game(int j) // принимает номер клетки поля
        {
            string fakeT; // переменная следующего хода
            if (i % 2 == 1) // узнает чей ход сделан (Х - непарный ход)
            {
                t = "X";
                fakeT = "O";
            }
            else {
                t = "O";
                fakeT = "X";
            }
            fakeT = "Ходит " + fakeT;
            arr[j] = t;
            i += 1;

            label1.Text = fakeT;// пишет следующего игрока который ходит
         
                   return t; // возвращает отметку на поле Х или О

        }

 public void who_vin()
        {
            if ((arr[1] == "X" & arr[2] == "X" & arr[3] == "X") | (arr[1] == "X" & arr[5] == "X" & arr[9] == "X") | (arr[1] == "X" & arr[4] == "X" & arr[7] == "X") | (arr[2] == "X" & arr[5] == "X" & arr[8] == "X") | (arr[3] == "X" & arr[6] == "X" & arr[9] == "X") | (arr[3] == "X" & arr[5] == "X"& arr[7] == "X") | (arr[4] == "X" & arr[5] == "X" & arr[6] == "X") | (arr[7] == "X" & arr[8] == "X" & arr[9] == "X"))
            { // побеждает Х
                Xvin += 1; // начисляем ему победу
                label3.Text = "X : O\n" + Xvin.ToString() + " : " + Ovin.ToString(); // обновляем табло побед
                MessageBox.Show(" X Победил!"); // выводим окно, которое сообщает о победе
                refresch();// чистим поле, начинаем новую игру
            }
            if ((arr[1] == "O" & arr[2] == "O" & arr[3] == "O") | (arr[1] == "O" & arr[5] == "O" & arr[9] == "O") | (arr[1] == "O" & arr[4] == "O" & arr[7] == "O") | (arr[2] == "O" & arr[5] == "O" & arr[8] == "O") | (arr[3] == "O" & arr[6] == "O" & arr[9] == "O") | (arr[3] == "O" & arr[5] =="O" & arr[7] == "O") | (arr[4] == "O" & arr[5] == "O" & arr[6] == "O") | (arr[7] == "O" & arr[8] == "O" & arr[9] == "O"))
            {// побеждает О, следующие действия аналогичны
                Ovin += 1;
                label3.Text = "X : O\n" + Xvin.ToString() + " : " + Ovin.ToString();
                MessageBox.Show(" O Победил!");
                refresch();
            }
            if ((arr[1] != "") & (arr[2] != "") & (arr[3] != "") & (arr[4] != "") & (arr[5] != "") & (arr[7] != "") & (arr[8] != "") & (arr[9] != ""))
            {// Ничья, то есть все поле заполнено, а победителя нет
                MessageBox.Show(" Ничья! "); // объявляем ничью
                refresch();// чистим поле
            }         
        }
   public void refresch()
        {
            button1.Text = "";
            button2.Text = "";
            button3.Text = "";
            button4.Text = "";
            button5.Text = "";
            button6.Text = "";
            button7.Text = "";
            button8.Text = "";
            button9.Text = "";// чистим каждую клетку поля
            label1.Text = "";//табло следующего хода
            for (i = 0; i < 10; i += 1) // массив ходов
            {
                arr[i] = "";
            }
            i = 1; // номер хода
            num_game += 1; // добавляем к номеру игры
            label2.Text = num_game + " игра"; // обновляем табло с номером игры
        }

Обработка кнопок: 

  private void button10_Click(object sender, EventArgs e) // Кнопка "Start" чистит поле
        {
            refresch();
        }

        private void button1_Click(object sender, EventArgs e) // первая клетка поля
        {
            if (button1.Text == "X" | button1.Text == "O") // если клетка уже заполненая
            {
                MessageBox.Show(" Нельзя!");// предупреждаем, что нельзя
            }
            else { button1.Text = Game(1); who_vin(); }// если все хорошо, запускаем 2 функции. задаем клетке отметку Х или О
        }

        private void button2_Click(object sender, EventArgs e) // вторая клетка поля. действия аналогичны, и со следующими
        {
            if (button2.Text == "X" | button2.Text == "O")
            {
                MessageBox.Show(" Нельзя!");
            }
            else { button2.Text = Game(2); who_vin(); }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (button3.Text == "X" | button3.Text == "O")
            {
                MessageBox.Show(" Нельзя!");
            }
            else { button3.Text = Game(3); who_vin(); }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            if (button4.Text == "X" | button4.Text == "O")
            {
                MessageBox.Show(" Нельзя!");
            }
            else { button4.Text = Game(4); who_vin(); }
        }

        private void button5_Click(object sender, EventArgs e)
        {
            if (button5.Text == "X" | button5.Text == "O")
            {
                MessageBox.Show(" Нельзя!");
            }
            else { button5.Text = Game(5); who_vin(); }
        }

        private void button6_Click(object sender, EventArgs e)
        {
            if (button6.Text == "X" | button6.Text == "O")
            {
                MessageBox.Show(" Нельзя!");
            }
            else { button6.Text = Game(6); who_vin(); }
        }

        private void button7_Click(object sender, EventArgs e)
        {
            if (button7.Text == "X" | button7.Text == "O")
            {
                MessageBox.Show(" Нельзя!");
            }
            else { button7.Text = Game(7); who_vin(); }
        }

        private void button8_Click(object sender, EventArgs e)
        {
            if (button8.Text == "X" | button8.Text == "O")
            {
                MessageBox.Show(" Нельзя!");
            }
            else { button8.Text = Game(8); who_vin(); }
        }

        private void button9_Click(object sender, EventArgs e)
        {
            if (button9.Text == "X" | button9.Text == "O")
            {
                MessageBox.Show(" Нельзя!");
            }
            else { button9.Text = Game(9); who_vin(); }
        }
 private void Form1_Load(object sender, EventArgs e)
        {
            refresch();// чистим поле перед игрой
            label3.Text = "X : O\n" + Xvin.ToString() + " : " + Ovin.ToString(); // задаем счетчик
        }

3.3. Задачи для программирования на С++ и C#
При работе информация вводится и выводится в текстовые поля с надписями, каждая задача оформляется в виде приложения в отдельной папке под номером задачи, например: z_4_2. Если есть варианты, то для каждого варианта создается кнопка его вызова. Условие задачи указывается на первой форме или на отдельной форме, вызываемой кнопкой, или в начале текста программы в виде комментария.
3.3.1. Числовые типы, оператор присваивания
Поменять местами значение целых переменных х и у, не используя дополнительные переменные.
Вычислить значения выражений:
а) not odd (n) при n = 0;
б) t and (p mod 3 = 0) при t = True, p = 101010;
в) (х ( у <>0) and (у > х) при х = 2, у = 1;
г) (х ( у <>0) or (у > х) при х = 2, у = 1;
д) a or (not b) при а = False, b = True.
3.3.2. Алгоритмы линейной структуры
Алгоритм линейной структуры  алгоритм, в котором блоки выполняются последовательно друг за другом, в порядке, заданном схемой. Такой порядок выполнения называется естественным.
Вычислить площадь треугольника со сторонами a, b, c по формуле Герона: 13 EMBED Equation.3 1415, где 13 EMBED Equation.3 1415.
Вычислить для усеченного конуса площадь поверхности 13 EMBED Equation.3 1415 и объем 13 EMBED Equation.3 1415.
Вычислить координаты центра тяжести трех материальных точек с массами 13 EMBED Equation.3 1415 и координатами 13 EMBED Equation.3 141513 EMBED Equation.3 141513 EMBED Equation.3 1415 по формулам: 13 EMBED Equation.3 1415; 13 EMBED Equation.3 1415.
Вычислить высоты треугольника со сторонами а, b, c, организуя ввод данных из блока данных и вывод результатов с их наименованиями.
3.3.3. Алгоритмы разветвляющей структуры
Часто в зависимости от каких-либо промежуточных результатов вычисления производятся либо по одним, либо по другим формулам, т.е. в зависимости от выполнения некоторого логического условия вычислительный процесс осуществляется по одной или другой ветви.
Алгоритм такого вычислительного процесса называется алгоритмом разветвляющей структуры.
Вычислить:
13 EMBED Equation.3 1415
Найти квадрат наибольшего из двух чисел a и b и отпечатать
N = 1, если наибольшим является а, и признак N = 2  в противном случае.
Определить, попадает ли точка с координатами х, у в круг радиуса r (уравнение окружности13 EMBED Equation.3 1415). Вывести признак N = 1, если точка находится внутри круга, и признак N = 0, если точка находиться вне круга.
Составить программу, выполняющую упорядочение трех чисел A, B, C, таким образом, чтобы при выполнении ее в ячейке с символическим адресом A находилось наименьшее число, в ячейке B  среднее, в ячейке C  наибольшее.
Записать указанное действие в виде одного условного оператора:
а) у = 13 EMBED Equation.3 1415
б) переменной х присвоить корень уравнения 13 EMBED Equation.3 1415.
в) перераспределить значение переменных х и у так, чтобы в х оказалось большее из этих значений, а в у  меньшее;
г) d = max (a, b, c);
д) z = 13 EMBED Equation.3 1415
е) переменной k присвоить номер четверти плоскости, в которой находится точка с координатами х и у (ху13 EMBED Equation.3 14150);
Записать программу для решения задачи:
а) по номеру у (у > 0) некоторого года определить с  номер его столетия (учесть, что, к примеру, началом XX столетия был 1901);
б) 13 EMBED Equation.3 1415;
в) если уравнение ax2 + bx +c = 0 (a13 EMBED Equation.3 14150) имеет вещественные корни, то логической переменной t присвоить значение True, а переменным xl и х2  сами корни, иначе переменной t присвоить False, а значение переменных xl и х2 не менять;
г) считая, что стандартные функции sin и cos применимы только к аргументам из отрезка [0, 13 EMBED Equation.3 1415], вычислить у = sin х для произвольного числа х;
д) значения переменных а, b и c поменять местами так, чтобы оказалось а13 EMBED Equation.3 1415b13 EMBED Equation.3 1415c.
3.3.4. Алгоритмы циклической структуры
Часто при решении задач приходится многократно вычислять значение по одним и тем же алгоритмам. Такие многократно повторяемые алгоритмы называются циклами. Различают циклы с заданным и неизвестным числом повторений. К последним относятся итерационные циклы, характеризующиеся последовательным приближением к искомому значению с заданной точностью.
Для организации цикла необходимо выполнить следующие действия: 1) задать перед циклом начальное значение переменной, изменяющейся в цикле; 2) изменять переменную перед каждым новым повторением цикла; 3) проверять условие окончания или повторения цикла; 4) управлять циклом, т.е. переходить к его началу, если он не закончен, или выходить из него по окончании. Последние три функции выполняются многократно.
Переменная, изменяющаяся в цикле, называется параметром цикла.
Вычислить значения функции 13 EMBED Equation.3 1415, если Х задано массивом, состоящим из 40 элементов.
Вычислить и вывести на печать положительные значения функции у=sin (nx)  cos (n/x) при n = 1, 2, , 50.
Вычислить значения функции z = xk/k, большие а, если k=1, 2, .
Вычислить значения функции у = а3/(а2 + х2) при х, изменяющемся от 0 до 3 с шагом 0,1.
Напечатать таблицу значений аргумента х и функции
у(х) = а3/(а2 + х2) при значении х, изменяющихся от 0 до 3 с шагом 0,1.
Составить программу для вычисления значения функции у = 13 EMBED Equation.3 1415 при одновременном изменении аргументов t от 2 до 3 с шагом 0,2 и х от 1 до 2 для а = 2,1.
Составить программу вычисления n! (1 . 2 . 3 . 4. ... . n):
Составить программу, вычисляющую экстремальное значение функции 13 EMBED Equation.3 1415 при изменении аргумента х от 0 до 4 с шагом h.
Вычислить:
а) у = (2n 1)! = 13 EMBED Equation.3 1415 13 EMBED Equation.3 1415, n >0;
б) у = (2n)! = 13 EMBED Equation.3 141513 EMBED Equation.3 1415, n >0;
в) у = n!, n > 0.
Вычислить: у = 13 EMBED Equation.3 1415.
Определить, является ли заданное натуральное число совершенным, т.е. равным сумме всех своих делителей, кроме самого этого числа (например, число 6 совершенно: 6=1+2+3).
Дано целое n >2. Напечатать простые числа из диапазона [2, n].
Найти сумму цифр заданного натурального числа.
Вычислить k  количество точек с целочисленными координатами, попадающих в круг радиуса R (R>0) с центром в начале координат.
Напечатать в возрастающем порядке все трехзначные числа, в десятичной записи которых нет одинаковых цифр.
Даны целое n и вещественные числа 13 EMBED Equation.3 1415 Рассматривая пары 13 EMBED Equation.3 1415 как координаты точек на плоскости, определить радиус наименьшего круга (с центром в начале координат), внутрь которого попадают все эти точки.
Напечатать все простые делители натурального числа.
18. Уравнение (предложена М.В. Дякиным).
Дана последовательность 13 EMBED Equation.3 1415, 13 EMBED Equation.3 1415  натуральное число. Квадратные скобки 13 EMBED Equation.3 1415 обозначают в формуле взятие целой части (округление до ближайшего меньшего целого числа). Обозначим 13 EMBED Equation.3 1415.
Написать программу, которая для заданного натурального 13 EMBED Equation.3 1415 13 EMBED Equation.3 1415 решает уравнение 13 EMBED Equation.3 1415,
где 13 EMBED Equation.3 1415 - обозначение числа 13 EMBED Equation.3 1415 - факториал: 13 EMBED Equation.3 1415.
Программа должна найти и сообщить:
1) точное значение x в виде несократимой дроби;
2) сумму цифр числителя и сумму цифр знаменателя этой дроби.
Образец вывода результата:
Число 6, числитель дроби X=10, знаменатель дроби X=63.
Сумма цифр числителя =1, сумма цифр знаменателя =9.
19. Задача «Кучи и яма» (предложена А.Б. Дернятиным).
Имеются яма и несколько куч (не более пяти) кирпичей. Разрешается перекладывать кирпичи из куч в яму по следующему правилу: если количество кирпичей в куче больше, чем в яме, то можно переложить столько кирпичей, сколько находится в яме в данный момент. Требуется разработать алгоритм, который позволяет уложить в яму как можно больше кирпичей.
Образец вывода результатов:
К1=150001 К2=81234 Я=70000 было
К1=150001 К2=11234 Я=140000 в яму из кучи 2й
К1=10001 К2=11234 Я=280000 в яму из кучи 1й
20. Представления натурального числа (предложена Д.Я.Шараевым).
Известно, что любое натуральное число N (0Пример. N=4. S=2. (12+12+12+12=4, 22=4)
21. Задача «Многоугольник» (предложена Н.Ю. Лукояновым).
На плоскости декартовыми координатами своих вершин дан выпуклый 13 EMBED Equation.3 1415-угольник. Его вершины пронумерованы от 1 до n в порядке следования против часовой стрелки. Задан номер 13 EMBED Equation.3 1415. Требуется провести через 13 EMBED Equation.3 1415-вершину 13 EMBED Equation.3 1415-угольника два луча (назовем их a и b) так, чтобы эти лучи делили 13 EMBED Equation.3 1415-угольник на три равновеликие по площади части.
Входные данные: 13 EMBED Equation.3 1415 - число вершин; (х1, y1), (x2, y2), , (xn, yn) - координаты 1-й, 2-й, и т.д. 13 EMBED Equation.3 1415-й вершины соответственно; 13 EMBED Equation.3 1415 - номер выделенной вершины.
Выходные величины: координаты (ха, ya) и (xb, yb) точек пересечения лучей a и b с границей 13 EMBED Equation.3 1415-угольника.

3.3.5. Алгоритмы работы с рядами
При работе с рядами обычно составляют рекуррентную формулу, которая задает значение i+1-го члена ряда (Y(i+1)) через значения предыдущих членов, чаще  i-го члена ряда (Y(i)). Обычно используют отношение i+1-го члена к i-му члену, подставляют их значения, и после преобразований получается рекуррентная формула.
Пример. Вычислить значение членов бесконечного ряда 13 EMBED Equation.3 1415 точностью до члена 13 EMBED Equation.3 1415. Считать, что требуемая точность (
·) достигнута, если очередное слагаемое по модулю меньше указанной точности и все последующие слагаемые можно уже не учитывать. Определим рекуррентную формулу Y(i+1)/Y(i)=(x(i+1)/(i+1)!)/(xi/i!)=x/i. Получим рекуррентную формулу Y(i+1)=Y(i)*x/(i+1).
Вычислить сумму членов для следующих рядов с точностью до 10-4:
а) 13 EMBED Equation.3 1415
б) 13 EMBED Equation.3 1415
Для вычисления текущего значения члена ряда использовать рекуррентную формулу 13 EMBED Equation.3 1415, где n  номер члена ряда. Начальное значение у принять равным 13 EMBED Equation.3 1415;
в) 13 EMBED Equation.3 1415;
г) 13 EMBED Equation.3 1415;
д) 13 EMBED Equation.3 1415;.
е) 13 EMBED Equation.3 1415;
ж) 13 EMBED Equation.3 1415.
Текущий член ряда вычислять, используя рекуррентную формулу.
Составить программу вычисления значений членов убывающей последовательности 13 EMBED Equation.3 1415 с точностью до10-4.
Составить программу вычисления членов бесконечного ряда
z =13 EMBED Equation.3 1415
с точностью до10-4.
Не используя стандартные функции (за исключением abs), вычислить с точностью до 10-4:
а) 13 EMBED Equation.3 1415
б) 13 EMBED Equation.3 1415
в) 13 EMBED Equation.3 1415
г) 13 EMBED Equation.3 1415
Вычисление f = 10!
Вычислить:
а) у = cos(x )+ cos(x2) + cos(x3) ++cos(x30);
б) у = 1! + 2! + 3! + + n! (n>1);

в) у  первое из чисел sin(x), sin(sin(x)), sin(sin(sin(x,))), меньшее по модулю 10-4.
Числа Фибоначчи («fn») определяются по формулами f0 = f1 = 1;
fn = fn-1 + fn-2 при n = 2, 3, :
а) определить четвертое число Фибоначчи;
б) вычислить первое число Фибоначчи, большее m (m > 1);
в) вычислить s  сумму всех чисел Фибоначчи, которые не превосходят 1000.
3.3.6. Алгоритмы работы с массивами
Для массива Х, состоящего из 40 элементов, выполнить следующие действия:
а) записать нули в массив;
б) вывести на печать положительные элементы массива;
в) вывести на печать первый отрицательный элемент массива и его порядковый номер, полагая, что в массиве есть хотя бы один отрицательный элемент;
г) вывести на печать номера элементов, удовлетворяющих условию 0<13 EMBED Equation.3 1415<1;
д) записать на место отрицательных элементов массива нули.
Вывести на печать элементы целочисленного массива (13 EMBED Equation.3 1415), кратные трем; n 13 EMBED Equation.3 1415 10.
Вывести на печать номера точек, лежащих в круге с радиусом r. Координаты точек заданы массивами (13 EMBED Equation.3 1415), (13 EMBED Equation.3 1415). Точка принадлежит кругу, если ее расстояние от центра круга не более r.
Составить программу вычисления значения функции z=хуi/(х+ уi), где yi  элементы массива Y {13 EMBED Equation.3 1415}, а аргумент х изменяется одновременно с yi от начального значения а с шагом h.
Составить программу для вычисления значения функции 13 EMBED Equation.3 1415, где 13 EMBED Equation.3 1415  элемент массива Х = {13 EMBED Equation.3 1415}.
Дана (построчно) вещественная матрица размером 713 EMBED Equation.3 14154. Переставляя ее строки и столбцы, следует добиться того, чтобы наибольший элемент (один из них) оказался в верхнем левом углу.
Определить, является ли заданная целая квадратная матрица
10-го порядка симметричной (относительно главной диагонали).
Элемент матрицы назовем седловой точкой, если он является наименьшим в своей строке и одновременно наибольшим в своем столбце или, наоборот, является наибольшим в своей строке и наименьшим в своем столбце. Для заданной целой матрицы размером 1013 EMBED Equation.3 141515 напечатать индексы всех ее седловых точек.
Определить, является ли заданная целая квадратная матрица 10-го порядка ортонормированной, т.е. такой, в которой скалярное произведение каждой пары различных строк равно 0, а скалярное произведение каждой строки на себя равно 1.
Определить, является ли заданная целая квадратная матрица 9-го порядка магическим квадратом, т.е. такой, в которой суммы элементов во всех строках и столбцах одинаковы.
Составить программу нахождения наибольшего элемента массива Х = {13 EMBED Equation.3 1415}.
Дано 100 вещественных чисел. Вычислить разность между максимальным и минимальным из них.
Дана непустая последовательность различных натуральных чисел, за которой следует 0. Определить порядковый номер наименьшего из них.
Дана последовательность из 100 целых чисел. Определить три наибольших числа среди них.
Дано 200 вещественных чисел. Определить, сколько из них больше своих «соседей», т.е. предыдущего и последующего чисел.
Задан массив Х = {3,2; 8,5; 20; 40; 8,2}. Написать программу ввода и вывода элементов массива.
Ввести 20 элементов массива С в диалоговом режиме.
Ввести по строкам матрицу А (5 13 EMBED Equation.3 1415 3).
Записать операторы ввода матрицы Х (6 13 EMBED Equation.3 1415 8) в общепринятом виде с заголовком МАТРИЦА Х.
3.3.7. Обработка символьных данных
Написать программу, которая подсчитывает частоту появления символа А в тексте, состоящем из любого числа строк. Признаком окончания входного набора данных следует считать строку из четырех символов «####».
Написать программу редактирования текста, которая заменяет в последовательности символов все восклицательные знаки точками. Признаком окончания вычислений является строка с начальными символами «##».
Составить программу определения, является ли заданный текст, правильной записью целого числа (возможно, со знаком).
Составить программу определения, является ли заданное натуральное число палиндромом, т.е. таким, десятичная запись которого читается одинаково слева направо и справа налево.
3.3.8. Организация подпрограмм
Написать программу, определяющую частоту появления символов А, В, С и цифры 9 в тексте, состоящем из любого числа строк. Признаком конца набора данных служит строка из пяти символов «13 EMBED Equation.3 1415«. Вычисление частоты повторяемости символа Х в строке текста оформить в виде подпрограммы.
Составить программу упорядочения трех чисел а, b, c, оформив перестановку двух чисел х и у в виде подпрограммы.
Составить программу нахождения корней следующих уравнений с точностью 13 EMBED Equation.3 1415, используя метод половинного деления:
а) 13 EMBED Equation.3 1415. Интервал, содержащий корень, равен [1, 2];
б) sin2(x) + cos(x2 ) – 10x = 0, а = 0, b = 1.
Уточнение корня уравнения f (x) на интервале [a, b] оформить в виде подпрограммы.
Два простых числа называются «близнецами», если они отличаются друг от дуга на 2 (таковы, например, числа 41 и 43). Напечатать все пары «близнецов» из отрезка [3,n], где n  заданное число, большее 2. Определение простого числа оформить подпрограммой.
Два натуральных числа называются «дружественными», если каждое из них равно сумме всех делителей другого, за исключением его самого (таковы, например, числа 220 и 284). Напечатать все пары «дружественных» чисел, не превосходящих заданное натуральное число. Определение суммы делителей числа оформить подпрограммой.
3.3.9. Работа с файлами
Написать программу, которая записывает в файл последовательного доступа квадраты и кубы 30 первых натуральных чисел.
Написать программу, которая записывает в файл последовательного доступа информацию о студентах, проживающих в общежитии: фамилию, индекс группы, домашний адрес, номер комнаты в общежитии. Если в качестве фамилии студента вводится пустая строка, то выполнение программы прекращается.
Написать программу, в которой создается файл прямого доступа, содержащий сведения о числе деталей с заданным кодом. Код детали равен номеру записи. Сведения о числе сведены в целочисленный массив А (10).
Написать программу создания файла прямого доступа, содержащего информацию о личной библиотеке. Информация о книгах вводится с клавиатуры. Номером записи является шифр книги.
Написать программу создания файла «Телефонный справочник» объемом не более 100 абонентов, содержащего следующие сведения об абоненте: фамилия абонента, адрес, номер телефона.
Написать программу создания файла, содержащего сведения о сдаче сессии студентами специальности: индекс группы, фамилия студента, шифры предметов и оценки.
Результаты соревнований по шести видам спорта летней Олимпиады 2000 г. записаны в файл прямого доступа OLIMP. Написать программу, которая выполняет одну из следующих функций:
а) выдает данные в виде таблицы о всех призерах Олимпиады  золотая, серебряная, бронзовая медали по запрашиваемому виду спорта;
б) выдает список призеров страны.
Создать файл «ТОВАР», содержащий сведения о товарах, хранящихся на складе: код товара, наименование товара, количество единиц, стоимость одной единицы. Все записи в файле должны быть отсортированы в порядке возрастания товара.
Написать программу, которая на основании информации, содержащейся в файле «ТОВАР» (с полями: наименование товара, дата поступления, количество и единица измерения):
а) добавляет новые товары, поступившие на склад;
б) производит корректировку записи о товаре с кодом ХХ  изменение количества, стоимости единицы товара.
3.3.10. Работа с формами и диаграммами
Вывести список из пяти различных рисунков, выбрав из списка нужный рисунок, вывести его.
Разработать программу-игру «Сапер». Число мин и их расположение в таблице (7 строк на семь колонок) загадывается случайным образом. Если мина в соседней ячейке от текущей (по которой щелкнули мышкой), то выводится символпредупреждение «!». Если щелкнули по ячейке с миной, то выводится знак «X’ и игра прекращается с сообщением: «Сапер убит». Во всех остальных случаях выводится символ «-». Для обезвреживания мины используется двойной щелчок по ячейке с миной. На экран выводится текущее число двойных щелчков. Выигрыш наступает, когда все мины обезврежены и число двойных щелчков минимально; на экран выводится сообщение «Мин нет».
Составить столбиковую диаграмму для 10 случайных чисел в интервале 0-60.
Составить круговую диаграмму для 17 случайных чисел в интервале 0-34.
Разработать ActiveX-элемент кнопки Выход.
Изменить тип, размер и стиль шрифта в диалоге с выводом новых значений и образца.
Составить программу для тестирования знаний логических операций «И», «Или», «Нет».
Составить форму с действующей блок-схемой нахождения максимального числа из трех вводимых пользователем чисел с кнопками Начало, Далее (переход на следующий шаг), Выход. Текущий символ блок-схемы выделяется красным цветом. Результаты выполнения шага помещают в текстовое поле.
Вывести бегущую строку с текстом, введенным в текстовое поле.
Реализовать игру «Крестики  нолики» между пользователем и компьютером (таблица 3х3).
Составить программу для тестирования знаний четырех любых простых законов физики. Числа случайные, целые. При неверном ответе выводить правильный ответ. За каждый неверный ответ оценка снижается на балл.
Составить программу компьютерного тестирования знаний. В текстовом редакторе создать файл с текстом. Каждое описание вопроса занимает несколько строк: текст вопроса, номер правильного ответа и строки с текстами вариантов ответа (не более семи), пустая строка  разделитель описаний вопросов. В форму последовательно выводятся вопрос с вариантами ответов, и тестируемый щелкает мышкой на предполагаемом правильным ответе. В конце выводится оценка по формуле: 513 EMBED Equation.3 1415число верных ответов/число всех вопросов. На форме разместить кнопки Начало, Выход.
Игра «Поле чудес». На форме представлены следующие элементы: поле для ввода загадываемого слова и кнопок его очистки, начала и выхода; поле с темой, к которой относится слово; поля для ввода буквы, с угаданными и неугаданными буквами; число попыток.
Составить программу «Будильник» с кнопками установки текущего времени, времени подачи звукового сигнала, отключения звука. Вывести на экран текущее время и время сигнала.
Для заданной целой матрицы случайных чисел (11000) размером 1013 EMBED Equation.3 141515 вывести красным цветом все ее седловые точки (п. 16.6, задача 8).

3.4. Контрольные работы
Для некоторых учебных программ по изучаемой дисциплине контрольная работа может быть выполнена и оформлена как курсовая работа.
В контрольной работе нужно создать:
Базу из основной таблицы с оперативными данными и трех таблицсправочников с наименованиями кодов, которые используются для расшифровки кодов при формировании форм, запросов и отчетов с установкой связей между таблицами. Рекомендуется создавать базу данных средствами СУБД, а не языков программирования и использовать для доступа к ней технологию формирования источника данных ODBC.
Базовый и другие запросы.
Формы для заполнения таблиц и просмотра запросов с русифицированными кнопками, наименованиями полей.
Один отчет с детальными строками, с расшифровками кодов и с итогами по двум уровням группировки, которые указаны в условии задачи.
Меню из пунктов: формы, запросы, отчеты и выход для вызова разработанных форм, запросов и отчетов.
Оформление контрольной работы
Работа оформляется в виде документа Word. На титульном листе указываются (сверху вниз): министерство, вуз, факультет, кафедра, текст: Контрольная работа по дисциплине <наименование дисциплины>, тема, фамилия студента, группа, фамилия руководителя, город и номер текущего года.
Содержание работы состоит из следующих разделов:
постановка задачи (краткое описание задачи);
входная информация (список таблиц с описанием их полей);
логическая модель базы (изображение таблиц и связей);
выходная информация (изображения форм, запросов и отчетов при проектировании и выполнении);
обращение к приложению (описание меню вызова форм, запросов и отчетов).

Темы контрольных работ

1. Учет семейного бюджета.
Бюджет: дата, учетный номер члена семьи, код статьи расхода, сумма расхода, код статьи дохода, сумма дохода.
Справочники: статьи расходов (код и наименование), статьи доходов (код и наименование), члены семьи (учетный номер, фамилия, родство).
Отчет по статьям расходов, членам семьи с итогами расходов по статьям и по членам семьи.
2. Учет переселенцев.
Переселенцы: код населенного пункта, код национальности, дата рождения, фамилия, наименование населенного пункта, откуда прибыл.
Справочники: населенные пункты (код, наименование, код области), национальности (код, наименование), области (код, наименование).
Отчет по областям, населенным пунктам с итогами (число переселенцев) по областям и населенным пунктам.
3. Учет авиапассажиров.
Авиапассажиры: код авиапредприятия, код города назначения, код страны города назначения, номер рейса, дата вылета, фамилия, адрес.
Справочники: авиапредприятия (код, наименование, адрес, телефон), города (код и наименование), страны (код и наименование страны).
Отчет по странам и городам с итогами (число авиапассажиров) по странам и городам.
4. Учет производства сельскохозяйственных культур.
Урожай: код сельскохозяйственного предприятия, код сельскохозяйственной культуры, урожайность, площадь, год.
Справочники: сельскохозяйственные предприятия (код и наименование, адрес, телефон, код района), сельскохозяйственные культуры (код и наименование), районы (код, наименование).
Отчет по сельскохозяйственным культурам и предприятиям с итогами урожая по сельскохозяйственным культурам и предприятиям.
5. Учет выпуска изделий.
Выпуск изделий: код изделия, код предприятия, количество выпускаемых изделий (шт.), отпускная цена, дата выпуска.
Справочники: изделия (код, наименование), предприятия (код, наименование, адрес, телефон, код города), города (код, наименование).
Отчет по городам, предприятиям с итоговой стоимостью выпущенных изделий по городам и предприятиям.
6. Учет платежей налогов.
Уплата налогов: код типа налога, код предприятия, сумма налогов за 1, 2, 3, 4-й кварталы.
Справочники: типы налогов (код, наименование, процент от базы налогообложения), предприятия (код, наименование, адрес, телефон, код города), города (код и наименование).
Отчет по типам налогов и городам с итоговыми суммами налогов по типам налогов и городам.
7. Учет поставок товаров.
Поставки товаров: код поставщика, код товара, количество, цена, единица измерения, дата поставки.
Справочники: поставщики (код, наименования, адрес, телефон, код города), товары (код, наименование), города (код и наименование).
Отчет по городам и поставщикам с итоговой стоимостью поставленных товаров по городам и поставщикам.
8. Учет сбросов отравляющих веществ в окружающую среду.
Сбросы отравляющих веществ: код организации, дата сброса, концентрация, размер сброса, код единицы измерения, сумма ущерба.
Справочники: организации (код, наименование, адрес, код города), единицы измерения (код, наименования), города (код и наименование).
Отчет по городам и предприятиям с итоговыми суммами ущерба по городам и предприятиям.
9. Учет призеров олимпийских игр.
Призеры: номер олимпийца, число завоеванных золотых, серебряных и бронзовых медалей.
Справочники: страны (код, наименование), виды спорта (код, наименование), олимпийцы (номер, фамилия, код страны, код вида спорта,).
Отчет по странам и видам спорта с итогами (число завоеванных золотых, серебряных и бронзовых медалей) по странам и видам спорта.
10. Учет уволившихся с предприятия.
Увольнения: код причины увольнения, дата увольнения, номер приказа, табельный номер уволенного.
Справочники: подразделения (код, наименование), причины увольнения (код и наименование), сотрудники (табельный номер, фамилия, код подразделения, пол).
Отчет по подразделениям и причинам увольнения с итогами (число уволенных сотрудников ) по подразделениям и причинам увольнения.
11. Учет рождаемости.
Новорожденные: код населенного пункта, код национальности, вес, рост, дата рождения, фамилия, имя, отчество.
Справочники: населенные пункты (код, наименование, код области), национальности (код, наименование), области (код, наименование).
Отчет по областям, населенным пунктам с итогами (число новорожденных) по областям и населенным пунктам.
12. Учет участников олимпиады.
Олимпийцы: код страны, код вида спорта, фамилия, дата рождения, рост, вес, пол, код города.
Справочники: страны (код, наименование, начальник команды, телефон), виды спорта (код, наименование), города (код, наименование).
Отчет по странам и видам спорта с итогами (число участников, средний вес, средний рост) по странам и видам спорта.
13. Учет проданных товаров.
Продажа товаров: код торгового предприятия, код товара, стоимость проданного товара, дата продажи.
Справочники: торговые предприятия (код, наименование, директор, телефон), товары (код, наименование, код группы товаров), группы товаров (код и наименование).
Отчет по торговым предприятиям и типам товаров с итогами (стоимость проданного товара) по торговым предприятиям и видам товаров.
14. Учет малых предприятий.
Предприятия: наименование предприятия, код населенного пункта, код вида деятельности, численность, адрес, объем выполненных работ за год, телефон, дата создания предприятия.
Справочники: населенные пункты (код, наименование, код области), виды деятельности (код, наименование), области (код и наименование).
Отчет по областям и населенным пунктам с итогами (численность и объем выполненных за год работ) по областям и населенным пунктам.
15. Учет больных в больнице.
Больные: фамилия, код диагноза, даты поступления и выписки, код отделения, дата рождения больного, код страховой компании.
Справочники: диагнозы (код, наименование, стоимость лечения), отделения (код и наименование), страховые компании (код и наименование).
Отчет по страховым компаниям и отделениям с итогами стоимости лечения по страховым компаниям и отдлениям.
16. Учет движения общественного транспорта.
Движение транспорта: код типа транспорта, номер и длина маршрута, табельный номер водителя, дата выхода на мршрут, код депо.
Справочники: типы транспорта (код, наименования), водители (табельный номер, фамилия), депо (код и наименование).
Отчет по видам транспорта и водителям с итогами (длина пройденного расстояния) по видам транспорта и водителям.
17. Учет дорожно-транспортных происшествий.
Дорожно-транспортные происшествия: код населенного пункта, содержание и дата нарушения, код подразделения милиции, зарегистрировавшего ДТП, и фамилия инспектора, число убитых и раненных, материальный ущерб.
Справочники: населенные пункты (код, наименование, код района), подразделения милиции (код, наименование), районы (код и наименование).
Отчет по районам, населенным пунктам с итогами (число убитых и раненных, материальный ущерб) по районам и населенным пунктам.
18. Учет платежных поручений в банке.
Платежные поручения: код банка, код клиента, код вида платежа, дата, сумма, номер поручения.
Справочники: клиенты банка (код, наименование, адрес, директор, телефон), виды платежей (код, наименование), банки (код, наименование).
Отчет по банкам и клиентам с итоговыми суммами перечислений по по банкам и клиентам.
19. Учет договоров займа.
Договора: код организации, номер договора, дата заключения, дата окончания, сумма, процент, сумма возврата, возвращенная сумма, особые условия, процент штрафа за каждый просроченный день.
Справочники: организации (код, наименование, адрес, директор, телефон, код города), города (код и наименование, код области), области (код и наименование).
Отчет по дням городам и предприятиям с итоговыми суммами возвратов по городам и предприятиям.
20. Учет проданных ценных бумаг.
Продажа ценных бумаг: код эмитента, код типа ценной бумаги, число, номинальная и курсовая стоимости (цены), дата, номер регистрации выпуска ценных бумаг.
Справочники: эмитенты (код, наименование, адрес, директор, телефон, код города), типы ценных бумаг (код, наименование), города (код и наименование).
Отчет по типам ценных бумаг и эмитентам с итогами курсовой стоимости проданных ценных бумаг по типам бумаг и эмитентам.
21. Учет кадров.
Сотрудники: табельный номер, фамилия, дата рождения, код специальности, код подразделения, дата приема, дата начала трудовой деятельности, оклад, образование, код должности.
Справочники: специальности (код, наименование), подразделения (код, наименование), должности (код и наименование).
Отчет по подразделениям и должностям с итогами (число сотрудников) по подразделениям и должностям.
22. Учет очередников на получение жилья.
Очередники: фамилия, номер очереди, номер приказа, код организации, код основания включения в очередь, дата, паспортные данные, число членов семьи, адрес.
Справочники: организации (код, наименование, код города), основания включения в очередь (код, наименование), города (код и наименование).
Отчет по предприятиям и основаниям включения в очередь с итогами (числом очередников) по предприятиям и основаниям включения в очередь.
23. Учет обмена валюты.
Обмен валюты: дата, фамилия, паспортные данные, код валюты, количество валюты проданной и купленной, количество рублей, затраченных на покупку, и вырученных от продажи валюты, код банка.
Справочники: валюта (код, наименование), города (код, наименование, код банка), банки (код и наименование банка, код города).
Отчет по видам валюты и по банкам с итогами (сумма проданной и купленной валюты, валютная выручка) по видам валют и банкам.
24. Учет объектов строительства.
Стройки: код населенного пункта, сметная стоимость, стоимость выполненных работ, дата начала строительства, наименование объекта, код заказчика, код подрядчика.
Справочники: населенные пункты (код, наименование), заказчики (код, наименование), подрядчики (код и наименование).
Отчет по населенным пунктам и заказчикам с итогами (сметная стоимость, стоимость выполненных работ) по населенным пунктам и заказчикам.
25. Учет нарушителей трудовой дисциплины на предприятии.
Нарушения: код вида нарушения, дата нарушения, мера наказания, табельный номер нарушителя, содержание нарушения, код подразделения.
Справочники: подразделения (код, наименование), виды нарушений (код и наименование), сотрудники (табельный номер, фамилия, код подразделения, пол).
Отчет по подразделениям и видам нарушений с итогами (число нарушителей) по подразделениям и видам нарушений.
26. Учет выдачи и возврата книг.
Выдача и возврат книг: номер читательского билета, регистрационный номер книги, дата выдачи, дата возврата, дата фактического возврата.
Книги: регистрационный номер книги, код тематики, наименование, авторы, адрес хранения, код издательства.
Справочники: тематика (код, наименование), издательства (код, наименование), читатели (номер читательского билета, фамилия, адрес, дата рождения, паспортные данные).
Отчет по темам и читателям с итогами (число выданных книг) по темам и читателям.
27. Учет исполнительской дисциплины.
Мероприятия: код подразделения, в котором проводится мероприятие, табельный номер исполнителя, ответственного за проведение мероприятия, наименование мероприятия, срок исполнения, табельный номер руководителя, контролирующего выполнение мероприятия.
Справочники: подразделения (код, наименование), сотрудники (табельный номер, фамилия), руководители (табельный номер, фамилия, должность).
Отчет по руководителям и исполнителям с итогами (число мероприятий) по руководителям и исполнителям.
28. Учет успеваемости студентов.
Испытания: код предмета, дата, оценка, номер зачетки, код вида испытания (зачет, экзамен, реферат, курсовая работа, практика).
Справочники: предметы (код и наименование), студенты (номер зачетки, фамилия, группа), виды испытаний (код и наименование).
Отчет по группам и студентам со средней оценкой по группам и студентам.
29. Учет книг в библиотеке.
Книжный фонд: код тематики, наименование, авторы, дата, число экземпляров, адрес хранения, код издательства, код отдела библиотеки.
Справочники: тематика (код, наименование), издательства (код, наименование, адрес, телефон), отделы библиотеки (код и наименование).
Отчет по тематикам и издательствам с итогами (число наименований и экземпляров книг) по тематикам и издательствам.
30. Учет успеваемости школьников.
Оценки: код предмета, дата, оценка, учетный номер школьника, табельный номер учителя.
Справочники: предметы (код и наименование), школьники (учетный номер школьника, фамилия, дата рождения, номер класса, пол), учителя (табельный номер, фамилия, дата рождения, пол).
Отчет по классам и школьникам со средней оценкой по классам и школьникам.


Библиографический список

Е.А. Зуев А.А. Чупринов Стандарт С++: перевод, комментарии, примеры. Москва: ООО «ВАШ ФОРМАТ».  2016 г. 888 с.
Понамарев В. Программирование на C++/C# в Visual Studio .NET 2003 / В. Понамарев. - М.: БХВ-Петербург, 2015. - 917 c.
Джон Шарп. Microsoft Visual C#. Питер, 2017 год, 848 стр. 8-е изд.
[ Cкачайте файл, чтобы посмотреть ссылку ]
https://metanit.com/cpp/tutorial/

Учебное издание
Плещёв Владимир Васильевич,
Шишков Евгений Иванович
Основы программирования на языках C++, C# с примерами и упражнениями

Редактор и корректор М.В. Баусова

Поз. Подписано в печать .
Формат бумаги 60 х 84 1/16. Бумага для множительных аппаратов.
Печать плоская. Уч.- изд. л. 20,1. Усл. печ. л. 19,67 .
Заказ 823 Тираж 600 экз.
Издательство Уральского государственного экономического университета
Екатеринбург, ул. 8 Марта, 62
ОАО «Полиграфист», цех № 4
Екатеринбург, ул. Тургенева, 22






































13 PAGE 14215



13 PAGE 14415 Оглавление

13 PAGE 14315

13 PAGE 141015 Оглавление



13 PAGE 1431415 Глава 8. Лабораторный практикум

13 PAGE 1422415

13 PAGE 1433015

13 PAGE 1423615


13 EMBED Photoshop.Image.5 \s 1415

УДК 681.3.06
ББК 32.973
( Плещёв В.В., 2018
( Уральский государственный
экономический университет, 2018



Рисунок 2Рисунок 6Рисунок 7Рисунок 8Рисунок 10Рисунок 14Рисунок 15Рисунок 16Рисунок 17Рисунок 18Рисунок 20Рисунок 24Рисунок 26Рисунок 27Рисунок 55Рисунок 58Рисунок 59Рисунок 60Рисунок 64Рисунок 19Рисунок 32Рисунок 37Рисунок 38Рисунок 42Рисунок 44Рисунок 46Рисунок 36Рисунок 51Рисунок 54Рисунок 65Рисунок 76Рисунок 67Рисунок 70Рисунок 77Рисунок 82Root EntryEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeEquation NativeРисунок 4Рисунок 5Рисунок 1Рисунок 12

Приложенные файлы

  • doc 6439020
    Размер файла: 8 MB Загрузок: 1

Добавить комментарий