Задание для самостоятельной работыиндивидуальное



Практическая работа № 1: Знакомство со средой MicrosoftVisualStudio 2010 и настройка компилятора языка C.

Отличительной особенностью среды MicrosoftVisualStudio 2010 является то, что она поддерживает работу с несколькими языками программирования и программными платформами. Поэтому перед тем, как писать программу на языке C, необходимо выполнить несколько подготовительных шагов по созданию проекта, выбору и настройке компилятора языка C для трансляции исходного кода.

После запуска MicrosoftVisualStudio 2010 появляется стартовая страница.

Первым шагом является создание нового проекта. Для этого в меню Файл необходимо выбратьСоздать | Проект… (или нажать комбинацию клавиш Ctrl + Shift + N).Среда VisualStudio отобразит окно «Создать проект», в котором необходимо выбрать тип создаваемого проекта. Проект используется в VisualStudio для логической группировки нескольких файлов, содержащих исходный код на одном из поддерживаемых языков программирования, а также любых вспомогательных файлов. Обычно после сборки проекта (которая включает компиляцию всех всходящих в проект файлов исходного кода) создается один исполняемый модуль.

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

После выбора типа проекта в поле редактора Имя (где по умолчанию имеется<Введите_имя>) необходимо ввести его имя, например hello. В поле Расположение можно указать путь размещения проекта или выбрать его с помощью кнопки Обзор. По умолчанию проект сохраняется в специальной папке Projects.

Одновременно с проектом VisualStudio создает решение. Решение – это способ объединения нескольких проектов для организации более удобной работы с ними.

После нажатия кнопки OK откроется окно «Мастер приложений Win32».

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

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

После нажатия кнопки Готово получим экранную форму, где приведена последовательность действий добавления файла исходного кода к проекту. Стандартный путь для этого: выбрать в контекстном меню папки Файлы исходного кода узла hello дерева обозревателя решений пунктДобавить, затем Создать элемент….

В центральной части открывшегося окна «Добавление нового элемента» необходимо выбрать Файл C++ (.cpp).В поле редактора Имя (в нижней части окна) следует задать имя нового файла и указать расширение .c. Например, main.c. Имя может быть достаточно произвольным, но имеется негласное соглашение, что оно должно отражать назначение файла и логически описывать исходный код, который в нем содержится. В проекте, состоящем из нескольких файлов, есть смысл выделить файл, содержащий главную функцию программы, т. е. ту, с которой она начнет выполняться. В данном случае такому файлу зададим имя main.c, где расширение .c указывает на то, что этот файл содержит исходный код на языке C, и он будет транслироваться соответствующим компилятором. Программам на языке C принято давать указанное расширение. После задания имени файла получим следующую форму.

Затем следует нажать кнопкуДобавить. Вид среды VisualStudio после добавления первого файла к проекту показан на рисунке ниже. Добавленный файл отображается в дереве Обозреватель решений под узлом Файлы исходного кода, и для него автоматически открывается редактор.

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

Папка Файлы исходного кода предназначена для файлов с исходным кодом. В ней отображаются файлы с расширением .c.

Папка Заголовочные файлысодержит заголовочные файлы с расширением .h.

В папке Файлы ресурсов представлены файлы ресурсов, например изображения, звуковые файлы и т. д.

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

Следующий шаг состоит в настройке проекта. Для этого в меню Проект главного меню следует выбрать Свойства: hello….

После того как откроется окно свойств проекта, в дереве слева следует выбрать узел Свойства конфигурации/Общиеи в левой панели изменить значение свойства Набор символов наИспользовать многобайтовую кодировку. Эта настройка позволяет определиться, какая кодировка символов – ANSI или UNICODE – будет использована при компиляции программы. Для совместимости со стандартом C89 выбираем «Использовать многобайтовую кодировку». Это позволяет применять многие привычные функции, например, по выводу информации на консоль.

Аналогичным образом необходимо установить следующие свойства:

· C/C++ / Создание кода / Включить C++ исключения в значение Нет

· C/C++ / Язык / Отключить расширения языка в значение Да (/Za)

· C/C++ / Язык / Считать WChar_t встроенным типом в значение Нет (/Zc:wchar_t-)

· C/C++ / Язык / Включить информацию о типах времени выполнения в значение Нет (/GR-)

· C/C++ / Язык / Поддержка OpenMP в значение Нет (/openmp-)

· C/C++ / Дополнительно / Компилировать как в значение Компилировать как код C (/TC)

После нажатия кнопок Применить и ОК в подготовленном проекте с пустым полем редактора кода можно начать писать программу. В этом редакторе наберем программу, выводящую традиционное приветствие «Hello, World». Для компиляции созданной программы можно обратиться в меню Построение | Компилироватьили нажать клавиши Ctrl + F7. В случае успешной компиляции получим экранную форму, показанную на следующем рисунке.

 

Запуск программы на исполнение выполняется нажатием клавиши F5.

Произведем разбор первой программы. Во-первых, отметим, что в языке C нет стандартных инструкций (операторов) для ввода\вывода, в т. ч. сообщений на консоль (окно пользователя), а предусмотрены специальные библиотечные файлы, в которых имеются функции для этих целей. В приведенной программе используется заголовочный файл с именем stdio.h(стандартный ввод\вывод), который должен быть включен в начало программы при помощи инструкции препроцессора #include. Для вывода сообщения на консоль используется функция printf(). Для работы с консолью в программу включен также заголовочный файл conio.h, поддерживающий функцию _getch(), которая извлекает символ из стандартного потока ввода, т. е. предназначена для приема сообщения о нажатии какой-либо (почти любой) клавиши на клавиатуре. С другими компиляторами, возможно, потребуется getch(), т.е. без префиксного нижнего подчеркивания. Строка программы

