Будь умным!


У вас вопросы?
У нас ответы:) SamZan.net

Программирование для студентов направления подготовки 6050102 Компьютерная инженерия отрасли знаний 0501

Работа добавлена на сайт samzan.net:


МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ УКРАИНЫ

ХЕРСОНСКИЙ НАЦИОНАЛЬНЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ

КАФЕДРА ИНФОРМАЦИОННЫХ ТЕХНОЛОГИЙ

Рег. №____________

МЕТОДИЧЕСКИЕ УКАЗАНИЯ

для выполнения лабораторных работ

по дисциплине «Программирование»

для студентов направления подготовки 6050102 «Компьютерная инженерия»

отрасли знаний 0501 «Информатика и вычислительная техника»

факультета кибернетики

Херсон 2010


Методические указания для выполнения лабораторных работ по дисциплине «Программирование» для студентов направления подготовки 6050102 «Компьютерная инженерия» /Е.А. Дроздова. – Херсон: ХНТУ, 2010. – 75 с.

Рецензент: Бражник А.М., к.т.н., доцент кафедры Технической кибернетики ХНТУ

Утверждено

на заседании кафедры ИТ

протокол № 1 от «_30_» августа 2010 г.

Зав. кафедрой _____________проф. В.Е.Ходаков


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

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

Лабораторные работы выполняются в отведенное для этой цели аудиторное время, в соответствии с расписанием учебных занятий, в дисплейном классе, оборудованном персональными компьютерами типа IBM PC.

Как правило, выполнение каждой лабораторной работы требует от студента следующих действий:

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

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

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

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

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

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


Лабораторная работа №1

Интегрированная среда разработки программ Borland C

Цель работы: Изучение интегрированной среды разработки программ Borland C.

Теоретические сведения

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

Весь этот комплекс возможностей заключен в Интегрированной Среде Разработки (ИСР).

Кроме того, Среда разработки программ Borland C предоставляет следующие дополнительные возможности, которые еще больше упрощают процесс написания программ:

  •  Возможность отображения на экране монитора значительного числа окон, которые можно перемещать по экрану и размеры которых можно изменять.
  •  Наличие поддержки “мыши”.
  •  Наличие блоков диалога.
  •  Наличие команд удаления и вставки (при этом допускается копирование из окна HELP и между окнами EDIT).
  •  Возможность быстрого вызова других программ и обратного возврата.
  •  Наличие в редакторе макроязыка.

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

Строка меню и меню

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

Окна Borland C

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

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

Любые вводимые команды или вводимый текст, как правило, относятся только к активному окну.

Существует несколько типов окон, но большая их часть имеет следующие общие элементы:

  •   строку заголовка;
  •   маркер закрытия окна;
  •   полосы прокрутки;
  •   угол изменения размера окна;
  •   маркер распахивания окна на весь экран;
  •   номер окна.

Строка состояния

Строка состояния, расположенная у нижнего края экрана, выполняет следующие функции:

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

Блоки диалога

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

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

Работа с экранным меню Borland C

МЕНЮ (системное)

Отображается у левого края строки меню. Для вызова следует нажать ALT -пробел. При вызове этого меню отображаются команды:

About

При выборе данной команды появляется блок диалога, в котором содержится информация по авторским правам и номер версии Borland C. Данное окно закрывается нажатием клавиши ESC или ENTER.

Clear Desktop

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

Repaint Desktop

Осуществляет регенерацию изображения на экране.

Элементы подменю Transfer

В этом подменю показаны имена всех программ, которые установлены с помощью блока диалога Transfer, вызываемого командой Options/Transfer. Для запуска программы необходимо выбрать ее имя из системного меню.

Меню File(ALT F)

Это МЕНЮ позволяет открывать в окнах EDIT и создавать исходные файлы программ, сохранять внесенные изменения, выполнять другие действия над файлами, выходить в оболочку DOS и завершать работу с Borland C.

Open(F3)

Команда FILE OPEN отображает блок диалога, в котором выбирается исходный файл программы, который будет открыт в окне EDIT.

Этот блок диалога содержит блок ввода, список файлов, и кнопки OPEN, REPLACE, CANCEL и HELP, а также информационную панель.

Здесь можно выполнить одно из действий:

1) Ввести полное имя файла и выбрать указатель REPLACE или OPEN.

В результате выбора Open файл загружается в новое окно Edit. Для выбора Replace должно иметься активное окно Edit; в результате выполнения Replace содержимое окна заменяется выбранным файлом.

2) Ввести имя файла с метасимволами. Это позволяет отфильтровать список файлов в соответствии со спецификацией.

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

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

Блок ввода позволяет явно ввести имя файла или ввести имя файла с метасимволами DOS (* и ?). Если ввести имя полностью и нажать Enter, Borland C откроет указанный файл. (Если ввести имя файла, который система Borland C не может обнаружить, она автоматически создаст и откроет новый файл с таким именем.)

Если нажать ? , когда курсор находится в блоке ввода, то под этим блоком появляется список предыстории, содержащий последние восемь имен файлов, которые были введены ранее.

New

Команда File New позволяет открывать новое окно Edit со стандартным именем NONAMExx.С (где вместо букв хх задается число в диапазоне от 00 до 99). Файлы с именем NONAME используются в качестве временного буфера для редактирования; когда файл с подобным именем сохраняется на диске, Borland C запрашивает действительное имя файла.

Save (F2)

Команда File Save записывает на диск файл, находящийся в активном окне Edit (если активно окно Edit в настоящий момент, если нет, то данным элементом меню нельзя воспользоваться.) Если файл имеет использованное по умолчанию имя (NONAME00.C и т.п.) Borland C откроет блок диалога Save Editor File, который позволяет переименовать данный файл и сохранять его в другом каталоге или на другом дисководе.

Save As

Команда File Save As позволяет сохранить файл в активном окне Edit под другим именем, в другом каталоге или на другом дисководе.

Change Dir

Команда File Change Dir позволяет задать идентификатор и имя каталога, которые следует сделать текущими. Текущим является тот каталог, который используется в Borland C для сохранения и поиска файлов. (При использовании относительных маршрутов в Options Directories они задаются только относительно текущего каталога).

Print

Команда File Print печатает содержимое активного окна Edit Borland C "раскрывает" символы табуляции (заменяет их соответствующим числом пробелов), а затем посылает файл на устройство печати, заданное в DOS. Данная команда будет "запрещена", если содержимое активного окна не может быть выведено на печать. Для вывода на печать только выделенного текста следует использовать Ctrl-K P.

Get Info

Команда File Get Info отображает блок, в котором содержится информация относительно текущего файла.

Значения блока Get Info

Таблица 1.1

ЗНАЧЕНИЕ

СМЫСЛ

Current directory

Имя каталога по умолчанию

Current file

Имя файла в активном окне

Extended memory usage

Объем дополнительной памяти, зарезервированной для Borland C

Expanded memory usage

Объем расширенной памяти, зарезервированной для Borland C

Lines compiled

Число откомпилированных строк

Total warnings

Число выданных системой предупреждающих сообщений

Totals errors

Число сгенерированных ошибок

Total time

Время последнего выполнения программы

Program loaded

Статус отладки

Program exit

Код возврата от последней завершившейся программы

Available memory

Объем доступной памяти DOS (640 К)

Last step time

Время выполнения последнего шага отладки

DOS Shell

Команда File DOS Shell позволяет временно выйти из Borland C, чтобы выполнить команду DOS или запустить программу. Для возврата в Borland C необходимо ввести с клавиатуры EXIT и нажать Enter.

Иногда можно обнаружить, что во время отладки не хватает памяти для выполнения этой команды. В этом случае необходимо завершить сеанс отладки командой Run Program Reset (Ctrl-F2).

Quit (Alt-x)

Команда File Quit осуществляет выход из системы Borland C, удаляет ее из памяти и передает управление DOS. Если внесены изменения, которые еще не были сохранены, то перед выходом Borland C выдаст запрос на их сохранение.

Меню Edit(Alt-E)

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

1) Нажать Shift с одновременным нажатием стрелки.

2) Нажать Ctrl-K B, чтобы пометить начало выделяемого блока.

Затем переместить курсор в конец фрагмента текста и нажать Ctrl-K K.

3)Для выбора строки необходимо нажать Ctrl-K L.

После выделения фрагмента текста становятся доступными команды, расположенные в меню Edit, и можно использовать текстовый буфер (Clipboard).Он взаимодействует с командами меню Edit:

Restore Line

Эта команда отменяет действие последней команды редактирования, примененной к какой-либо строке. Она действует только над последней отредактированной строкой.

Cut (Shift-Del)

Удаляет выделенный фрагмент текста из документа и заносит его в текстовый буфер. Затем можно вставить текст в другой документ путем выбора Paste.

Copy (Ctrl-Ins)

Эта команда не изменяет выделенный текст, но заносит в текстовый буфер его точную копию. Затем можно вставить текст в другой документ командой Paste. Можно скопировать текст из окна Help; следует использовать Shift и клавиши управления курсором.

Paste (Shift-Ins)

Эта команда вставляет текст из текстового буфера в текущее окно в позиции курсора.

Show Clipboard

Эта команда открывает окно Clipboard, в котором хранятся фрагменты текста, удаленного и скопированного из других окон.

Clear (Ctrl-Del)

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

Меню Search (Alt-S)

Меню Search выполняет поиск текста, объявлений функций, а также местоположение ошибок в файлах.

Команда Search Find отображает блок диалога Find, который позволяет ввести образец поиска и задать параметры, влияющие на процесс поиска. Эта команда может быть также вызвана с помощью (Ctrl-Q-F).

Replace (Ctrl Q A)

Команда Search Replace отображает блок диалога для ввода искомого текста и текста, на который его следует заменить.


Search Again (Ctrl L)

Команда Search Again повторяет действие последней команды Find или Replace. Все параметры, которые были заданы при последнем обращении к использованному блоку диалога(Find или Replace), остаются действительными при выборе данной команды.

Меню Run (Alt-R)

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

Run(Ctrl-F9)

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

Тrace Into(F7)

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

Program Reset(Ctrl-F2)

Команда Run Program Reset прекращает текущий сеанс отладки, освобождает память программы и закрывает все открытые файлы, которые использовались в программе.

Over

Команда Run Step Over выполняет следующий оператор в текущей функции без вхождения в функции более низкого уровня, даже если эти функции доступны отладчику. Командой Step Over следует пользоваться в случаях, когда необходимо отладить функцию в пооператорном режиме выполнения без вхождения в другие функции.

Arguments

Команда Run Arguments позволяет задать выполняемой программе аргументы командной строки точно так же, как если бы они вводились в командной строке DOS. Команды переназначения ввода/вывода DOS будут игнорироваться.

Compile (C)

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

EXE File

Команда Compile Make EXE File вызывает Менеджер проектов для создания EXE-файла.

Link EXE File Только при полном наборе меню

Команда Compile Link EXE File использует текущие OBJ и LIB-файлы и компонует их, не производя избирательной компиляции.

Меню Debug (Alt F9)

Команды меню Debug управляют всеми возможностями интегрированного отладчика.

Inspect (Alt F4)

Команда Debug Inspect открывает окно Inspector, которому позволяет проанализировать и модифицировать значения элемента данных.

Меню Options(Alt-O)

Меню Oрtions содержит команды, которые позволяют просматривать и модифицировать стандартные параметры, определяющие функционирование Borland C.

Задание:

1. Используя команды экранного меню File, найти, открыть и переименовать какой-либо файл из каталога примеров пакета Borland C.

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

Контрольные вопросы

  1.  Какая команда позволяет сохранить на диске файл, который находится в активном окне?
  2.  Какая команда отображает на экране блок диалога, позволяющий открыть файл?
  3.  Какая команда позволяет распахивать на весь экран активное окно?
  4.  Для чего служит команда Change Dir?
  5.  Какая команда позволяет осуществлять циклическое перемещение от одного открытого окна к следующему?
  6.  Какая команда позволяет выполнять программу в режиме отладки с отслеживанием внутри функции?
  7.  Для чего служит команда Inspect?
  8.  Какая команда позволяет выполнять программу в режиме отладки, выполняя функцию за один шаг?
  9.  Какая команда позволяет удалить текст из окна не помещая его в текстовый буфер?
  10.  Для чего служит команда Arguments?
  11.  Какая команда позволяет копировать выбранный текст в текстовый буфер?
  12.  Какая команда позволяет заносить выбранный текст в текстовый буфер и удалять выбранный текст из окна?
  13.  Для чего служит команда Trace Into?
  14.  Какая команда позволяет отображать на экране кадр контекстной подсказки?
  15.  Какая команда позволяет осуществить переход к предыдущей ошибке?
  16.  Какая команда позволяет инициализировать программу?
  17.  Какая команда позволяет компилировать в OBJ-файл?
  18.  Какая команда позволяет выполнять программу?
  19.  Какая команда позволяет выполнять программу до строки, на которой установлен курсор?
  20.  Для чего служит команда DOS Shell?
  21.  Какая команда позволяет включить или выключить полный набор меню?
  22.  Какая команда позволяет регенерировать изображение на экране?
  23.  Какая команда позволяет сохранить файл под другим именем?
  24.  Для чего служит команда Get Info?