intmain(void)

определяет главную функцию программы и что она возвращает целое число, о чем указывает аббревиатура int. Имя main() – это специальное имя, которое указывает, где программа должна начать выполнение. Наличие круглых скобок после слова main свидетельствует о том, что это имя функции. Если содержимое этих скобок отсутствует или в них представлено служебное слово void, то это означает, что в функцию main() не передается никаких аргументов. Тело функции main() ограничено парой фигурных скобок. Все утверждения программы, заключенные в них, будут относиться к этой функции.

В теле функции main() вызываются еще две функции. Функция printf()печатает или отображает в стандартный поток вывода (по умолчанию на консоль, т.е. на экран) те аргументы, которые были подставлены вместо параметров. Символ \n означает единый символ newline (новая строка), т.е. с его помощью выполняется перевод на новую строку. Символ \t осуществляет горизонтальную табуляцию, т.е. начало вывода с отступом вправо.

Функция без параметров _getch() извлекает символ из потока ввода, т.е. ожидает нажатия клавиши для завершения работы программы.

Последнее утверждение в первой программе

return 0;

указывает на то, что выполнение функции main() закончено и что в систему возвращается значение 0 (целое число). Нуль используется в соответствии с соглашением об индикации успешного завершения программы.

Все инструкции в программе завершаются символом точки с запятой.

Все файлы проекта сохраняются в той папке, которая была указана в поле «Расположение» в диалоговом окне при создании проекта.

Перечислим основные файлы в этой папки:

· hello.sln – файл решения для созданной программы. Он содержит информацию о том, какие проекты входят в данное решение. Обычно эти проекты расположены в отдельных подкаталогах. Например, наш проект находится в подкаталоге hello;

· hello.suo – файл настроек среды VisualStudio при работе с решением включает информацию об открытых окнах, их расположении и прочих пользовательских параметрах;

· hello.sdf – файл, содержащий вспомогательную информацию о проекте, который используется инструментами анализа кода VisualStudio, такими как IntelliSense для отображения подсказок об именах и т. д.

Файлы папки Debug:

· hello.exe – исполняемый файл проекта;

· hello.ilk – файл «incremental linker», используемый компоновщиком для ускорения процесса компоновки;

· hello.pdb – отладочная информация (информация об именах в исполняемых файлах, используемая отладчиком).

Файлы папки hello:

· main.c – файл исходного программного кода;

· hello.vcxproj – файл проекта;

· hello.vcxproj.user – файл пользовательских настроек, связанных с проектом;

· hello.vcxproj.filters – файл с описанием фильтров, используемых VisualStudioSolutionExplorer для организации и отображения файлов с исходным кодом.

Практическая работа № 2: Переменные и базовые типы данных языка C. Арифметические операторы.

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

тип список_переменных;

Здесь тип означает один из базовых или производных типов (если необходимо — с одним или несколькими спецификаторами), а список_переменных состоит из одного или более идентификаторов, разделенных запятыми.

В языке Cидентификаторами называют имена переменных, функций, меток и т.п. Обычно идентификатор представляет собой последовательность из одного или нескольких символов. Первый символ должен быть буквой или символом подчеркивания, последующие символы должны быть буквами, цифрами или символами подчеркивания. Верхние и нижние регистры символов рассматриваются как различные. Следовательно, count, Count и COUNT — это три разных идентификатора. Идентификатор не может совпадать с ключевым словом C или с именем библиотечной функции.

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

Стандарт С89 определяет пять базовых типов данных:

char — символ;

int — целое числа;

float — вещественное числос плавающей точкой;

double — вещественное число с плавающей точкой двойной точности;

void — без значения.

На основе этих типов формируются другие типы данных. Размер (объем занимаемой памяти) и диапазон значений этих типов данных для разных процессоров и компиляторов могут быть разными.

Объект типа char всегда занимает 1 байт. Размер объекта int обычно совпадает с размером слова в конкретной среде программирования. В большинстве случаев в 16-разрядной среде int занимает 16 битов, а в 32-разрядной — 32 бита. Однако полностью полагаться на это нельзя, особенно при переносе программы в другую среду. Необходимо помнить, что стандарт C обусловливает только минимальный диапазон значений каждого типа данных, но не размер в байтах.

Переменные типа char обычно используются для обозначения набора символов стандарта ASCII.

Диапазон значений типов float и double зависит от формата представления чисел с плавающей точкой. Стандарт C определяет для чисел с плавающей точкой минимальный диапазон значений от 1Е-37 до 1Е+37.

Тип void служит для объявления функции, не возвращающей значения, или для создания обобщенного указателя.

Существуют 4 модификатора, которые могут применяться к указанным базовым типам: signed (знаковый), unsigned (беззнаковый), long (длинный), short (короткий).

Базовый тип int может быть модифицирован каждым из перечисленных модификаторов (спецификаторов), тип char – с помощью unsigned и signed, тип double – с помощью long.

По умолчанию все переменные являются знаковыми. Поэтому применение модификатора signedна практике сильно ограничено. По большому счету он существует лишь как пара модификатору unsigned. При применении модификатора unsignedдлина положительного диапазона удваивается за счет отрицательной части. Например, диапазон типа unsignedintбудет [0…65535], а не [-32768…32767] как для int.

Модификатор longпредназначен для увеличения стандартного диапазона значений типа данных за счет выделения большего объема памяти. Short,по аналогии с signed, существует лишь как пара и на практике не используется.Тип longfloatпо сути представляет собой тип double.

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

Типы данных языка C

Тип данных Типичный размер в битах Минимально допустимый диапазон значений
char 8 от –128 до 127
unsigned char 8 от 0 до 255
signed char 8 от –128 до 127
int 16 или 32 от –32 768 до 32 767
unsigned int 16 или 32 от 0 до 65 535
signed int 16 или 32 от –32 768 до 32 767
short int 16 от –32 768 до 32 767
unsigned short int 16 от 0 до 65 535
signed short int 16 от –32 768 до 32 767
long int 32 от –2 147 483 647 до 2 147 483 647
long long int 64 от –(263 – 1 ) до (263 – 1) для С99
signed long int 32 от –2 147 483 647 до 2 147 483 647
unsigned long int 32 от 0 до 4 294 967 295
unsigned long long int 64 от 0 до (264 – 1) для С99
float 32 от 1Е – 37 до 1Е + 37 (с точностью не менее 6 значащих десятичных цифр)
double 64 от 1Е – 37 до 1Е + 37 (с точностью не менее 10 значащих десятичных цифр)
long double 80 от 1Е – 37 до 1Е + 37 (с точностью не менее 10 значащих десятичных цифр)

Ниже приведены примеры объявлений переменных:

int i,j;
unsignedint ui;
double balance, profit, loss;

В приводимых ниже программах используются такие стандартные функции форматного ввода/вывода, как printf()иscanf(). Приведем их краткую характеристику.

Прототип функции printf()имеет следующий вид:

int printf(const char *управляющая_строка, ...);

Управляющая_строка состоит из элементов двух видов. Первый из них — это символы, которые предстоит вывести в стандартный поток вывода (по умолчанию на экран); второй — это спецификаторы преобразования, которые определяют способ вывода стоящих за ними аргументов. Каждый такой спецификатор начинается со знака процента, за которым следует код формата. Аргументов должно быть ровно столько, сколько и спецификаторов, причем спецификаторы преобразования и аргументы должны попарно соответствовать друг другу в направлении слева направо. Например, в результате такого вызова printf():

printf("%d + %lg = %lg", 2, 1.5, 3.5);

Будет выведено

1 + 2.5 = 3.5

В этом примере первому спецификатору преобразования (%d), соответствует целое число 2, а второму и третьему (%lg), — числа с плавающей точкой двойной точности 1.5 и 3.5.

В следующей таблице приведены основные спецификаторы преобразования, используемые в функции printf().

Спецификаторы преобразования для функции printf()

Код Формат
%c символ
%dили %i целое число со знаком
%u беззнаковое целое
%f вещественное число (float) с точностью до 6-го знака
%lf число типа double с точностью до 6-го знака
%e вещественное число в экспоненциальном представлении
%g в зависимости от того, какой вывод будет короче, используется %е или %f
%s Строка символов

Функция scanf() осуществляет ввод со стандартного потока ввода (консоли, клавиатуры). Она может читать данные всех встроенных типов и автоматически преобразовывать числа в соответствующий внутренний формат, scanf() во многом выглядит как обратная к printf(). Прототип функции scanf():

int scanf(const char *управляющая_строка, ...);

Управляющая_строка определяет преобразование считываемых значений при записи их в переменные, на которые указывают элементы списка аргументов.

Управляющая строка состоит из символов трех видов:

· спецификаторов преобразования,

· разделителей,

· символов, не являющихся разделителями.

Каждый спецификатор формата ввода начинается со знака % и сообщает функции scanf() тип считываемых данных. Их перечень (за небольшим исключением) соответствует спецификаторам функции printf(). Спецификаторам преобразования в порядке слева направо ставятся в соответствие элементы списка аргументов.

Разделитель в управляющей строке дает scanf() указание пропустить в потоке ввода один или несколько начальных разделителей. Разделителями являются пробелы, табуляции, вертикальные табуляции, подачи страниц и разделители строк. В сущности, один разделитель в управляющей строке заставляет scanf() читать, но не сохранять любое количество (в том числе и нулевое) разделителей, которые находятся перед первым символом, не являющимся разделителем.

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

Для всех переменных, которые должны получить значения с помощью scanf(), должны быть переданы их адреса. Для этого перед их именем необходимо ставить оператор &, определяющий адрес переменной. Например, для считывания целого значения в переменную count можно использовать такой вызов функции scanf():

scanf("%d", &count);

В следующем примере у пользователя запрашивается один символ и одно целое число, которые считываются и записываются в переменные c и i и обратно выводятся на экран с помощью функций scanf() и printf() соответственно.

char c;
int i;
scanf("%c%i", &c, &i);
printf("c = %c\ni = %i", c, i);

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

имя_переменной = выражение;

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

В языке C разрешается присваивать одно и то же значение нескольким переменным одновременно. Например, во фрагменте программы, приведенном ниже, переменным x, у и z одновременно присваивается число 0:

х = у = z = 0;

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

Оператор Действие
Вычитание, а также унарный минус
+ Сложение
* Умножение
/ Деление
% Деление по модулю
–– Декрементация
++ Инкрементация

Операторы +, –, * и / выполняются точно так же, как и вбольшинстве других языков программирования. Их можно применять практически к любым встроенным типам данных. Если оператор / применяется к целому числу или символу, дробная часть отбрасывается (правило целочисленной математики). Например, 5/2 равно 2.