Лабораторная работа №2

Организация размещения данных при выводе на экран.
Использование функции
printf()

Цель работы: Научиться использовать функцию printf() для вывода на экран.

Теоретические сведения

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

#include <stdio.h>

int printf (char *format-string [, argument...]);

Функция формирует и печатает наборы символов и значений в стандартный выводной поток, stdout, которым по умолчанию является монитор. Format-string состоит из обычных символов, escape-последовательностей, и, если за format-string следуют аргументы, спецификации форматов. Обычные символы и escape-последовательности просто копируются в stdout (на монитор) в порядке их появления. Например, строка

printf(" Первая строка\n\t\t Вторая строка\n");

выводит

Первая строка

Вторая строка

Если за format-string следуют аргументы arguments, то format-string должна содержать спецификацию форматов, определяющих выводной формат для этих аргументов. Спецификации форматов начинаются с символа процента (%) и описываются ниже. Format-string считывается слева направо. Когда первая спецификация формата (если их несколько) встречается, значение первого аргумента после format-string преобразуется и выводится согласно спецификации формата. Вторая спецификация формата преобразует и выводит второй аргумент, и таким образом продолжается до конца format-string. Если задано больше аргументов, чем спецификаций формата, лишние аргументы игнорируются. Результат будет неопределенным, если нет достаточного количества аргументов для всех спецификаций форматов.

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

Более формально спецификатор % можно определить следующим образом:

%[flags] [width] [.precision] [l,L] type

Обязательными являются только символы «%» и type.

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

Символ формата type служит для указания типа выводимого значения и может принимать значения в соответствии с таблицей 2.1:

Таблица 2.1 – Символы формата

Символ type

Пример выводимого значения

Назначение

%c

?

Одиночный символ

%d

123

Десятичное целое число

%e

3.50000e+00

Число с плавающей точкой в экспоненциальном представлении

3.50000E+00

Число с плавающей точкой в экспоненциальном представлении

%f

3.500000

Число с плавающей точкой в десятичном представлении

%g

для числа 0.00314 – вывод 0.00314

для числа 0.0000314 –

вывод 3.14e-05

Число в форме f или e в зависимости от значения. Форма e используется, если показатель меньше чем -4 или больше либо равен заданной точности.

%G

Аналогично %g

То же, что и %g, но при выводе в экспоненциальной форме используется символ E.

%i

6

Десятичное целое число со знаком

%o

13

Восьмеричное целое число без знака

%p

5B74

Указатель (адрес памяти)

%s

Str

Строка символов

%u

18

Десятичное целое число без знака

%x

1f

Шестнадцатиричное целое число без знака
(с цифрами
a b c d e f)

%X

1F

Шестнадцатиричное целое число без знака
(с цифрами
A B C D E F)

%%

%

Печать знака процента

Все прочие элементы строки формата называются модификаторами и служат для уточнения формы представления информации при выводе.

Символы l или L используются для указания целых длинных типов.

Модификатор формата width (ширина) представляется целым положительным числом и служит для указания минимального количества выводимых символов. Если количество символов выводимого значения меньше width, поле будет дополняться символами в соответствии с указанными флагами. Значение width никогда не ограничивает выводимое значение.

Варианты элемента flags представлены в таблице 2.2.

Таблица 2.2 – Значения модификатора flags

Значение флага

Пример

Назначение

-

%-20s

Значение выравнивается по левому краю поля

+

%+d

Выводится знак значения - как плюс, так и минус

Пробел

% 6.2f

Положительные значения печатаются без знака, но с пробелом, отрицательные со знаком "минус"

0

%010d

%08.3f

Для числовых форм поле вывода заполняется по ширине нулями вместо пробелов. Этот флаг игнорируется, если указан флаг "-" или указана точность для целочисленной формы

#

%#o

%#8.0f

%+#10.3E

Вывод первого 0 для восьмеричных, 0x или 0X для шестнадцатиричных. Для всех форм с плавающей точкой гарантируется вывод символа десятичной точки. Для форм %g и %G предотвращается удаление заключительных нулей.

Модификатор формата .precision (точность) используется для чисел с плавающей точкой. Точность представляется неотрицательным целым числом, следующим за точкой и задает либо количество символов, которое должно быть выведено (для строк), либо количество цифр в дробной части числа (для значения с плавающей точкой), либо количество значащих цифр (для целого). Так "%5.2f" определяет вывод вещественного числа в поле шириной пять символов с двумя цифрами после десятичной точки.

Задание:

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

Контрольные вопросы

  1.  Как сделать видимой в программе функцию printf()?
  2.  Каковы параметры функции printf()?
  3.  Как задать длину выводимого значения?
  4.  Как задать точность выводимого значения?


Лабораторная работа №3

Ввод данных с клавиатуры
с использованием функции
scanf()

Цель работы: Научиться использовать функцию scanf() для ввода данных с клавиатуры.

Теоретические сведения

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

#include<stdio.h>

main()

{

int a;

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

scanf("%d", &a);

printf("\n Вы ввели число %d", a);

}

В этой программе помимо известной уже функции printf() содержится функция scanf(). Каждой вводимой величине, а их может быть несколько, в строке функции scanf() должен соответствовать спецификатор типа (для целых %d, для вещественных %f, для символьных %c, для строковых %s и др.). Перед именем переменной, которой присваивается вводимое значение, в строке функции scanf() должен стоять символ & (операция взятия адреса). Спецификаторы функции scanf() полностью совпадают со спецификаторами функции printf().

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

 #include<stdio.h>

 main()

 {

int a, b;

float c, d;

printf("\n Введите целые числа:");

scanf("%d,%d", &a, &b);

printf("\n Введите вещественные числа:");

 scanf("%f %f", &c, &d);

 printf("\n Вы ввели числа %d %d %f %f", a, b, c, d);

}

В данной программе при вводе целых чисел их необходимо разделять запятыми, а при вводе вещественных чисел - пробелами.

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


Задание:

  1.  Ввести при помощи одной функции scanf() следующие значения и вывести их на экран:

а) Целое, вещественное, символьное.

б) Вещественное, символьное.

в) Символьное, целое.

  1.  Вывести на экран с использованием функции printf() ASCII-код введенного символа.

Контрольные вопросы

  1.  Для чего служит функция scanf()?
  2.  Каков синтаксис функции scanf()?
  3.  Каковы особенности использования функции scanf()?


Лабораторная работа №4

Типы констант. Использование констант в языке С

Цель работы: Изучение использования констант различных типов в языке С.

Теоретические сведения

В языке С имеется четыре типа констант: целые, вещественные (с плавающей точкой), символьные и строковые.

Константы целого типа

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

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

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

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

Шестнадцатеричные цифры - это десятичные цифры от 0 до 9 и латинские буквы: a, b, c, d, e, f, или A, B, C, D, E, F.

Например: задание константы 3478 в десятичном, восьмеричном и шестнадцатеричном виде:

 int a = 3478,

 b = 06626,

 c = 0хD96;

К любой целой константе можно справа приписать символ l или L, и это будет означать, что константа - длинная целая (long integer). Символ u или U, приписанный к константе справа, указывает на то, что константа целая без знака (unsigned long).

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

Константы вещественного типа

Константы с плавающей точкой (называемые вещественными) состоят из цифр, десятичной точки и знаков десятичного порядка е или Е. Ниже приведены все возможные варианты записи констант вещественного типа:

 1. 2e1 .1234 .1e3

 .1 2E1 1.234 0.0035e-6

 1.0 2e-1 2.1e-12 .234

Cимвольные константы

Cимвольные константы заключаются в апострофы (кавычки). Все символьные константы имеют в (Турбо) С значение типа int (целое), совпадающее с кодом символа в кодировке ASCII.

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

Например: 

символ " апостроф " задается как '\'', переход на новую строку - как '\', а обратный слэш - как '\\'.

Каждая esc - последовательность должна быть заключена в кавычки.

Управляющие коды

\n Новая строка

\t Горизонтальная табуляция

\v Вертикальная табуляция

\b Возврат на символ

\r Возврат в начало строки

\f Прогон бумаги до конца страницы

\\ Обратный слэш

\' Одинарная кавычка

\" Двойная кавычка

\а Звуковой сигнал

\? Знал вопроса

\ddd Код символа в ASCII от одной до трех восьмеричных цифр

\xhhh Код символа в ASCII от одной до трех шестнадцатеричных цифр.

Строковые константы

Строковые константы состоят из нуля или более символов, заключенных в двойные кавычки. В строковых константах управляющие коды задаются с помощью esc - последовательности. Обратный слэш используется как символ переноса текста на новую строку.

Пример описания строковых констант:

# include <stdio.h>

main( )

{

char *str1, *str2;

str1=“ Пример использования\n\n”;

str2=“строковых\

констант.\n\n”;

printf(str1);

printf(str2);

}

Программа выведет следующий текст:

Пример использования

строковых констант.

Задание:

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

Контрольные вопросы

  1.  Константы каких типов приняты в С?
  2.  Какие целые константы вы знаете?
  3.  Как формируются восьмеричные константы?
  4.  Как формируются шестнадцатеричные константы?
  5.  Чем отличаются символьные и строковые константы?
  6.  Для чего используются esc-последовательности?


Лабораторная работа № 5

Работа с автоматизированной
обучающей системой
AOS_C

Цель работы: получить навыки в использовании основных операций и функций языка С в автоматизированной обучающей системе.

Теоретические сведения

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

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

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

В работе с АОС рекомендуется придерживаться следующей последовательности действий:

  1.  Установить курсор оболочки на директорию АOS_C.
  2.  Войти в директорию (нажав <Enter>).
  3.  Установить курсор оболочки на файл  c.exe.
  4.  Запустить файл (нажав <Enter>).
  5.  Выйти в меню выбора темы, нажав дважды пробел.
  6.  Выбрать заданную преподавателем тему (темы) для самостоятельной работы, используя клавиши управления курсором (стрелки) и <Enter> на основной клавиатуре, при этом отмеченные темы будут выделены синим цветом.
  7.  В случае неправильного выбора темы нажать дважды <ESC> и повторить п4-п7.
  8.  Нажать дважды <F10> для выхода в меню режима работы АОС.
  9.  Используя клавиши управления курсором на основной клавиатуре, выбрать режим работы АОС (<>).
  10.  Выбрать заданные преподавателем упражнения, используя клавиши управления курсором и <Enter>.
  11.  В случае неправильного выбора упражнения нажать несколько раз <F10> до выхода в меню выбора упражнений и повторить п10.
  12.  Нажать <F10> для начала работы.
  13.  Нажать <F2> и законспектировать теоретические сведения.
  14.  Выполнить предложенные АОС примеры.
  15.  Нажать <F1> и ввести полученные результаты.
  16.  Выписать в тетрадь для лабораторных работ 5 правильно выполненных заданий и ответы к ним.
  17.  В случае неправильного выполнения задания нажать дважды <F3>, найти в вычислениях ошибки, нажать <F4> и ввести новые.
  18.  Нажать <F10> для перехода в следующую тему или меню режима работы.
  19.  Нажать <> для выхода в меню выбора тем.
  20.  Нажать дважды <ESC> для выхода из АОС.
  21.  Представить отчет преподавателю.


Темы для самостоятельной проработки в АОС:

Тема

АОС

Тема

Упражнение

  1.  

Арифметические опера-ции, операции при-сваивания.

Операции

Операции присваивания

  1.  

Логические и условные операции.

Операции

  1.  Операции: логи-ческие и увеличения.
  2.  Операции отношения и условия.
  3.  Логические выра-жения.
  1.  

Управление, конструкции выбора.

Управление

  1.  Условный оператор IF-ELSE.
  2.  Переключатель (опе-ратор SWITCH)
  1.  

Управление, циклы

Управление

  1.  Операторы цикла WHILE и DO-WHILE
  2.  Оператор цикла FOR.

Пример работы с АОС:

Запустить программу и нажать несколько раз <Enter> до появления меню:

Выбрать тему «операции» и нажать дважды <F10>, до появления меню:

Нажать <>:

Выбрать «операции присваивания», нажать <F10>:

Вычислить предложенные упражнения, нажать <F1>, ввести результаты.

Следует заметить, что при выполнении заданий в некоторых разделах АОС  примеры программ могут не вмещаются на один экран, о чем сигнализирует надпись в нижнем правом углу после нажатия <F1>. Используя предложенные клавиши (Home,End, ,,PgUp, PgDown) можно просмотреть всё задание.

При необходимости повторить вычисления и ввод результатов:

Для выхода из АОС несколько раз нажать <F10> до появления меню выбора возможностей АОС, нажать <> (выход), и несколько раз <ESC>, до выхода в оболочку.


Лабораторная работа № 6

Работа с автоматизированной обучающей системой:
арифметические операции, операции пр
исваивания

Цель работы: получить навыки в использовании арифметических операций и операций присваивания языка С в автоматизированной обучающей системе.

Теоретические сведения

Арифметические операции

Числа можно складывать, вычитать, умножать и проделывать над ними другие действия, обозначаемые специальными знаками, называемые операциями; объект, на который действует операция, называется операндом.

Каждая операция определяет количество операндов, их типы и тип результата, при этом по количеству операндов операции делятся на следующие типы:

  •  унарные (имеющие один операнд);
  •  бинарные (имеющие два операнда);
  •  тернарные (имеющие три операнда).

К арифметическим операциям относят:

  •  унарные (+, -, ++, --);
  •  бинарные (+, -, *, /, %).

Унарные операции:

Унарный минус

Формат:  -E;

где E – выражение, имеющее тип signed, char, int, float, long, short, double, long double.

Результат операции по абсолютному значению совпадает с E, но имеет противоположный знак; тип результата совпадает с типом E.

Унарный плюс

Формат:  +E;

где E – выражение, имеющее тип signed, char, int, float, long, short, double, long double.

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

Инкремент и декремент

Формат: префиксная форма  ++E;  --E;

 постфиксная форма  E++;  E--;

где E – может быть переменной любого целочисленного типа, причем E обязательно должно быть переменной, а не константой, т.е. операции 1++ или --7 некорректны.

Операция инкремент (декремент) увеличивает (уменьшает) переменную на единицу, при этом префиксная запись изменяет переменную до её использования в выражении, а постфиксная – после.

Бинарные операции:

Формат:

E1 + E2; E1 – E2; E1 * E2;  E1 / E2; E1 % E2;

где E1 и E2 – выражения любого типа: целого или вещественного, кроме операции % - её операндами могут быть только выражения целого типа.

Результат имеет такой же тип, как и у операндов. Если тип левой и правой части различны, то тип правой приводится к типу левой.

Специфической операцией является «%», которая называется операцией  определения остатка от деления. Её операнды всегда должны иметь целый тип; знак результата совпадает со знаком E1, если используются знаковые числа.

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

Операции простого присваивания

Формат: E1 = E2;

При выполнении операции переменная E1 получает значение выражения E2, тип и значение результата операции совпадают с типом и значением E2. Можно выполнять также многократные присваивания:

 E1=E2=E3=…=En=K;

где K – значение n переменных.

Операции присваивания могут применяться также и в правой части выражения:

 a = (b = c)*d;

где в правой части переменной b присваивается значение переменной c, затем это значение умножается на d и присваивается переменной a.

Составные операции присваивания

Формат:

E1+=E2;  E1–=E2;  E1*=E2;  E1/=E2;  E1%=E2;

где E1 – переменная любого типа; E2 – выражение того же типа.

При выполнении операции сначала вычисляется значение E2, а затем:

  •  для += E1 суммируется с E2 и результат заносится в E1;
  •  для –= из E1 вычитается E2 и результат заносится в E1;
  •  для *= E1 умножается на E2 и результат заносится в E1;
  •  для /= E1 делится на E2 и результат заносится в E1;
  •  для %= остаток от деления E1 на E2 и результат заносится в E1;
  •  результатом всей операции является новое значение E1.

Задание:

Пример работы с АОС:

Через ОПЕРАЦИИ | РЕЖИМ САМОСТОЯТЕЛЬНОЙ РАБОТЫ | ОПЕРАЦИИ ПРИСВАИВАНИЯ выйти к меню (вариант может отличаться):

Внимательно прочесть теорию (<F2>).

Вычислить предложенные примеры, например:

  1.  x+=1*8-8; PRINTX;

Следуя вышеизложенным правилам и учитывая, что x уже задано, вычисляем

1*8=8; 8-8=0; x=x+0;

таким образом

x=4;

Далее

  1.  x*=y=z=-3; PRINTX;

Здесь в правой части производится многократное присваивание, другими словами переменные z и y приравниваются -3

z=-3;  y=z;  x=x*y;

т.е.

x=-12;

  1.  x=-19!=-48; PRINTX;

Здесь, учитывая приоритет операций, сначала происходит сравнение на неравенство чисел –19 и –48, после чего значение выражения присваивается переменной x:

-19!=-48; (=1)  

т.е.   

x=1;

  1.  x>=(y=58); PRINTX;

Здесь сначала вычисляется выражение в правой части, а именно: переменной y присваивается значение 58. Далее происходит нестрогое сравнение значения x и значения y, при этом никого присваивания НЕ происходит (операция >=  - операция сравнения), таким образом, переменная x не изменяет своего значения

y=58;  x>y;  

т.е.

 x=1;

После того, как все предложенные программой задания будут вычислены, нажать <F1> и ввести полученные ответы, при этом программа, после ввода всех ответов, должна подтвердить правильность расчетов:

Контрольные вопросы

  1.  Какие действия выполняет операция «++» и над какими типами она может выполняться?
  2.  Как работает операция «%»?
  3.  Какое отличие между записями «х=+5;» и «x+=5;»?
  4.  Для чего применяются составные операции присваивания?


Лабораторная работа № 7

Работа с автоматизированной обучающей системой:
логические и усло
вные операции

Цель работы: получить навыки в использовании логических и условных операций языка С  в автоматизированной обучающей системе.

Теоретические сведения

Логические операции и операции увеличения

В языке С имеется три логические операции И, ИЛИ, НЕ.

Таблицы истинности этих операций приведены ниже:

И(&&)

ИЛИ(||)

НЕ(!)

0

1

0

1

1

0

0

0

0

1

1

0

1

1

1

0

Формат записи: E1&&E2;  E1||E2;  !E1;

где E1 и E2 – выражения целого или вещественного типа. Следует учесть то, что выражение считается равным 1, если оно не равно 0, другими словами, если значение какого либо выражения равно, например 21, то оно считается равным 1 или истинно. Аргументами логических операций могут быть также и аргументы типа char.

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

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

  •  если в конъюнкции (И) вычисленное выражение равно 0, то и вся конъюнкция считается равной нулю и дальнейшее вычисление прекращается;
  •  если в дизъюнкции (ИЛИ) вычисленное выражение равно 1, то и вся дизъюнкция считается равной 1 и вычисление прекращается.

Операции увеличения (или инкремент и декремент)

Подробно рассмотрены в лабораторной работе «Арифметические операции, операции присваивания».

Операции отношения

В языке С имеют место следующие операции отношения:

<  (меньше);

<=  (меньше либо равно);

==  (равенство);

!=  (не равно);

>=  (больше либо равно);

>  (больше).

Формат записи:

E1<E2; E1<=E2; E1==E2; E1!=E2; E1>=E2; E1>E2;

где E1 и E2 – выражения целого или вещественного типа, при этом результат имеет всегда тип int. 

Результат операции равен 1, если:

  •  для “<” E1 меньше E2;
  •  для “<=” E1 не больше E2;
  •  для “==” E1 равен E2;
  •  для “!=” E1 не равен E2;
  •  для “>=” E1 не меньше E2;
  •  для “>” E1 больше E2,

в противном случае для каждой операции результат равен 0.

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

Условная операция ?: (тернарная операция)

Формат записи:

E1 ? E2 : E3;

где E1 – выражение целочисленного или вещественного типа; типы E1 и E2 должны совпадать и могут быть любыми.

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

  •  если E1 отлично от нуля, то вычисляется выражение E2, и результатом всей операции будет E2, при этом выражение E3 игнорируется;
  •  если E1 равно нулю, то вычисляется E3, которое и будет результатом всей операции, при этом E2 вычисляться не будет.

Логические выражения

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

Порядок и направление выполнения операций

В выражении различные операции можно комбинировать. Рассмотрим некоторые из них.

Например, выражение 2+2*2 будет равно 8 или 6? Операции, приведенные в таблице выше, будут вычислены раньше, или, как говорят, имеют более высокий приоритет, чем те, которые расположены ниже.

Рассмотрим ещё один пример: какой результат даст выражение 40/5*2? Приоритет выполнения операций “/” и “*” одинаков, но в зависимости от того, какая операция будет вычислена первой, в данном случае можно получить два ответа: 16 или 4. Таким образом, при выполнении  операций необходимо учитывать их направление: слева на право или наоборот. Эти данные также приведены в таблице.

Операция

Направление

!, - (унарный), +(унарный), ++, --

Справа налево    

*, /, %

Слева направо   

<, <=, >, >=

Слева направо   

==, !=

Слева направо   

&&

Слева направо   

||

Слева направо   

? :

Справа налево    

=,+=,-=,*=,/=,%=

Справа налево    

Таким образом, при выполнении операций слева направо, первой из двух, имеющих одинаковый приоритет, будет выполнена левая операция, при выполнении справа налево – правая.


Задание:

Пример работы с АОС:

Через ОПЕРАЦИИ | РЕЖИМ САМОСТОЯТЕЛЬНОЙ РАБОТЫ | (ОПЕРАЦИИ: ЛОГИЧЕСКИЕ И УВЕЛИЧЕНИЯ + ОПЕРАЦИИ ОТНОШЕНИЯ И УСЛОВИЯ + ЛОГИЧЕСКИЕ ВЫРАЖЕНИЯ) выйти к меню (цифры могут отличаться):

Внимательно прочесть теорию (<F2>).

Вычислить предложенные примеры, например:

  1.  PRINT(x||y||!z);

Следуя вышеизложенным правилам и учитывая, что x, y, z уже заданы, имеем:

0||0||!2 т.е. 0||0||0, что равно 0.

  1.  z=++x + 2; PRINT(x); PRINT(z); 

имеем: z = 5 + 2 (x=5 при вычислении, т.к. префиксная форма записи указывает на инкремент до использования переменной в выражении). При выполнении этой строки переменные x и z принимают значения, равные 5 и 7 соответственно.

Значение последней строки равно –2, проверьте.

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

Для перехода к следующей теме («Операции отношения и условия») нажать <F10>.

Переписать задание и ответы в тетрадь для лабораторных работ и перейти к выполнению следующего задания (нажать любую клавишу). Таким образом выполнить все предложенные задания. Для перехода к следующей теме (Логические выражения) нажать <F10>:

Контрольные вопросы

  1.  Перечислите, какие логические операции вы знаете, и над какими типами выражений они могут производиться?
  2.  В чем заключается правило усечения?
  3.  Какие действия выполняет операция «++» и над какими типами она может выполняться?
  4.  Чем отличается запись ‘X=Y’ от ‘X==Y’?
  5.  Перечислите последовательность выполнения операций в выражении
    z-=x<=y?++x:--y и обоснуйте ответ.
  6.  При каком значении x в выражении --x&&++y&&++z; значение переменной y не изменится?


Лабораторная работа №8

Операторы и операции

Цель работы: Изучение арифметических, логических операций и операций отношения и присваивания.

Теоретические сведения

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

В операторе присваивания используется операция присваивания = ,

Например:

 c = a * b;

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

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

Например: оператор:

 if ( ( c = cube( a * b ) ) > d )

 ...

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

К понятию оператора вплотную примыкает понятие операции.

Различают следующие группы операций С: арифметические операции, операции отношения, операции присваивания, логические операции, побитовые операции, операция вычисления размера (sizeof) и операция следования (запятая).

Арифметические операции

К арифметическим операциям относятся: сложение (+), вычитание (-), деление (/) , умножение (*) и остаток (%). Все операции (за исключением остатка) определены для переменных типа int , char , float. Остаток не определен для переменных типа float. Все арифметические операции с плавающей точкой производятся над операндами двойной точности.

Операции отношения

В языке определены следующие операции отношения: проверка на равенство (==), проверка на неравенство (!=), меньше (<), меньше или равно (<=), больше (>), больше или равно (>=).

Все перечисленные операции вырабатывают результат типа int. Если данное отношение между операндами истинно, то значение этого целого - единица, а если ложно, то нуль.