Оператор деления по модулю %, как и в других языках программирования, возвращает остаток целочисленного деления. Этот оператор нельзя применять к числам с плавающей точкой.

Унарный минус умножает свой операнд на –1. Иными словами, унарный минус меняет знак операнда на противоположный. В языке C есть два полезных оператора, которыми не обладают некоторые другие языки. Это операторы инкрементации и декрементации ++ и ––. Оператор ++ добавляет 1 к своему операнду, а оператор –– вычитает ее. Таким образом, два следующих выражения эквивалентны:

х = х + 1;
++x;

Операторы инкрементации и декрементации имеют две формы: префиксную (++x) и постфиксную (x++). Однако между ними существует важное отличие,которое проявляется, когда они используются внутри выражений.В префиксном случае операнд вначале увеличивается (уменьшается), а затем используется. В постфиксной форме в выражении используется старое значение операнда, и только затем он увеличивается (уменьшается).

х = 10; у = ++х; /* y присвоится 11 */
x = 10; y = х++; /* y присвоится 10 */

Большинство компиляторов языка C создают для операторов инкрементации и декрементации очень быстрый и эффективный объектный код. Он выполняется намного быстрее, чем код, соответствующий оператору присваивания. По этой причине операторы инкрементации и декрементации следует применять всегда, когда это возможно.

Ниже перечислены арифметические операторы по их приоритету (от высшего к низшему):

++ –– (префиксная форма)
– (унарный минус)
* / %
 + –
++ –– (постфиксная форма)

Операторы, имеющие одинаковый приоритет, выполняются слева направо. Разумеется, для изменения порядка вычисления операторов можно применять скобки. В языке C скобки интерпретируются точно так же, как и во всех других языках программирования. Они позволяют присвоить некоторым операторам или группе операторов более высокий приоритет.

Круглые скобки – это оператор, повышающий приоритет операций, заключенных внутри. Лишние скобки не приводят к ошибкам и не замедляют выполнение программ. Однако они позволяют прояснить точный порядок вычислений:

х = y/3–34*temp+127;
х = (у/3) – (34*temp) + 127;

Пробелы и символы табуляции облегчают чтение программ.

В языке C существуют составные формы оператора присваивания, представляющие собой комбинации оператора присваивания и арифметических операторов. Например, оператор х = х + 10 можно переписать в виде х += 10. Оператор "+=" сообщает компилятору, что к старому значению переменной х следует прибавить число 10. Оператор присваивания образует составные формы практически со всеми бинарными операторами. Составные формы присваивания часто называют сокращенными операторами присваивания.

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

Практическая работа № 3: Операторы языка C. Выражения. Явное и неявное приведение типов.

Язык C располагает весьма значительным набором операторов. Их можно разделить на 4 основные группы: арифметические, сравнения, логические и битовые. Кроме того,в Cпредусмотрено еще несколько специальных операторов, например, операторы приведения, адресации, разыменования и т.п.

По количеству операндов операторы могут быть унарными, бинарными и тернарными. Унарные операторы работают с одним, бинарные – с двумя, а тернарные – с тремя операндами.

c = a + b;

Здесьa, bиcявляются операндами, а ‘+’ и ‘=’ – операторами.

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

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

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

Для оператора присваивания правило преобразования типов формулируется просто: значение правой части преобразовывается к типу левой части. Рассмотримпример:

int main(void)

{

int x = 550;

char ch = '0';

float f = 3.15;

ch = x; /* Строка 1 */

x = f; /* Строка 2 */

f = ch; /* Строка 3 */

f = x; /* Строка 4 */

return 0;

}

В строке 1 левый старший разряд целой переменной х отбрасывается, и переменной ch присваиваются 8 младших битов, апоскольку число 550 в шестнадцатеричной системе равно 0x226,то переменной ch будет присвоен символ '&' (с кодом 0x26 или 38).Если значение переменной х изменяется от 0 до 255, то переменные ch и х будут эквивалентными. В строке 2 переменной х будетприсвоена целая часть переменной f, то есть 3. В строке 3 восьмибитовое целое число, хранящееся в переменой ch, будет преобразовано в число с плавающей точкой – 38,0. То же самое произойдет и в строке 4, только теперь в число с плавающей точкой будетпреобразовано целочисленное значение переменной х, то есть 3,0.

В процессе преобразования типа int в тип char и типа long intв тип int старшие разряды отбрасываются. Во многих 16-битовыхоперационных системах это означает, что 8 бит будет потеряно. В32-разрядных операционных системах при преобразовании типаint в тип char будет потеряно 24 бит, а при преобразовании типаint в тип shortint – 16 бит.

Правила преобразования типов показаны в следующей таблице.

Результирующий тип Тип выражения Возможные потери
signed char char если значение > 127, результатом будет отрицательное число
char short int старшие 8 бит
char int (16 бит) старшие 8 бит
char int (32 бит) старшие 24 бит
char long int старшие 24 бит
short int int (16 бит) нет
short int int (32 бит) старшие 16 бит
int (16 бит) long int старшие 16 бит
int (32 бит) long int нет
int float дробная часть и, возможно, что-то еще
float double точность, результат округляется
double long double точность, результат округляется

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

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

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

х = f1() + f2();

нет никаких гарантий того, что функция f1() будет вызвана перед вызовом f2().

Если в выражение входят константы и переменные разныхтипов, они преобразуются к одному типу. Компилятор преобразуетвсе операнды в тип "наибольшего" операнда. Этот процесс называется расширением типов. Во-первых, все переменные типов charи short int автоматически преобразуются в тип int. Этот процессназывается целочисленным расширением. Во-вторых, все преобразования выполняются одно за другим, следуя приведенному ниже алгоритму.

ЕСЛИ операнд имеет тип long double,

ТО второй операнд преобразуется в тип long double

ИНАЧЕ, ЕСЛИ операнд имеет тип double,

ТО второй операнд преобразуется в тип double

ИНАЧЕ, ЕСЛИ операнд имеет тип float,

ТО второй операнд преобразуется в тип float

ИНАЧЕ, ЕСЛИ операнд имеет тип unsigned long,

ТО второй операнд преобразуется в тип unsigned long

ИНАЧЕ, ЕСЛИ операнд имеет тип long,

ТО второй операнд преобразуется в тип long

ИНАЧЕ, ЕСЛИ операнд имеет тип unsigned int,

ТО второй операнд преобразуется в тип unsigned int

Кроме того, есть одно правило: если один из операторовимеет тип long, а второй – unsigned int, и значение переменнойтипа unsigned int невозможно представить с помощью типа long, тооба операнда преобразуются в тип unsigned long.

После выполнения преобразований тип обоих операндоводинаков и совпадает с типом результата выражения.

Рассмотрим пример автоматического (неявного)преобразования типов при разборе приведенного ниже выражения

char ch;

int i;

float f;

double d;

result = (ch / i) + (f * d) - (f + i);

Сначала символ ch преобразуется в целое число. Результат операции ch/i преобразуется в double, потому что результат f*d имеет тип double. Результат операции f+i имеет тип float, потому что f имеет тип float. Окончательный результат имеет тип double.

Используя явное приведение типов, можно принудительно задатьтип выражения. Приведение типов имеет следующий вид:

(тип) выражение

Здесь тип – это любой допустимый тип данных. Например, в приведенном ниже фрагменте программы результат выражения х/2приводится к типу float:

(float) x/2

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

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

Предположим, что нам необходимо найти знаменатель геометрической прогрессии, заданной целочисленными значениями:3, –7, …. Без оператора приведения типа (float) деление было быцелочисленным и дробная часть была бы потеряна, то есть:

q = -7/3; /* –2.0000000 */

q = (float) -7/3; /* –2.3333333 */

Операторы сравнения используются для того, чтобы сравнить два значения. Например, для определения того, больше ли значение переменной a значения переменной b, можно воспользоваться оператором ‘>’. Соответствующее выражение будет иметь вид:

a>b

Результатом вычисления данного выражения будет значение логического типа (истина или ложь). Так как в языке Cнет отдельного логического типа, то в нем принято следующее правило: любое значение любого типа данных является истиной, если оно отлично от нуля и ложью, если равно нулю.Выражения, использующие операторы сравнения и логическиеоператоры, возвращают 0, если результат ложен, и 1, если результат истинен.

В следующей таблице приведен полный список операторов сравнения языка C.

Оператор Проверяемое условие
> больше
>= больше или равно
< меньше
<= меньше или равно
== равно
!= не равно

Приоритет операторов сравнения ниже, чем у арифметических. Например,  выражение 10 > 1 + 12 будет вычислено так, будто оно записано следующим образом: 10 > (1 + 12). Разумеется, это выражение будет ложным.

Взаимный приоритет операторов сравнения представлен в таблице:

Приоритет Оператор
1 >, <, >=, <=
2 ==, !=

То есть результатом вычисления выражения 5> 4 == -4<-3 будет истина [(5 > 4) == (-4 < -3) → 1 == 1 → 1], а не ложь, как в случае, если бы операторы имели одинаковый приоритет [((5 > 4) == -4) <-3 → (1 == 4) <-3 → 0 < -3 → 0].

Логические операторы позволяют создавать сложные условные выражения из операторов сравнения. Результатом вычисления логического выражения также является значение логического типа (0 или 1).

В следующей таблице приведен список операторов сравнения языка C.

Оператор Действие
! НЕ
&& И
|| ИЛИ

Ниже приведена таблица истинности для логических операторов.

a b a && b a || b !a
0 0 0 0 1
0 1 0 1 1
1 0 0 1 0
1 1 1 1 0

a&&bбудет иметь значение 1, если ни выражение a, ни выражение b не равны нулю, и значение 0 – в противном случае (выражение bбудет вычисляться только в том случае, если aне равно нулю).

a || bбудет иметь значение 1, если оба выражения aи bне равны нулю, и значение 0 – в противном случае (выражение b будет вычисляться только в том случае, если a равно нулю).

!a будет иметь значение 1, если a равно нулю, и значение 0 – в противном случае.

Логические операторы выполняются после операторов сравнения.Взаимный приоритетлогических операторов представлен в таблице:

Приоритет Оператор
1 !
2 &&
3 ||

Как и для арифметических операторов, естественный порядок вычислений можно изменять с помощью скобок. Например, выражение !0 && 0 || 0 является ложным. Однако если перегруппировать его операнды с помощью скобок, результат станет противоположным: !(0 && 0) || 0.

Как для операторов сравнения, так и для логических операторов, типом результирующего значения является int.

Возможно, самым необычным оператором в языке C можно назвать оператор условия. В отличие от других операторов он является тернарным, т.е. работает с тремя операндами. Общий формат условного оператора представлен ниже

условие ? выражение_1 : выражение_2

Если в результате вычисления условия будет получено истинное значение (не нуль), то результатом выполнения условного оператора будет значение, полученное при вычислении выражения_1, в противно случае – выражения_2. В следующем примере в переменную maxValue присваивается большее из двух значений aиb.