Все операции типа больше-меньше имеют равный приоритет, причем он выше , чем приоритет операций == и !=. Приоритет операции присваивания ниже приоритета всех операций отношений. Для задания правильного порядка вычислений используются скобки.

Логические операции

В языке имеются три логические операции:

&& операции И (and)

|| операции ИЛИ (or)

! отрицание

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

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

Вычисление выражений, содержащих логические операции, производится слева направо и прекращается (усекается), как только удается определить результат. Если выражение составлено из логических утверждений (т.е. выражения, вырабатывающие значения типа int), соединенных между собой операцией И (&&), то вычисление выражения прекращается, как только хотя бы в одном логическом утверждении вырабатывается значение нуль. Если выражение составлено из логических утверждений, соединенных между собой операцией ИЛИ (||), то вычисление выражения прекращается, как только хотя бы в одном логическом утверждении вырабатывается ненулевое значение.

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

if( i > 50 && j == 24)

 ...

 if( value1 < value2 && (value3 > 50 || value4 < 20) )

 ...

Операции присваивания

К операциям присваивания относятся =, +=, -=, *= и /=, а также префиксные и постфиксные операции ++ и --. Все операции присваивания присваивают переменной результат вычисления выражения. Если тип левой части присваивания отличается от типа правой части, то тип правой части приводится к типу левой.

В одном операторе операция присваивания может встречаться несколько раз. Вычисления производятся справа налево.

Например:

a = ( b = c ) * d;

Вначале переменной d присваивается значение с, затем выполняется операция умножения на d, и результат присваивается переменной а.

Операции +=, -=, *= и /= являются укороченной формой записи операции присваивания. Их применение проиллюстрируем при помощи следующего описания:

 a += b означает a = a + b.

 a -= b означает a = a - b.

 a *= b означает a = a * b.

 a /= b означает a = a / b.

Префиксные и постфиксные операции ++ и -- используют для увеличения (инкремент) и уменьшения (декремент) на единицу значения переменной.

Семантика указанных операций следующая:

++a увеличивает значение переменной а на единицу до использования этой переменной в выражении.

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

--a уменьшает значение переменной а на единицу до использования этой переменной в выражении.

a-- уменьшает значение переменной а на единицу после использования этой переменной в выражении.

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

Например:

 printf ( "\nРазмер памяти под целое %d", sizeof( int) );

 printf ( "\nРазмер памяти под cимвол %d", sizeof( сhar) );

Задание:

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


Лабораторная работа № 9

Работа с автоматизированной обучающей системой:
условный оператор
IF-ELSE

Цель работы: получить навыки в использовании операций управления языка С в автоматизированной обучающей системе.

Теоретические сведения

В программировании часто встречаются такие ситуации, когда выполнение какого-нибудь действия зависит от определённых условий. Для разрешения этой проблемы в языке С существуют условные операторы if и switch.

Операторы if, ifelse

Формат: if (условие) оператор

    [else оператор]

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

Следует обратить внимание на то, что условие обязательно заключается в круглые скобки!!!

В некоторых случаях возникает необходимость в совместном использовании нескольких операторов if, что может привести к неоднозначности типа «висящего else». Например:

if (условие1) if (условие2) else оператор

Подобную запись можно интерпретировать двояко: else выполняется при невыполнении условие1 либо условие2. Для устранения этой неоднозначности существует правило:

else всегда относится к ближайшему if.

Таким образом, в нашем случае, ветвь else выполнится при невыполнении условие2.

Задание:

Пример работы с АОС (см. также л.р. «Работа с автоматизированной обучающей системой»): Через УПРАВЛЕНИЕ | РЕЖИМ САМОСТОЯТЕЛЬНОЙ РАБОТЫ | УСЛОВНЫЙ ОПЕРАТОР IF-ELSE + ПЕРЕКЛЮЧАТЕЛЬ (ОПЕРАТОР SWITCH) выйти к меню

Внимательно прочесть теорию (<F2>).

Вычислить предложенные примеры, например:

  1.  if (y!=1) x=36; else x=34;

Начинается с проверки условия (y!=1) результат проверки которой равен 0, т.к. y=1, следовательно результатом всей строки будет x=36 .

  1.  if (y<=1) if (y==1) x=18; else x=20;  

Начинается с проверки условия (y<=1), т.к. в данном случае оно выполняется, происходит переход ко второй части строки: if (y==1) x=18; else x=20; в которой условие (y==1) выполняется (т.к. у=1). Следовательно, выполняется присваивание x=18 и дальнейшее выполнение строки прекращается. Следующие строки программы выполняются аналогично.

Следует заметить, что при выполнении заданий в этом разделе АОС, примеры программ, как правило, не помещаются на один экран, о чем сигнализирует надпись в нижнем правом углу после нажатия <F1>. Используя предложенные клавиши (Home ,End, ,, PgUp, PgDown) можно просмотреть всё задание.

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

Контрольные вопросы

  1.  Что может выступать в операторе ifelse в качестве условия?
  2.  Когда возникает неоднозначность типа «висящего else»?


Лабораторная работа №10

Программирование с использованием оператора if-else

Цель работы: Изучить оператор if-else и ознакомиться с правилами его использования в программах.

Теоретические сведения

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

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

Это указание естественно сформулировать с использованием отношения X>Y: если это отношение при текущих значениях X и Y справедливо, то для исполнения должен выбираться оператор Z=Y (при X = Y безразлично, какой оператор выполнять, так что выполнение в данном случае оператора Z=Y дает правильный результат).

Для задания подобного рода разветвляющихся вычислительных процессов служит условный оператор.

Синтаксис оператора:

   Вариант 1

   if(<выражение>) <оператор>

Если <выражение> определено и не равно 0 , то выполняется <оператор>.

   Вариант 2

   if(<выражение>)

      <оператор1>

   else

      <оператор2>

Если <выражение> определено и не равно 0 , то выполняется <оператор1>,иначе (т.е. если <выражение> равно нулю) выполняется <оператор2>.

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

  if (X<Y)

     Z=X;

  else

     Z=Y;

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

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

При формулировании алгоритма типичной является такая ситуация, когда на определенном этапе вычислительного процесса какие-либо действия надо выполнить при выполнении некоторого условия, а если это условие не выполняется, то на данном этапе вообще не нужно выполнять никаких действий. Простейшим примером такой ситуации является замена текущего значения переменной X на абсолютную величину этого значения: если X<0, то необходимо выполнить оператор присваивания X=-X: если же X>=0 , то текущее значение X должно оставаться без изменений, т.е. на данном этапе вообще не нужно выполнять каких-либо действий.

В таких ситуациях удобна сокращенная форма условного оператора.

Рассмотрим, к примеру, такую задачу:

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

#include <stdio.h>

#include <math.h>

main()

{

double Angle,Result = 0;

printf("Введите значение переменной :");

scanf("%lf",&Angle);

if(Angle >= 0)

 {

 Result=sqrt(Angle);

 printf("Квадратный корень = %lf",Result);

 }

}

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

#include <stdio.h>

 #include <math.h>

main()

{

double Angle,Result=0;

 printf("Введите значение переменной :");

scanf("%lf",&Angle);

 if(Angle >=0)

  {

  Result=sqrt(Angle);

  printf("Квадратный корень = %lf",Result);

  }

else

  printf("Квадратный корень из %lf не извлекается", Angle);

}

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

Примечания:

1. Ключевые слова else или if могу иметь только по одному оператору, причем он может быть простым или составным. Все другие операторы будут интерпретироваться как независимые.

Например, конструкция

if(<выражение>)

 <оператор1>

 <оператор2>

else

 <оператор3>

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

if(<выражение>)

  {

  <оператор1>

  <оператор2>

  }

else

  <оператор3>

2. Внутри одного блока каждое ключевое слово else относится к первому из предшествующих if, которое еще не имеет соответствующего else.

Например:

if(<выражение1>)

  if(<выражение2>)

     {

     <оператор3a>

     <оператор3b>

     }

  else

     {

     <оператор4a>

     <оператор4b>

     }

эквивалентна следующей:

if(<выражение1> && <выражение2>)

 {

 <оператор3a>

 <оператор3b>

 }

if(!<выражение1> && !<выражение2>)

 {

 <оператор4a>

 <оператор4b>

 }

3. В сложных конструкциях, содержащих много if и else, иногда явно указываются все else, после которых ставится пустой оператор.

Например, выражение

if(<выражение1> && <выражение2>)

 {

 <оператор3a>

 <оператор3b>

 }

if(!<выражение1>)

 {

 <оператор4a>

 <оператор4b>

 }

можно записать так:

if(<выражение1>)

if(<выражение2>)

    {

    <оператор3a>

    <оператор3b>

    }

else

   ;

else

{

<оператор4a>

<оператор4b>

}

4. При формировании условного выражения следует обращать внимание на приоритет операций.

5. Следует помнить, что проверка на равенство осуществляется с помощью оператора ==, а оператор = в условном выражении интерпретируется как оператор присваивания. Обращайте внимание на предупреждения компилятора, которые указывают на условное выражение в операторе if.

Задание:

  1.  Составить программу для вычисления величины x=2a+b-1, если a>=b, і х=а+0.64*102*b в противном случае.
  2.  Составить программу для вычисления величины y=x3, где x=abc при условии, что a+b/c равно нулю, и x=(a+b)c, если a+b/c меньше 0. Если a+b/c больше 0, вывести сообщение о том, что решений нет.
  3.  Составить программу для вычисления величины у=x3-24x, если число x принадлежит отрезкам [a,b] и [c,d]; y=3x/x3, если x принадлежит отрезку [a,b], но не принадлежит отрезку [c,d].

 *** Все значения величин должны быть введены с клавиатуры. ***

Контрольные вопросы

  1.  Каков синтаксис и алгоритм выполнения оператора if?
  2.  Каков синтаксис и алгоритм выполнения оператора ifelse?
  3.  В чем основное отличие операторов  if и ifelse?
  4.  Каковы особенности использования условных операторов?


Лабораторная работа №11

Использование конструкций выбора switch

Цель работы: научиться использовать при программировании на С конструкцию switch.

Теоретические сведения

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

if (выражение = =значение1)

оператор1;

else  if  (выражение= =значение2)

оператор2;

else    /*необязательно*/

оператор_умолчания          /*необязательно*/  ;

Конструкцию  можно  сократить  с  помощью  оператора  switch:

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

case значение1 :     /* выполняется    if (выражение = =значение1)*/

break ;                      /* выход  из  оператора  switch*/

case значение2 :   /* выполняется   else   if (выражение= = значение1)*/

break  ;                    /* выход  из  оператора  switch */

default  :                 

На первый взгляд эта запись может показаться длиннее, но на практике оператор switch использовать проще, чем эквивалентную конструкцию if-else. За ключевым словом switch следует выражение, которое будет сравниваться с множеством значений внутри блока switch. Селекторы case сравнивают выражение с заданными значениями . Cтрока

case значение1:

сравнивает значение1 с результатом вычисления выражения оператора switch. Если результат сравнения дает значение “истина”, то будет выполнен оператор (или блок операторов), следующих за строкой case. Если же результатом сравнения будет “ложь”, аналогичным образом будет обрабатываться следующая строка case. Последняя строка оператора switchdefault- необязательная строка выбора. Она задает действия, выполняемые в случае, если ни одно из значений строк case не совпало со значениями выражениями оператора switch.

Листинг программы, создающей меню выбора:

# include <stdio.h>

# include <ctype.h>

main( )