maxValue = (a > b) ? a : b;

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

Оператор Описание Ассоциативность
() [] -> . вызов функции ссылка на элемент массива ссылка на член структуры с помощью указателя ссылка на член структуры слева направо
- + ++ -- ! * & sizeof (тип) унарный минус унарный плюс префиксная форма инкремента префиксная форма декремента логическое отрицание разыменования адресации размер объекта приведение типов (преобразование) справа налево
* / % умножение деление остаток от деления слева направо
+ - сложение вычитание слева направо
< <= > >= меньше чем меньше чем или равно больше чем больше или равно слева направо
== != равно не равно слева направо
&& логическое И слева направо
|| логическое ИЛИ слева направо
?: условный оператор справа налево
= операторы присваивания (в т. ч. сокращенные) справа налево
++ -- постфиксная форма инкремента постфиксная форма декремента справа налево
, последовательно вычисление слева направо

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

Задание для самостоятельной работы общее для всех:Написать программу вычисления математического выражения для произвольных значений z.

Ниже перечислены стандартные математические функции языкаC, для использования которых необходимо предварительно подключить заголовочный файл <math.h>.

Для вычисления модуля воспользуйтесь условным оператором.

Задание для самостоятельной работыиндивидуальное

Разработать программу с использованием операций языка С++ и функций стандартной математической библиотеки. Значения исходных данных вводить с клавиатуры с использованием библиотечной функции scanf(). Значение результата вычислений выводить на экран с использованием библиотечной функции printf().

Составить отчет по практической работе.

Варианты заданий

1. Разработать программу, которая вводит длины сторон треугольника a, b, cи вычисляет его площадь по формуле Герона.

2. Разработать программу, которая вводит координаты вершин треугольника (x1,y1), (x2,y2), (x3,y3) и вычисляет длины его сторон и его площадь.

3. Для цилиндра радиусом r и высотой h разработать программу вычисления площади и объема по формулам:

; .

4. Для полого цилиндра высотой h, внешним радиусом r1 и внутренним радиусом r2 разработать программу вычисления объема по формуле:

.

5. Разработать программу вычисления площади кольца с внешним радиусом r1 и внутренним радиусом r2.

6. Для конуса радиусом r и высотой h разработать программу вычисления объема по формуле:

.

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

8. Напишите программу вычисления величины дохода по вкладу через N лет, если известны годовая процентная ставка и время хранения вклада.

9. Разработать программу вычисления площади параллелограмма.

10. Разработать программу вычисления площади параллелепипеда.

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

12. Разработать программу, которая вводит значения аргумента x и вычисляет значение функции y:

13. Функция y=sin(x) на отрезке  хорошо приближается разложением: . Разработать программу, которая для заданного значения аргумента x подсчитывает  по этой формуле и сравнивает его с точным значением, вычисленным с помощью стандартной функции.

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

15. Разработать программу, которая вводит значения аргумента x и вычисляет значение функции y:

16.  Разработать программу, которая для введенного целого трехзначного числа определяет, какая цифра в числе является первой, какая – второй и какая – третьей.

17. Разработать программу, которая вводит значения аргумента x и вычисляет значение функции y:

18. Разработать программу, переводящую время, указанное в минутах, во время в часах и минутах.

19. Заданы уравнения двух пересекающихся прямых на плоскости: y1=k1x+b1, y2=k2x+b2. Разработать программу, вычисляющую угол между ними в градусах и минутах, используя формулу .

20. Разработать программу, которая вводит значения аргумента x и вычисляет значение функции y:

21. Длина некоторого отрезка составляет p метров. Разработать программу перевода ее в русскую неметрическую систему. Указание: 1 верста = 500 саженей, 1 сажень = 3 аршина, 1 аршин = 16 вершков, 1 вершок = 44,45 мм.

22.  Разработать программу, которая вводит значения аргумента x и вычисляет значение функции y:

 

Практическая работа № 4: Условная конструкция.

Условная конструкция (ветвления, принятия решений) - одна из трёх (наряду с линейной и циклической) базовых конструкций структурного программирования, обеспечивающая выполнение определённой команды (набора команд) только при условии истинности некоторого логического выражения, либо выполнение одной из нескольких команд (наборов команд) в зависимости от значения некоторого выражения.

Язык Cпредоставляет две основные формы условной конструкции:

· условный оператор if;

· оператор многозначного выбора switch.

Общая форма записи оператора if:

if (условное выражение) оператор;

else оператор;

Если условное выражение истинно (т.е. не равно нулю), выполняетсяоператор или блок, указанный в разделе if, в противном случаевыполняется оператор или блок, предусмотренный в разделе else.Операторы, указанные в разделах if или else, являются взаимоисключающими.

Здесь оператор может состоять из одного или нескольких операторов (блока) или отсутствовать вовсе (пустой оператор). Раздел elseявляется необязательным.

В языке C результатом условного выражения является скаляр, т.е. целое число, символ, указатель или число с плавающейточкой. Число с плавающей точкой редко применяется в качестверезультата условного выражения,поскольку значительно замедляет выполнение программы.

В приведенном ниже листинге написан код для определения четности введенного пользователем числаи отображения соответствующего сообщения на терминале.

int main(void)

{

int i;

 

printf("i = ");

scanf("%d", &i);

 

if (i % 2 == 0)

       printf("Введенное число четное");

else

       printf("Введенное число нечетное");

 

_getch();

return 0;

}

Если тело условной конструкции включает более одной инструкции, его необходимо оформить в виде блока кода. Блок – это группа связанных между собой операторов, рассматриваемых как единое целое. Операторы, образующие блок, логически связаны друг с другом. Блок иногда называется также составным оператором. Блок начинается открывающей фигурнойскобкой { и завершается закрывающей фигурной скобкой }. Блокчаще всего используется как составная часть другого оператора,в частности, условного оператора if. Однако блок может являться исамостоятельной единицей программы.

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

if(i)

{

       if(j) оператор1;

       if(k) оператор2;

       else оператор3; /* связан с if(k)*/

}

else оператор4; /* связан с if(i) */

Последний раздел else связан не с оператором if(j), которыйнаходится в другом блоке, а с оператором if(i). Внутренний разделelse связан с оператором if(k), потому что этот оператор if являетсяближайшим.

В программах на языке C часто используется вложенная конструкция if - elseif, называемая также лестница, которая позволяет выбрать одно из нескольких условий.

Общий вид этой конструкции выглядит так:

if(условное выражение) оператор;

Else

if (условное выражение) оператор;

Else

if(условное выражение) оператор;

else оператор;

Эти условия вычисляются сверху вниз. Как только значениеусловного выражения становится истинным, выполняется связанный с ним оператор, и оставшаяся часть конструкции игнорируется. Если все условные выражения оказались ложными, выполняется оператор, указанный в последнем разделе else. Если этого раздела нет, то не выполняется ни один оператор.

Поскольку по мере увеличения глубины вложенности количество отступов в строке возрастает, лестницу if – elseif часто записывают иначе (без отступов):

if(условное выражение) оператор;

Else

if (условное выражение) оператор;

Else

if(условное выражение) оператор;

elseоператор;

Ниже приведен код программы, которая по введенному номеру месяцавыводит его название, используя оба варианта вложенности оператора if.

int main(void)

{

intm;

printf("Введите номер месяца: ");

scanf("%d",&m);

if (m > 0 && m <= 12)

{

       printf("Выввели ");

       if (m == 1) printf("январь");

       elseif (m == 2) printf("февраль");

       elseif (m == 3) printf("март");

       elseif (m == 4) printf("апрель");

       elseif (m == 5) printf("май");

       elseif (m == 6) printf("июнь");

       elseif (m == 7) printf("июль");

       elseif (m == 8) printf("август");

       elseif (m == 9) printf("сентябрь");

       elseif (m == 10) printf("октябрь");

       elseif (m == 11) printf("ноябрь");

       else printf("декабрь");

}

elseprintf("Вы ввели неправильный номер месяца");

 

_getch();

return 0;

}

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

Общая форма записи оператораswitch:

switch (выражение)

{

case константа1:

последовательность операторов

break;

case константа2:

последовательность операторов

break;

case константа3:

последовательность операторов

break;

default:

последовательность операторов

}

Значением выражения должен быть перечислимый тип: символ или целое число. Значение выражения последовательно сравнивается с константами, указанными в операторахcase. Если обнаруживается совпадение, выполняется последовательность операторов, связанных с данным оператором case, покане встретится оператор break или не будет достигнут конец оператора switch. Если значение выражения не совпадает ни с одной изконстант, выполняется оператор default. Этот раздел оператораswitch является необязательным. Если он не предусмотрен, в отсутствие совпадений не будет выполнен ни один оператор.

Оператор break относится к группе операторов перехода. Егоможно использовать как в операторе switch, так и в циклах (рассматривается в следующем практическом занятии). Когда поток управления достигает оператора break,программа выполняет переход к оператору, следующему за оператором switch.

Следует знать следующие особенности оператора switch:

· Оператор switch отличается от оператора if тем, что значение его выражения сравнивается исключительно с константами, в то время как в операторе if можно выполнятькакие угодно сравнения или вычислять любые логическиевыражения.

· Две константы в разных разделах case не могут иметьодинаковых значений, за исключением случая, когдаодин оператор switch вложен в другой.

· Если в операторе switch используются символьные константы, они автоматически преобразовываются в целочисленные.

· Оператор switch не позволяет проверять вхождение константы во множество или диапазон.

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

В приведенном ниже примере по введенному номеру месяца выводится, к какой поре года он относится. Приведенная программаиспользует эффект "сквозного" выполнения ветвей case (пропускаоператора break):

int main(void)

{

intm;

printf("Введитеномермесяца: ");

scanf("%d",&m);

if (m > 0 && m <= 12)

{

       printf("Выввели ");

       switch (m)

       {

       case 12: case 1: case 2:

       printf("зимний"); break;

       case 3: case 4: case 5:

       printf("весенний"); break;

       case 6: case 7: case 8:

       printf("летний"); break;

       default:

       printf("осенний");

       }

       printf(" месяц");

}

else printf("Вы ввели неправильный номер месяца");

 

_getch();

return 0;

}

"Сквозное" выполнение ветвей case позволяет нескольковетвей case объединить в одну.Рекомендуется в конце последней ветви помещать операторbreak, хотя с точки зрения логики в ней нет необходимости. Но этамаленькая предосторожность спасет, когда однажды потребуетсядобавить в конец еще одну ветвь case.

Операторы switch могут быть вложены друг в друга. Дажеесли константы разделов case внешнего и внутреннего операторовswitch совпадают, проблемы не возникают. Например, приведенный ниже фрагмент программы является вполне приемлемым:

switch (x)