{int choice;

printf(“ Menu: A(dd  D(elete  S(ort  Q(uit :“);

choice=toupper(getchar()); /*Функция toupper() переводит символ в верхний регистр
    (делает прописным)*/

  switch(choice){

          case  A:  printf  (“You  selected  Add \n”);

                        break;

          case  D: printf  (“You  selected  Delete\n”);

                         break;

           case  S: printf  (“You  selected  Sort \n”);

                        break;

           case  Q: : printf  (“You  selected  Quit \n”);

                         break;

           default  :  printf  (“\n illegal  choice !!!\n”);

   }

  return  choice;

}

Задание:

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

Контрольные вопросы

  1.  Опишите конструкцию оператора switch.
  2.  Для чего служит оператор default?
  3.  Какова функция селектора case?
  4.  Для чего служит оператор break?


Лабораторная работа № 12

Работа с автоматизированной обучающей системой:
операторы цикла
WHILE и DO-WHILE, оператор цикла FOR

Цель работы: получить навыки в использовании операторов цикла языка С в автоматизированной обучающей системе.

Теоретические сведения

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

Язык С поддерживает два оператора цикла, первый из которых оператор while, который имеет две формы записи:

while (условие) [оператор];

и

do [оператор] while (условие);

где условие здесь имеет тот же смысл, что и операторе if.

В первой и второй формах оператора while оператор выполняется, пока условие не станет ложным, с одним отличием: в первом случае проверка производится до выполнения оператора, во втором – после. Другими словами, во второй форме записи тело цикла выполнится всегда как минимум один раз. Следует обратить внимание на то, что оператор или группа операторов должна модифицировать значения переменных, входящих в условие, для того, чтобы оно в конце концов приняло значение 0 и цикл прекратился.

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

Вторым оператором цикла в С является оператор for:

for ([оператор1]; [выражение]; [оператор2])

[тело_цикла];

где оператор1 – простой или сложный оператор, оператор2 – простой оператор; выражение – любое вычисляемое выражение; тело цикла – это простой или сложный оператор, который будет выполняться в цикле. Каждое из трёх выражений в заголовке цикла может быть опущено программистом или использовано как угодно.

Формально алгоритм выполнения оператора for записывается так:

  1.  Если оператор1 присутствует, то он выполняется;
  2.  Вычисляется выражение, если оно вырабатывает 0, то цикл прекращается, в противном случае цикл будет продолжен;
  3.  Исполняется тело цикла;
  4.  Вычисляется оператор2, если присутствует;
  5.  Переход к пункту 2.

Появление в любом месте цикла оператора continue приводит к немедленному переходу к шагу 4.

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

Следует заметить также, что отсутствие в заголовке цикла оператор1 или выражение не означает отсутствия знака `;` после него.

Как правило, в цикле for оператор1 используется для инициализации переменной цикла, выражение – для проверки на окончание цикла, а оператор2 – для модификации переменной цикла.

Нетрудно заметить, что оператор for является упрощённой формой записи оператора while:

[оператор1];

while ([оператор2])

{[тело цикла];[оператор3];}

Простейшим примером использования цикла for может служить программа вывода всех четных чисел от 106 до 0 в порядке убывания:

#include <stdio.h>

void main(void)

{long i;

for (i=1E6;i>=0;i-=2)

printf("\n%ld",i);

}

Эту же программу можно записать, поместив все действия в заголовок цикла:

#include <stdio.h>

void main(void)

{for (long i=1E6;i>=0;printf("\n%ld",i),i-=2);}

Задание:

Пример работы с АОС (см. также л.р. «Работа с автоматизированной обучающей системой»):

Через УПРАВЛЕНИЕ | РЕЖИМ САМОСТОЯТЕЛЬНОЙ РАБОТЫ | ОПЕРАТОРЫ ЦИКЛА WHILE И DO-WHILE + ОПЕРАТОР ЦИКЛА FOR выйти к меню (задания могут отличаться):

Внимательно прочесть теорию (<F2>).

Вычислить предложенные примеры, например:

первая строка с циклом while (y<10) ++y; будет выполняться пока у будет меньше 10. При у=10 произойдёт переход к оператору x-=y; в котором переменная х примет значение 4 (14-10).

В следующей строке while (y<11) x+=++y; цикл будет выполняться 10 раз. Очевидно, что при начальных x=1 и y=0 первое действие цикла можно записать как x=1+0, а последнее x=57+10. Таким образом, будет выведено значение x, равное 67 и y=11. Следующая строка do z-=y; while (++y<9); будет выполняться до тех пор, пока y будет меньше 9. При первом проходе вначале переменная z не будет уменьшена, т.к. y в этом случае равен 0. Далее происходит проверка условия (++y<9); после чего переменная y увеличивается на 1 и происходит возврат к оператору z-=y; где переменная z уже уменьшается на 1 и т.д.

Следует заметить, что при выполнении заданий в этом разделе АОС, примеры программ могут не помещаться на один экран, о чем сигнализирует надпись в нижнем правом углу после нажатия <F1>. Используя предложенные клавиши (Home, End, ,, PgUp, PgDown) можно просмотреть всё задание.

Переписать задание и ответы в тетрадь для лабораторных работ и перейти к выполнению следующего задания (нажать любую клавишу). Таким образом выполнить все предложенные задания. Для перехода к следующей теме («ОПЕРАТОР ЦИКЛА FOR») нажать <F10>:

Внимательно прочесть теорию (<F2>).

Вычислить предложенные примеры, например:

строка for (y=8; y>0; y--) x=y; будет выполняться до тех пор, пока значение переменной y будет больше 0. Очевидно, что при выходе из цикла переменная x будет равна 1, а y будет равна нулю, так как после выполнения y-- (при у=1) происходит переход к y>0, где вырабатывается значение 0 и цикл прекращается. Следующая строка for (y=12; (x=y)>1; y--) ; аналогична предыдущей, за одним исключением – присваивание (x=y) происходит при проверке условия, т.е. при выходе из цикла переменная x будет равна переменной y, а так как цикл закончится при y равном 1, то переменная x при выходе из цикла также примет значение 1.

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

Контрольные вопросы

  1.  Какое основное отличие в работе циклов while и dowhile?
  2.  Какой цикл называется бесконечным, когда он может возникнуть?
  3.  Что называется телом цикла?
  4.  Каков алгоритм выполнения оператора for?
  5.  Как можно прервать выполнение операторов цикла?
  6.  В чем заключается действие оператора break и оператора continue?


Лабораторная работа №13

Разработка и отладка программы циклического процесса
с использованием оператора
do-while

Цель работы: Научиться использовать на практике циклические процессы с использованием оператора do-while.

Теоретические сведения

Оператор do-while является в некотором роде перевернутым циклом while. Его формат выглядит следующим образом:

do

{

оператор;

}

while (выражение);

Выполняется оператор, затем проверяется выражение. До тех пор, пока значение этого выражения будет истинным, оператор будет выполняться. В отличие от while do-while всегда выполняет свои операторы, по крайней мере, один раз, т.к. проверка выражения осуществляется по завершении итерации цикла. Из этого следует основное правило, необходимое при выборе между while и do-while: если есть такое условие, при котором операторы не должны выполняться, то следует выбирать while, иначе - do-while.

Многооператорные циклы do-while записываются следующим образом:

do

{

оператор 1;

оператор 2;

...

оператор n;

}

while (выражение);

Следующий листинг использует do-while для счета от одного до десяти:

#include <stdio.h>

main()

{

int number=0;

printf(“Цикл do-while \n”);

do

 {

  ++number;

  printf(“%d \n”, number);

 }

while (number<10);

}

Для цикла do-while можно использовать любое средство проверки логического выражения. Чтобы продемонстрировать такую многогранность, ниже приводится пример, использующий цикл do-while для вывода на экран алфавита:

#include <stdio.h>

main()

{

int c;

printf(”Алфавит do-while \n”);

c=’A’-1;

do

{

 ++c;

 printf(“%c”, c);

 }

while (c<’Z’);

}

Выражение c<’Z’ истинно, если ASCII-значение текущего символа меньше ASCII-значения буквы ‘Z’.

Задание:

  1.  Написать с использованием цикла do-while программу, вычисляющую F=1+x/1!+x2/2!+...+xn/n!. Закончить членом, который не превосходит E=10-6.
  2.  Написать программу с использованием цикла do-while, которая ожидает нажатия клавиши ‘!’ и по нажатии её завершает работу.

Контрольные вопросы

  1.  Каковы особенности использования оператора цикла do while?
  2.  В каком случае используется оператор do while вместо while?


Лабораторная работа №14

Помещение тела цикла for в заголовок

Цель работы: ознакомиться с особенностями цикла for и научиться помещать простое тело цикла в заголовок.

Теоретические сведения

Циклы (итерационные структуры) позволяют повторять выполнение отдельных операторов или групп операторов.

Число таких повторений в некоторых случаях фиксировано, в других случаях определяется в процессе счета.

Наиболее общей формой цикла в С является

for ( [необязательное выражение1; необязательное выражение 2; необязательное выражение 3] );

оператор;

Каждое выражение в заголовке цикла можно опускать. Хотя в принципе каждое выражение может быть использовано программой как угодно, обычно 1–е выражение служит для инициализации переменной цикла, 2-е выражение служит для проверки на окончание цикла, 3-е - для изменения значения переменной цикла.

Формально алгоритм for можно описать так :

  1.  Если 1-е выражение присутствует , то оно вычисляется .
  2.  Вычисляется 2-е выражение , если оно вырабатывает значение 0, то цикл прекращается .
  3.  Исполняется тело цикла.
  4.  Вычисляется 3-е выражение.

Появление оператора continue приводит к немедленному переходу к шагу 4.

Цикл for можно свести к циклу while следующим образом :

for (выражение 1; выражение 2; выражение 3);

оператор;

приводится к:

выражение 1;

while ( выражение 2);

{ оператор;

выражение 3;

}

Поскольку все 3 выражения в цикле for можно опустить, то

for ( ; ; )

;

представляет собой бесконечный цикл.

Листинг программы, отображающей ASCII-символы

# include <stdio.h>

main()

{ unsigned char c;

for (c=32; c<128; c++)

{ if ((c%128)= =0 )

printf (“%c”, c);

 }

 return 0;

}

Тело цикла можно поместить в заголовок цикла.

Пример:

Программа, выводящая четные числа от 10 до 0

# include <stdio.h>

main ()

{ int i;

for (i=10; i>=0;i-=2)

printf (“\n %d “,i);

}

Эту программу можно записать, поместив все действия  в заголовок :

#include <stdio.h>

main ()

{

int i;

for (i=10; i>=0; printf (“\n %d “,i),i-=2)

;

}

Задание:

  1.  Написать программу, вычисляющую сумму квадратов чисел от 1 до 100.
  2.  Написать программу, вычисляющую факториал числа N (N!).
  3.  Написать программу, определяющую все четные и ненулевые числа от -23 до 23, и выводящую их на экран.

Контрольные вопросы

  1.  Что такое цикл?
  2.  Для чего служат выражения в заголовке цикла for?
  3.  Для чего служит оператор continue?
  4.  Как можно поместить тело цикла в заголовок?


Лабораторная работа №15

Одномерные массивы

Цель работы: Изучение приемов объявления и обращения к массивам, использования директивы define при работе с массивами.

Теоретические сведения

Массивы – это набор объектов одинакового типа, доступ к которым осуществляется прямо по индексу в массиве. Обращение к массивам в С осуществляется и с помощью указателей.

Массивы можно описывать следующим образом:

тип_данных имя_массива [ размер массива ];

Используя имя массива и индекс, можно адресоваться к элементам массива:

имя_массива [ значение индекса ]

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

Вот несколько примеров описания массивов:

char name [ 20 ];

int grades [ 125 ];

float income [ 30 ];

double measurements [ 1500 ];

Первый из массивов ( name ) содержит 20 символов. Обращением к элементам массива может быть name [0], name [1], ...,name[19].

Второй массив ( grades ) содержит 125 целых чисел. Обращением к элементам массива может быть grades [0],grades [1],...,grades[124].

Третий массив ( incomе ) содержит 30 вещественных чисел. Обращением к элементам массива может быть income [0], incom[1],...,income[29].

Четвертый массив (measurements) содержит 1500 вещественных чисел с двойной точностью. Обращением к элементам массива может быть measurements[0], measurements[1],...,measurements[1499].

/* Программа, иллюстрирующая использование массивов */

/*Файл array.с*/

#include <stdio.h>

#define size 1000

int data [size];

main ( )

{

extern float average (int a[ ], int s );

int i;

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

data [ i ]= i;

printf ( “\nСреднее значение массива data =%f\n”,average (data,size));

}

float average (int a[ ] ,int s )

{

float sum=0.0;

int i;

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

sum+=a[ i ];

return sum/s;

}

В программе заводится массив на 1000 целых чисел. При помощи функции average подсчитывается сумма элементов этого массива. Первым формальным параметром функции average является массив. В качестве второго параметра функции передается число суммируемых значений в массиве a. Обратите внимание на использование константы size (размер). Если изменяется размерность массива, задаваемая этой константой, то это не приводит к необходимости менять что-либо в самом коде программы. 

Задание:

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

Контрольные вопросы

  1.  Что такое массив?
  2.  Как задать массивы разных типов?
  3.  Как осуществлять доступ к элементам массива?
  4.  Как задать размерность массива с помощью директивы define?


Лабораторная работа №16

Программирование с использованием указателей

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

Теоретические сведения

Указатель – это переменная, которая содержит в памяти адрес данных. Переменная-указатель содержит местоположение значения. То есть, переменная-указатель указывает на значение, так как она содержит его адрес.

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

Суть переменных-указателей

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

Единственная разница между обычными переменными и указателями заключается в их содержимом. Указатели содержат не само значение, а его адрес.

В С имеет два оператора, относящихся к указателям:

& - оператор "адрес значения"

* - оператор "значение по адресу"

Объявление указателей

Если нужно объявить переменную для хранения, например, возраста, то можно сделать это следующим образом:

int age = 20;

Такое объявление переменной age подразумевает несколько моментов. Во-первых, сообщается С, что нужна переменная с именем age, и С резервирует для этой переменной место в памяти. Во-вторых, С узнает, что age будет использоваться для хранения только целых чисел. В-третьих, при объявлении эта переменная инициализируется значением 20.

Пусть нужно объявить переменную-указатель, которая не содержит возраст, а указывает на age, переменную, где находятся нужные данные. Для объявления указателя на переменную age нужно сделать следующее:

int *p_age;

В этой строке резервируется место для переменной с именем p_age. Однако это не обычная целочисленная переменная. Так как перед ней стоит *, С определит, что это переменная-указатель.

Присваивание значений указателям

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

p_age=&age;

Вместо занесения адреса переменной age в переменную p_age при помощи оператора присваивания можно одновременно объявлять и инициализировать указатели.

int age=20;

int *p_age=&age;

Можно присваивать различные значения переменной age следующим оператором:

age=35;

Либо можно сделать то же самое другим путем:

*p_age=35;

Эта строка подразумевает "взять ячейку памяти, на которую указывает p_age и занести туда значение 35".

Объявление массивов указателей

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

int *iptr[10];

Можно присвоить адрес любому элементу из iptr таким же образом, как и любому другому указателю, не входящему в массив:

iptr[4]=&age;

В следующей строке резервируется массив из 20 указателей на переменные символьного типа:

char *cpoint[20];


Задание:

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


Контрольные вопросы

  1.  Какие типы переменных резервируются в каждом следующем случае?

int *a;

char *c;

float b;

  1.  Что означает запись:

*p_age=35;?


Лабораторная работа №17

Строковые константы и символьные массивы

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

Теоретические сведения

Любая строка символов или одиночный символ, заключенный в двойные кавычки, интерпретируется как строковая константа. Двойные кавычки не являются частью строковой константы. Они выделяют строку и сообщают компилятору, что она является константой. Строку можно вывести на экран следующим образом:

puts(“Это строка”);

Все строковые константы заканчиваются двоичным нулем или нулевым символом ‘\0’, который компилятор добавляет в конец строки автоматически при задании строковой константы. Этот символ очень важен для компилятора, так как без него было бы неизвестно, где в памяти заканчивается строка.

В С не существует переменной строкового типа, но можно хранить строки в массивах символов. Например, можно создать массив для хранения имени:

char name[10];

Этот оператор резервирует в памяти место для хранения массива символов. Можно инициализировать строку, присвоив ей начальное значение при объявлении:

char name[10]=”Michael”;

Эта строка состоит из 7 значащих символов, однако в памяти она занимает 8 байт, так как компилятор добавляет в конец строки нулевой символ – ограничитель строки. Можно получить доступ к каждому отдельному элементу массива обычным способом, например:

name[3]=’k’;

Содержимое массива можно вывести на экран при помощи оператора:

puts(name);

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

Часто строки задаются при помощи указателей, например:

char *name;

Если в этом случае строка не инициализируется сразу же при объявлении, то требуется выделить память для ее хранения и инициализировать указатель следующим образом:

name=(char*)malloc(sizeof(char)*10);

После этого имя name можно использовать как обычный указатель, а также использовать его в многочисленных функциях манипуляции со строками, которые находятся в системной библиотеке string.h. При помощи этих функций можно копировать строки, сравнивать, присоединять одну строку к другой и выполнять множество других полезных действий.

Задание:

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

  1.  Подсчет числа символов в строке (без учета нулевого символа).
  2.  Сравнение двух строк, введенных пользователем.
  3.  Присоединение одной строки к другой (строки ввести с клавиатуры).
  4.  Удаление из строки лишних пробелов между словами.
  5.  Подсчет количества слов в строке.
  6.  Проверку, является ли строка палиндромом (палиндром – фраза, которая слева направо и справа налево читается одинаково без учета пробелов – «А роза упала на лапу Азора»).

Контрольные вопросы

  1.  Каковы отличительные признаки строковой константы?
  2.  Как включить символ двойной кавычки в состав строковой константы?
  3.  Как можно задать массив символов?
  4.  Как можно инициализировать символьный массив?
  5.  В каком случае имя массива можно использовать в функциях манипуляции со строками?


Лабораторная работа №18

Программирование с помощью функций.
Вызов функций и возврат из них

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

Теоретические сведения

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

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

main ( )

{

// 

//Код на C для ввода символов

// Код на C для сортировки символов в

// алфавитном порядке

// Код на C для вывода отсортированных

// символов на экран

//

return 0;

}

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

main ()

{

getletters(); // Вызов функции ввода букв

alphabetize(); // Вызов функции сортировки

// букв по алфавиту

printletters(); // Вызов функции вывода

// букв на экран

return 0; // Возврат в DOS

}

getletters ( )

{  // Код на C для ввода символов

return; // Возврат в функцию main() }

alphabetize ( )

{ // Код на C для сортировки символов в алфавитном

// порядке

return; // Возврат в функцию main() }

printietters ()

{ // Код на C для вывода отсортированных символов

// на экран

return; // Возврат в функцию main() }

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

Функция, написанная на C, обычно имеет следующие свойства:

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

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

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

Полная программа с функциями, написанная на Cи, это прояснит. Следующая программа, выводит на экран несколько сообщений. Выводимые сообщения определяются порядком вызова функций. В программе определены три функции: main(), next_fun() и third_fun(). Тело каждой из них заключено в фигурные скобки. В конце каждой функции стоит оператор return.

// Эта программа демонстрирует вызовы функций

#include <stdio.h>

void next fun (void)

// Вторая функция

{

puts( "Inside next fun()");

return; // Теперь управление возвращается функции main()

}

void third_fun (void) 

// Последняя функция, вызываемая в программе

{

puts( "Inside third_fun ()");

return;

}

main()

// main() — ВСЕГДА первая выполняемая функция

{

puts( "First function called main()");

next fun(); // Здесь вызывается вторая функция

third fun(); // Третья функция вызывается здесь

puts("main() is completed"); //Управление возвращается сюда

return 0; // Возврат управления в DOS 

}

Результаты выполнения этой программы следующие:

First function called main()

Inside next_fun()

Inside third_fun()

main() is completed

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

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

Для вызова функции нужно написать ее имя вместе с круглыми скобками, и после этого поставить точку с запятой. Этот знак ставится в конце каждого выполнимого оператора в Cи, а вызов функции является выполнимым оператором. В этом случае выполняется код функции, которую вызывали. Каждая функция может вызвать любую другую функцию. В рассмотренном примере только main () вызывала другие функции.

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

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

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

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

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

Задание:

  1.  Написать программу, в которой объявить глобальную переменную ival и присвоить ей значение 0. Написать в функцию inc_ival (), которая выводит значение ival на экран, инкрементирует эту переменную, а затем вызывает саму себя, если значение ival меньше 10. Когда функция вызывает саму себя, то это называется рекурсией. С позволяет выполнять рекурсивные вызовы. Написать функцию main( ), которая будет вызывать inc_ival().
  2.  Написать программу, которая выполняет сортировку глобального одномерного массива целых чисел по возрастанию любым методом. Программа должна содержать отдельные функции для ввода массива, сортировки и вывода отсортированного массива.

Контрольные вопросы

  1.  Это истина или ложь: в теле функции последней командой всегда должен быть оператор return?
  2.  Как называется функция, которая первой выполняется в программе, написанной на C?
  3.  Что лучше одна большая функция или несколько меньших? Почему?
  4.  Как отличить имя функции от имени переменной?
  5.  Где ошибка в следующем фрагменте программы? 

void cal_ it (void)

{ puts( "Getting ready to calculate the square of 25 ");

sq_25( )

{

puts( "The square of 25 is :”);

printf(“%d”,  25 * 25 );

 return; }

puts( "That is a big number! ");

 return;

}

  1.  Является ли следующий код именем функции, ее вызовом, ее определением или ошибочным выражением?

scan names ();


Лабораторная работа №19

Видимость переменных. Глобальные и локальные переменные.
Передача значений

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

Теоретические сведения

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

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

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

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

Определение области видимости переменных:

  1.  Можно определить переменную в пределах фигурных скобок, между которыми находится код программы (обычно в начале функции).
  2.  Можно определить переменную перед именем функции, такой как main( ).

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

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

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

Локальная переменная удаляется сразу после завершения блока, в котором она объявлена (то есть при достижении закрывающейся фигурной скобки). С всегда использует переменные, которые он видит как «самые локальные».

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

Необходимость передачи переменных

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

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

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

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

Функция, передающая параметры, называется вызывающей функцией. Функция, которая принимает эти аргументы (которые в ней называются параметрами), называется принимающей функцией. 

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

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

Передача значений

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

Передача по значению (или копированием)

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

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

Массивы и указатели всегда передаются по адресу.

Передача по адресу (или по ссылке)

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

При передаче переменной по адресу принимающей функции происходит копирование ее адреса, а не значения. В С все массивы передаются по адресу. Фактически, передается копия адреса массива.

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

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

Задание:

  1.  Написать программу, состоящую из трех функций – main(), fun1(), fun2(). В функции main() объявить символьный массив из 10 элементов. Заполнить его буквами от a до j в fun1() и вывести на экран в fun2().
  2.  Написать функцию, в которую передаются две целые переменные по адресу. В самой функции объявить третью локальную переменную. С ее помощью обменять значения двух переданных так, чтобы каждая из них имела бы значение другой при возврате управления в вызывающую функцию. Напечатать значения переменных до вызова и после вызова функции, а также их адреса.
  3.  Изменить программу сортировки из предыдущей лабораторной работы так, чтобы массив был локальным и передавался в вызываемые функции.

Контрольные вопросы

  1.  Какие типы переменных всегда передаются по адресу?
  2.  Какие типы переменных всегда передаются по значению?
  3.  Если переменная передается в функцию по значению и там изменяется, будет ли изменена переменная в вызывающей функции?
  4.  Если переменная передается в функцию по адресу и там изменяется, будет ли изменена переменная в вызывающей функции?


Лабораторная работа №20

Возвращение значения функцией

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

Теоретические сведения

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

Хорошим стилем программирования на С является описание прототипа каждой написанной функции. Прототипы гарантируют соответствие типов данных передаваемых параметров и возвращаемых значений функции.

Возвращаемые значения функции

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

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

return(возвращаемое_значение);

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

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

/* Вычисление среднего значения трех введенных  пользователем чисел */

#include <stdio.h>

float calc_av(int num1, int num2, int num3)

{

float local_avg; /* Содержит среднее значение этих чисел*/

local_avg=(num1+num2+num3)/3; 

return (local_avg);

}

main ( )

{

int num1, num2, num3;

float avg; /* Будет содержать возвращаемое значение */

puts(“ Введи три числа через пробел”);

scanf(“%d %d %d”, &num1, &num2, &num3);

/* Вызов функции, передача параметров и получение возвращаемого значения */

avg = calc_avg(num1, num2, num3);

printf (“\n Их среднее – это %f”, avg);

return 0;

}

Cледует обратить внимание на дополнительные моменты программы, связанные с тем, что функция возвращает значение. Начальная часть функции main() обычна. Описываются локальные переменные три для входных данных пользователя и одна для вычисленного среднего значения. Вызов функции calc_av () также обычен; он передает по значению три переменные num1, num2, num3 в функцию calc_av () (если бы функция принимала их по адресу, каждому аргументу должен был предшествовать амперсанд (&)).

Принимающая функция calc_av () выглядит так же, как и другие функции, за исключением первой строки – строки описания функции, которая имеет одно дополнение: ключевое слово float перед ее именем. Так указывается тип возвращаемого значения. Нужно всегда указывать тип возвращаемого функцией значения. Если тип не указан, С установит его по умолчанию как int, но от этого пострадает четкость программы.

Так как переменная local_avg, которая возвращается из функции calc_av (), является вещественной, именно ключевое слово float, означающее вещественный тип, помещено перед именем этой функции.

Нужно обратить внимание на то, что оператор возврата функции calc_av () включает возвращаемое значение local_avg. Эта переменная будет передана назад в вызывающую функцию main(). Можно возвратить только единственное значение в вызывающую функцию.

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

После того, как вызываемая функция calc_av () вернет значение, функция main() должна с ним что-либо сделать. До сих пор в строке располагались только сами по себе вызовы функций. В функции main( ) вызов функции расположен справа от знака присваивания:

avg = calc_avg(num1, num2, num3);

Когда функция calc_av () возвращает значение (среднее арифметическое трех чисел), то это значение как бы заменяет вызов функции. Если среднее арифметическое, вычисленное функцией calc_av (), равно 40, выполняемая программа «видит» такой оператор на месте вызова функции:

avg=40;

Вызов функции расположен справа от знака присваивания, но программа заменяет вызов функции на возвращаемое посредством оператора return значение. Другими словами, функция, которая возвращает значение, становится этим значением. Можно поместить такую функцию везде, где вы можете поместить любую переменную или константу данного типа обычно справа от знака присваивания или в выражении, или при выводе с помощью printf().

Такой способ вызова функции calc_av () является некорректным:

calc_av ( num1, num2, num3); 

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

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

Прототипы функций

Слово «прототип» при использовании его применительно к функциям является синонимом слова «модель». Прототип функции является моделью настоящей функции.

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

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

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

тип_возвращаемого_значения имя_функции (тип_ параметра имя_параметра, …);

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

Задание:

  1.  Написать программу, которая в функции main() запрашивает у пользователя число, которое передается в функцию fun1(). Эта функция возвращает ASCII – символ, соответствующий этому числу. Обеспечить контроль правильности ввода.
  2.  Используя предыдущую программу, вывести все печатные символы таблицы ASCII.
  3.  Написать программу, содержащую функцию, которая возвращает минимальный элемент переданного ей массива, если все элементы массива положительны, и максимальный элемент, если есть хотя бы один отрицательный.

Контрольные вопросы

  1.  Как объявляется тип возвращаемого функцией значения?
  2.  Какое максимальное количество значений функция может вернуть?
  3.  Назовите хотя бы одну причину использования файлов заголовка.
  4.  Как описание прототипов защищает программу от ошибок?
  5.  Почему нет необходимости возвращать глобальные переменные?


Лабораторная работа №21

Программирование с использованием рекурсивных функций

Цель работы: Научиться программировать на С, используя рекурсивные функции.

Теоретические сведения

В теле функции доступны все объекты, описанные в этой функции или как глобальные, в том числе и имя самой функции. Таким образом, внутри тела функции возможен вызов самой функции. Функции, использующие вызовы "самих себя", называют рекурсивными. Допустима также косвенная рекурсия, при которой, например, функция А вызывает функцию В, та, в свою очередь, вызывает С, которая вызывает первоначальную функцию А.

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

 double Factorial (int number)

 {

  if (number>1) return number*Factorial(number-1);

  reurn 1;

 }

Функция Factorial() возвращает значение типа double и объявляет единственный параметр number типа int. Функция начинается с оператора if, который проверяет значение параметра number. Если number больше 1, функция возвращает значение number, умноженное на факториал number-1.

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

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

 #include <stdio.h>

void A(int c);

void B(int c);

main()

{

 A(‘Z’);

 puts(“”);

}

void A(int c)

{

 if (c>’A’)

 B(c);

 putchar(c);

}

void B(int c)

{

  A(--c);

 }

Основная функция начинает рекурсию в строке 8, вызывая функцию А() с аргументом Z. Функция А() проверяет свой параметр с. Если с в алфавитном порядке больше A, то происходит вызов функции В(), которая немедленно вызывает опять-таки функцию А(), передавая ей предшественника параметра с. Это заставляет функцию А() снова проверить параметр с и снова вызвать В(), пока значение с не сравняется с A.

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

Задание:

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

Контрольные вопросы

  1.  Что такое рекурсия?
  2.  Какие виды рекурсии вам известны?
  3.  Что нужно иметь в виду, планируя рекурсивные вызовы?
  4.  Каковы механизмы рекурсивных вызовов и рекурсивных возвратов?


Лабораторная работа №22

Программирование с использованием структур

Цель работы: ознакомиться с понятием структуры в языке С и научиться применять структуры при написании программ.

Теоретические сведения

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

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

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

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

struct date {

 int day;

 int month;

 int year;

 int yearday;

 char monthname[4];

};

Описание структуры, состоящие из заключенного в фигурные скобки списка описаний, начинается с ключевого слова struct.

За ним может следовать необязательное имя (иногда называемое ярлыком структуры или тегом) – date. Такой ярлык именует структуры этого вида и его можно использовать в дальнейшем как сокращенную запись подробного описания.

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

Операция указания члена структуры «.» связывает имя структуры и имя члена.

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

 struct person{

  char name[ namesize ];

  char address [ adrsize ];

  long zipcode; /*почтовый индекс*/

  double salary; /*зарплата*/

  struct date birthday; /* дата рождения */

 struct date hiredate; /* дата поступления на работу */

};

Структура person содержит 2 структуры типа date. Если определить экземпляр структуры

struct person emp;

то

emp.birthdate.mouth

будет ссылаться на месяц рождения.

Операция указания члена структуры «.» ассоциируется слева направо.

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

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

 #define COMPLEX struct complex type

COMPLEX{

  float real;

  float image;

};

Такое макроопределение COMPLEX позволяет описывать комплексные переменные в естественной форме.

Если переменные с1, с2 и с3 описаны как комплексные, то операция умножения с1 на с2 для получения с3 может быть реализована следующим образом:

COMPLEX c1, c2, c3;

c3.real = c1.real * c2.real – c1.image*c2.image;

c3.image= c1.image*c2.real + c1.real*c2.image;

Структурную переменную можно инициализировать подобно переменным или массивам. Например, можно инициализировать структурную переменную типа COMPLEX следующим образом:

COMPLEX с1 = { 1.15; -3.1 };

Можно создать указатель на структуру, например:

COMPLEX *ptс1;

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

ptc1 = (COMPLEX*) malloc(sizeof(float*2));

Теперь к полям структуры, хранящейся по адресу ptc, можно получить доступ с помощью операции доступа к полям структуры по указателю ->:

ptc1->real = 12.5;

ptc1->image=-3.7;

Задание:

  1.  Задать структуру, определяющую дату. Ввести данные в эту структуру. Напечатать содержимое структуры.
  2.  Задать структуру, характеризующею книгу в библиотеке. Ввести данные в эту структуру. Напечатать содержимое структуры.

Контрольные вопросы

  1.  Что такое структура и для чего она служит?
  2.  Как описывается структура?
  3.  Как инициализируется структура?


Лабораторная работа №23


Массивы структур

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

Теоретические сведения

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

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

struct store

{

int employees;

int registers;

doublе sales;

}stores[1000];

При помощи этого кода быстро и компактно создается 1000 структур с информацией о магазинах, каждая из которых содержит 3 элемента. Обращение к элементам происходит следующим образом:

stores[8].sales=10;

или

(*(stores+8)).sales=10;

Двойные скобки требуются потому, что приоритет операции "." выше, чем "*".


Задание:

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

Контрольные вопросы

  1.  Для чего используются массивы структур?
  2.  Что такое тег?
  3.  Как происходит обращение к информации из элемента массива стуктур?


Лабораторная работа №24

Передача структур в функции и структуры
как возвращаемые значения функций

Цель работы: изучить правила передачи структур в функции и научиться использовать структурные переменные как возвращаемые значения функций.

Теоретические сведения

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

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

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

#include <stdio.h>

#include<string.h>

struct students{

char name[25];

int age;

float average;

};

struct students fill( students sv)

{

fflush(stdin);

puts(“Имя студента?”);

gets(sv.name);

puts(“Возраст студента?”);

scanf(“%d”, sv.age);

puts(“Средний балл?”);

scanf(“%f”, sv.average);

return (sv);

}

void pr (students sv)

{

puts(“Имя студента:”);

puts(cv.name);

puts(“Возраст студента:”);

printf (“%d\n”, sv.age);

puts(“Средний балл:”);

printf (“%f\n”, sv.average);

}

main()

{

struct students sv1, sv2;

sv1=fill(sv1);

sv2=fill(sv2);

puts(“Вот информация о студентах:”);

pr(sv1);

pr(sv2);

}

Из определения функции fill следует, что она должна возвращать значение, тип которого представляет собой struct students, и имеет один аргумент такого же типа. Две локальные переменные такого типа sv1 и sv2 объявляются в main(), а затем передаются в функцию fill() по значению, и изменения, которые происходят с ними в fill(), в main() не видны. Поэтому эти переменные нужно вернуть в вызывающую функцию.

Задание:

Задать структуру, определяющую работника для отдела кадров. Хранить поля: ФИО, год рождения, пол, оклад. Создать функцию, которая получает структурную переменную в качестве параметра и определяет размер пенсии работника (80% от оклада), если в текущем году он достиг пенсионного возраста (55 лет для женщин и 60 лет для мужчин).

Контрольные вопросы

  1.  Как правильно передать структурную переменную в функцию?
  2.  Для чего используют структуры как возвращаемое значение функции?


Лабораторная работа №25

Использование файлов в программе на C.
Функции fopen() и fclose()

Цель работы: научиться работать с файлами в программе на Cи.

Теоретические сведения

В стандартной библиотеке языка С существует специальный тип данных. Это тип FILE. Переменные этого типа данных используются для обращения к файлам. Описание функций для работы с файлами и типа FILE находятся в файле заголовка stdio.h.

Для того, чтобы производить какие-либо операции с файлом, его надо открыть. Это производиться с помощью функции fopen. Ее описание выглядит так:

FILE * fopen(char *path, char *mode);

Функция fopen принимает два параметра: path и mode:

path – имя открываемого файла;

mode – режим открытия файла.

Функция, получив необходимые параметры, производит открытие файла и заполняет поля структурной переменной типа FILE, указатель на которую она и возвращает. При этом эта функция производит самостоятельное выделение необходимого количества памяти под переменную. Так как чтение и запись происходят с определенной позиции, функция fopen модифицирует значение этой позиции в соответствии с режимом открытия. Если открытие файла не произошло по какой-либо причине, то функция fopen возвращает 0. Поэтому после ее вызова необходима проверка на успешное открытие файла.

Фрагмент кода, выполняющий открытие файла, будет иметь вид:

FILE *fl; // указатель на файловую переменную.

fl=fopen("somef.dat","w+"); // открытие файла somef.dat для чтения и записи

if(fl==0)

         {

         printf("\nПроизошла ошибка открытия файла somef.dat");

         return;

         }

Файл может быть открыт в следующих режимах:

r - открыть только для чтения. Позиция, с которой будет производиться чтение, устанавливается на начало файла.

w - создать для записи. Позиционирование на начало файла. Если файл существует,   он будет переписан.

a - добавление. Открытие для записи в конец файла. Создание, если файл не существовал.

r+ - открытие существующего файла для изменения (и чтение, и запись)

w+ - создание нового для чтения и записи. Если файл существует, он будет дописан.

a+ - идентично a.

Кроме того, файл может быть открыт в текстовом и двоичном режиме - это устанавливается добавлением к параметрам в строке mode следующих  букв: t-текстовый режим , b-двоичный режим. Например, строка mode может иметь вид: "rt" или "wt+", "w+t", "ab", и т.д.

Для записи используются такие функции:

int  fputc(int byte, FILE  *stream);

Запись байта byte в файл stream. Если файл был открыт для только чтения, то функция fputc не произведет записи в файл. Если запись не была успешной, то fputc возвращает EOF. Фрагмент программы, выполняющей запись байта в файл:

int c=90;

// fl - ранее успешно открытый файл

if (fputc (c, fl)==EOF)

     {

     printf("Невозможно записать файл");

     }

Когда требуется запись в файл строки, побайтовая запись оказывается невыгодной, для этого существует функция: fwrite.

size_t  fwrite(void  *ptr, size_t size, size_t n,FILE  *stream);

ptr - указатель на данные которые необходимо записать;

size - длина одной единицы данных;

n - количество единиц данных;

stream – файл, в который производится запись.

Функция fwrite записывает в файл stream  n единиц данных, каждая из которых имеет длину size, данные берутся по указателю ptr. Возвращается количество действительно записанных единиц.

Фрагмент программы, выполняющий запись в файл массива int длиной 10:

int array[10];

for(int c=0;c<10;c++) array[c]=c;

// fl- заранее открытый файл

if(fwrite(array,sizeof(int),10,fl)!=10)

    {

    printf("\nВо время записи произошла ошибка");

    };

// Можно также записать так

//if(fwrite(array,sizeof(int)*10,1,fl)!=10)

Иногда целесообразно использовать функцию fprintf.

int fprintf(FILE  *stream, char  *format, ...);

Ее действия полностью аналогичны действиям функции printf, с тем отличием, что printf выводит данные на экран, а fprintf в заданный параметром stream файл. Задание значений всех параметров, кроме значения stream, функции fprintf аналогично заданию значений параметров функции printf. В результате записи значение позиции в файле изменяется на количество записанных байт.

Для чтения одного байта из файла можно использовать функцию: fgetc.

int fgetc(FILE  *stream);

Эта функция читает байт из файла stream, и возвращает его. Позиция чтения сдвигается на 1. В случае ошибки чтения возвращается EOF.

int c;

// fl - заранее открытый файл

if((c=fgetc(fl))==EOF)

     {

     printf("Чего-то не читается");

     return;

     }

else

    {

    printf("Прочитан байт – значение:%d",c);

    }

Чтобы прочитать последовательность байт используется функция fread().

size_t  fread(void  *ptr, size_t size, size_t n,FILE *stream);

fread читает из файла stream n единиц данных, длиной size каждая, данные помещаются в память, начиная с адреса, сохраненного в указателе ptr. Функция не выделяет память под данные, потому ответственность за их размещение в памяти ложится на пользователя.

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

Задание:

  1.  Написать программу, производящую запись в файл с именем, заданным пользователем, массива типа int заданной длины, инициализированного пользователем.
  2.  Написать программу, производящую копирование одного файла, заданного пользователем, в другой файл, заданный пользователем.

Контрольные вопросы

  1.  Какая функция производит открытие файла, ее параметры?
  2.  Какая функция производит закрытие файла, ее параметры?
  3.  Какие существуют режимы открытия файла?
  4.  Какие существуют функции  записи?
  5.  Какие существуют функции чтения?


Лабораторная работа №26

Использование имени файла в качестве параметра командной строки

Цель работы: научиться получать и обрабатывать параметры командной строки

Теоретические сведения

В операционной системе МS DOS существует возможность запуска исполняемой программы с одним или несколькими параметрами. Каждый из этих параметров записывается после имени исполняемого файла. Все они разделяются пробелами. Например:

format a: /s

В данном случае программе format передаются два параметра: “a:” и /s”.

Язык программирования С позволяет получать и обрабатывать переданные в программу параметры. Для этого функция main() должна быть описана следующим образом (идентификаторы переменных могут быть другими):

[тип возвращаемого значения] main(int argc, char **argv);

где int argc – количество параметров, char **argv – указатель на строки, содержащие эти параметры. Следует отметить, что первым параметром всегда является полное имя исполняемого файла, к которому принадлежит функция main. Например, для приведенного выше вызова программы format переменные будут  иметь следующие значения: argc=3, *argv=”c:\dos\format.com”, *(argv+1)=”a:”, *(argv+2)=”/s” (путь к format.com может отличаться от приведенного).

Работа с параметрами функции main() ведется точно так же, как и с обычными параметрами функций языка С.

Очень часто параметром программы является имя файла. Например:

edit autoexec.bat

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

Задание:

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

Контрольные вопросы

  1.  Как задаются параметры в командной строке DOS?
  2.  Как должна быть описана функция main() для приема параметров?
  3.  Для чего в программу часто передается одним из параметров имя файла?


Лабораторная работа №27

Использование функций преобразования символов

Цель работы: научиться использовать функции преобразования символов.

Теоретические сведения

К функциям преобразования символов относятся следующие функции:

atoi – преобразование строки в целое число;

atof – преобразование строки в число с плавающей точкой;

atol – преобразование строки в длинное целое;

gcvt – преобразование значения с плавающей точкой в строку.

Все эти функции описаны в файле stdlib.h.

  1.  int atoi(char *str);

Получает ASCII строку и преобразует ее в значение типа int.

  1.  long atol(char *str);

Получает ASCII строку и преобразует ее в значение типа float.

  1.  float atol(char *str);

Получает ASCII строку и преобразует ее в значение типа long.

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

#include <stdio.h>

int main(void)

{

  int n;

  float f;

  char *str = "12345.67";

  n = atoi(str);

  f = atof(str);

  printf("string = %s integer = %d float = %f\n", str, n,f);

  return 0;

}

На экране будет такая строка:

string = 12345.67 integer = 12345 float = 12345.67

Обратное преобразование производится с помощью функций gcvt и ecvt;

  1.  char *ecvt (double value, int ndig, int *dec, int *sign);

value – число которое необходимо преобразовать в строку.

ndig – максимальное число знаков в результирующей строке.

dec – указатель на переменную типа int, в которую нужно произвести запись количества цифр слева от запятой.

sign – указатель на переменную типа int, в которую функцией производится запись 1, если value < 0, и 0, если value > 0

  1.  char *gcvt (double value, int ndec, char *buf);

Эта функция проще, чем ecvt. Она производит запись в память, начиная с адреса, сохраненного в указателе buf, числа value, переведенного в строку, ndec – максимальная длина строки.

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

#include <stdlib.h>

#include <stdio.h>

#include <conio.h>

int main(void)

{

  char *string;

  double value;

  int dec, sign;

  int ndig = 10;

  char str[25];

  double num;

  int sig = 5;

  value = -98.76;

  string = ecvt(value, ndig, &dec, &sign);

  clrscr();

  printf("string = %s      dec = %d sign = %d\n", string, dec, sign);

  num = -9.876;

  gcvt(num, sig, str);

  printf("string = %s\n", str);

}

На экране будет:

string = 9876    dec = 2 sign = 1

string = -9.876

Задание:

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

Контрольные вопросы

1. Какие существуют функции преобразования строки в число?

2. Какие существуют функции преобразования числа в строку?


СПИСОК РЕКОМЕНДОВАННОЙ ЛИТЕРАТУРЫ

  1.  Болски И. Язык програмування С. : Радио и связь, 1988. - 96 с.
  2.  Иванов А.Н. Язык программирования С : Предварительное описание / Прикладная информатика. - 1985. - Вып 1.-С.68. - 113.
  3.  Керниган Б., Ритчи Д. Язык программирования С. - М.: Финансы и статистика, 1992. -271 с.
  4.  Керниган Б., Ритчи Д., Фьюэр А. Язык программирования С. Задания по языку С. - М.: Финансы и статистика, 1985. -279с.
  5.  Кнут Д. Искусство программирования: в 3 т. - М., 1976. Т1. - 735с; 1978. Т3. 844с.
  6.  Г.П.Котлинская, О.И.Галиновский Программирование на языке. - Минск: «Вишейшая школа», 1991г. -156с.
  7.  Проценко В.С. та ін. Техніка програмування мовою Сі: Навч.посібник. - К.: Либідь, 1993. - 224с.
  8.  Трой Д. Программирование на языке С для персонального компьютера IBM РС. - М.: Радио и связь, 1991. -432 з.
  9.  Уинер Р. Язык Турбо С : Пер. з англ. .:: Мир, 1991. - 384с.
  10.  Уэйт М., Прата С., Мартин Д. Язык С. Руководство для начинающих. - М.: Мир, 1988. -512 з.
  11.  Дейтел Х., Дейтел П. Как программировать на С: Третье издание. - М.: Бином-Пресс, 2002г. - 1168с.
  12.  Сэмюел П. Харбисон III, Гай Л. Стил мл. Язык программирования С. - М.: ТОВ «Бином-Пресс», 2004г. - 528с.
  13.  Демидович Е.М. Основи алгоритмизации и программирования. Язык С. - СПб.: БХВ-Петербург, 2006г. - 440с.
  14.  Джонс Би., Эйткен П. Освой самостоятельно С за 21 день. - М.: Издательский дом «Вильямс», 2005. - 800с.



EMBED Word.Picture.8  

EMBED Word.Picture.8  

EMBED Word.Picture.8  

EMBED Word.Picture.8  

ОТВЕТ ВЕРЕН

Press any key

ВЕРНО

ВЕРНО

ВЕРНО

ВЕРНО

4

-12

1

1

#define PRINTX printf("%d\n",x)

main()

{

  int x=4, y, z;

  x+=1*8-8; PRINTX;

  x*=y=z=-3; PRINTX;

  x=-19!=-48; PRINTX;

  x>=(y=58); PRINTX;

 }

ДИАГН.

СИСТЕМЫ

АШ ОТВЕТ

ЧТО НАПЕЧАТАЕТ СЛЕДУЮЩАЯ ПРОГРАММА?

  F10-ВЫХОД

  F2-ТЕОРИЯ

 F1-ПОМОЩЬ

#define PRINTX printf("%d\n",x)

main()

{

  int x=4, y, z;

  x+=1*8-8; PRINTX;

  x*=y=z=-3; PRINTX;

  x=-19!=-48; PRINTX;

  x>=(y=58); PRINTX;

 }

ДИАГН.

СИСТЕМЫ

ВАШ ОТВЕТ

ЧТО НАПЕЧАТАЕТ СЛЕДУЮЩАЯ ПРОГРАММА ?

  F10-ВЫХОД

  F2-ТЕОРИЯ

 F1-ПОМОЩЬ

#define PRINT(int) printf("%d\n",int)

main()

{

  int x=0,y=0,z=2;

  PRINT(x||y||!z);

  x=4; y=8;

  z=++x + 2; PRINT(x); PRINT(z);

  z/=++x - ++y; PRINT(z);

}

ДИАГН.

СИСТЕМЫ

ВАШ ОТВЕТ

ЧТО НАПЕЧАТАЕТ СЛЕДУЮЩАЯ ПРОГРАММА?

ЧТО НАПЕЧАТАЕТ СЛЕДУЮЩАЯ ПРОГРАММА ?

ВАШ ОТВЕТ

ДИАГН.

СИСТЕМЫ

#define PRINT(int) printf("%d\n",x)

main()

{

  int x, y=1, z;

  if (y!=1) x=36; else x=34;

    PRINT(x);

  if (y<=1) if (y==1) x=18;

  else x=20;

    PRINT(x);

  if (z=y<2) x=28;

 PRINT(x);

 F1-ПОМОЩЬ

  F2-ТЕОРИЯ

  F10-ВЫХОД

ЧТО НАПЕЧАТАЕТ СЛЕДУЮЩАЯ ПРОГРАММА ?

ВАШ ОТВЕТ

ДИАГН.

СИСТЕМЫ

#define PRINT(int) printf("%d\n",x)

main()

{ int x=14, y=3;

while (y<10) ++y; x-=y; PRINT(x);

x=1; y=0;

while (y<11) x+=++y;

PRINT(x); PRINT(y);

y=1; z=0;

do z-=y;

while (++y<9); PRINT(z);

 }

 F1-ПОМОЩЬ

 F2-ТЕОРИЯ

 F10-ВЫХОД

ЧТО НАПЕЧАТАЕТ СЛЕДУЮЩАЯ ПРОГРАММА ?

ВАШ ОТВЕТ

ДИАГН.

СИСТЕМЫ

#define PRINT(int) printf("%d\n",x)

main()

{

int x=0, y;

for (y=8; y>0; y--) x=y;

PRINT(x);

for (y=12; (x=y)>1; y--) ;

PRINT(x);

for (x=1,y=13; y>x; ++x,--y );

 PRINT(x); PRINT(y);

}

 F1-ПОМОЩЬ

 F2-ТЕОРИЯ

 F10-ВЫХОД




1. История как школьный предмет в многонациональной России
2. Челябинский государственный университет ФГБОУ ВПО ЧелГУ Костанайский филиал Кафедра эконо
3.  Введение
4. Литературные кафе Санкт-Петербурга начала XX века
5. 3 Налоговые органы
6. Теоретические основы информатик
7. Философия как историческая форма мировоззренияИзобразите отношения между понятиями в кругах Эйлера
8. На тему ОЦЕНКА ФИНАНСОВОЙ УСТОЙЧИВОСТИ ПРЕДПРИЯТИЯ
9. а В 1800 ваша команда собирается на первой указанной станции
10. а у детей образуются прочные стереотипы жизнедеятельности облегчается переход от одного её вида к другому
11. Оренбургский государственный университет Кафедра гуманитарных и социальных дисциплин Расс
12. на тему- Государственная тайна Выполнил -Проверила- Ст
13. Тема- Предмет философии
14. Фізикогеографічна диференціація Європи Для кожного фізикогеографічного регіону висвітлити такі те
15. Презирать моду так же неумно как и слишком рьяно е
16. Руководство по знанию законов 1
17. КОНТРОЛЬНАЯ РАБОТА по учебной дисциплине Статистика Вариант 2 Факультет государс
18. Критерии гиперактивности (схема наблюдений за ребенком)
19. Изучение учебной мотивации студентов ВУЗа
20. 1687г Он рассматривал статистику как науку об управлении