{

case 1:

       switch(у)

       {

             case 0:

                   printf( "Деление на нуль");

                   break;

             case 1:

                   process(x,у);

       }

       break;

case 2:

...

Задания для самостоятельной работы:

1. Напишите программу, определяющую, является ли введенный пользователем год високосным, используя правило: номер високосного года делится нацело на 4 и при этом не делится на 100 или делится нацело на 400. Для записи условного выражения воспользуйтесь логическими операторами.

2. Используя оператор switch,напишите программу, выводящую на экран названия языков программирования на заданную букву. Например:

Ввод Вывод
A или a Ada
B или b Basic
C или c COBOL
D или d Delphi
F или f Fortran

3. Используя вложения операторовif, напишите программу, определяющую наибольшее из трех чисел.

 

 

Практическая работа № 5: Циклическая конструкция.

Цикл – разновидность управляющей конструкции, предназначенная для организации многократного исполнения набора инструкций.

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

В языке C существуют три типа циклов:

· цикл с предусловием и дополнительными параметрамиfor (как правило, используется как цикл со счетчиком);

· цикл с предусловием while;

· цикл с постусловием dowhile.

Общая форма записи цикла for:

for (блок инициализации; условное выражение; блок изменения состояния)

тело цикла;

Три выражения, заключенные в круглые скобки, задают условия выполнения программного цикла. Первый параметр (блок инициализации) используется для задания начальных значений переменных цикла.Как правило, здесь задается начальное значение счетчика – переменной, хранящей текущий номер итерации. Этот блок выполняется только один раз.

Второй компонент (условное выражение) определяет условие, в соответствии с которыми будет осуществляться выход из цикла. Повторение будет происходить до тех пор, пока это условие истинно (значение отлично от нуля). Если условие не выполняется, то цикл немедленно завершается. Как правило, условием выхода из цикла является достижение счетчиком определенного значения.

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

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

В цикле for проверка условия выполняется перед каждой итерацией. Иными словами, если условие цикла с самого началаявляется ложным, его тело не будет выполнено ни разу.

В следующем примере цикл forиспользуется для вывода на экран сообщения “Hello, World” десять раз:

int i;

for(i = 1; i < 11; i++)

printf("Hello, World\n");

Сначала переменной i присваивается число 1, а затем она сравнивается с числом 11. Поскольку ее значение меньше 11, вызывается функция printf(). Затем переменная i увеличивается на единицу, и условие цикла проверяется вновь. Как только ее значение превысит число 10, выполнение цикла прекратится. В данном случае переменная i является счетчиком цикла, который изменяется и проверяется на каждой итерации.

Возможности цикла forмогут быть расширены за счет включения нескольких действий в блоки инициализации и (или) изменения состояния. В этом случае действия записываются через запятую и выполняются слева направо. В следующем примере на экран выводится таблица сумм для заданного числа:

int i, j, n;

printf("Введитечисло: ");

scanf("%d", &n);

for(i = 0, j = n; i <= n; i++, j--)

printf("\n%d + %d = %d", i, j, i + j);

Общая форма записи циклаwhile:

while (условное выражение)

тело цикла;

Производится расчет условноговыражения, заключенного в круглые скобки. Если получается истинный результат, то выполняется тело цикла, следующее непосредственно за закрывающей круглой скобкой. Затем опять рассчитывается условие. Если результатом расчета окажется «истина», то вновь будут выполнены инструкции, составляющие тело цикла. Цикл повторяется до тех пор, пока в результате расчета условного выражения не будет получено значение «ложь», которое является признаком окончания цикла, после чего выполнение программы продолжается с утверждения, следующего за циклом.

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

int i = 1;

while(i < 11)

{

printf("Hello, World\n");

i++;

}

Общая форма записи цикла do-while:

do {

тело цикла;

} while (условное выражение);

Цикл do…whileработает примерно также, как и цикл while. Единственное отличие заключается в том, что сначала выполняется тело цикла, и лишь затем проверяется условие выхода из цикла. Поэтому цикл do…while всегда выполняется как минимум один раз.

В следующем примере цикл do…while используется для организации диалога с пользователем. С помощью функции getch() с клавиатуры считывается один символ. Если этим символом является ‘д’ или ‘Д’, соответствующие ответу «да», программа начинает свою работу заново и завершается в противном случае.

char ans;

do

{

...

printf("Выполнить программу еще раз? (д/н)\n");

ans = getch();

} while(ans == 'д' || ans == 'Д');

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

5 4 3 2 1

4 3 2 1

3 2 1

2 1

1

int n, i, j;

printf("Введите размерность треугольника: ");

scanf("%d", &n);

 

for(i = 0; i<n; i++)

{

       for(j = n-i; j> 0; j--)

       {

             printf("%d", j);

       }

       printf("\n");

}

В теле цикла могут вызываться операторы безусловного перехода breakиcontinue для прерывания всего цикла и одной итерации соответственно.

Задания для самостоятельной работы общее для всех:

1. Используя цикл for со счетчиком,напишите программу, вычисляющую факториал заданного числа.

2. Используя цикл while, напишите программу, вычисляющую сумму цифр заданного целого числа. Например, суммой цифр числа 2155 будет 2 + 1 + 5 + 5 = 13. Для выделения цифр используйте остатки от последовательного деления числа на 10.

3. Используя вложенные циклы, напишите программу, выводящую на экран «полуелочку» из звездочек:

*

* *

* * *

*

* *

* * *

* * * *

*

* *

* * *

* * * *

* * * * *

и т.д. заданное количество раз.


Дата добавления: 2018-04-05; просмотров: 519; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!