Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
шпора основы.docx
Скачиваний:
8
Добавлен:
09.02.2015
Размер:
49.22 Кб
Скачать
  • Основные стадии разработки программного продукта.

Стадия предпроектных исследований и технического задания (постановка задачи)— определение требований к программному продукту и осуществление формальной постановки задачи;

Стадия технического предложения (анализ)— определение методов решения задачи;

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

Стадия технического проектирования (программирование)— составление программы на выбранном языке программирования, ее отладка и тестирование;

Стадия рабочего проектирования — оформление документации;

Стадии испытаний и внедрения в эксплуатацию — всестороннее тестирование программы и сопровождение при внедрении в эксплуатацию;

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

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

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

В результате согласования между заказчиком и исполнителем всех перечисленных вопросов составляют техническое задание (ТЗ) в соответствии с ГОСТ 19.201-78, которое служит основанием для дальнейшей работы.

  • Стадия технического предложения.

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

  • Стадия эскизного проектирования.

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

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

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

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

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

На данной стадии разрабатываются и оцениваются алгоритмы подпрограмм.

  • Стадия технического проектирования.

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

  • Стадия рабочего проектирования.

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

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

Документация должна включать:

описание постановки задачи

описание анализа задачи

описание определения структуры данных

описание алгоритма

текст программы с комментариями

тесты с входными и выходными данными

записи о процедурах внедрения

руководство пользователя

записи о всех модификациях

  • Стадии испытаний и внедрения в производство.

Стадия испытаний

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

Стадия внедрения в эксплуатацию

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

  • Понятие алгоритма. Свойства алгоритма.

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

Основные особенности алгоритма

Конечность (алгоритм всегда должен заканчиваться после выполнения конечного числа шагов);

определенность (каждый шаг алгоритма должен быть точно определен);

ввод (алгоритм имеет некоторое‚ возможно равное нулю‚ число входных данных‚ т.е. величин‚ которые задаются до начала его работы или определяются динамически во время его работы);

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

эффективность (алгоритм обычно считается эффективным‚ если все его операторы достаточно просты для того‚ чтобы их можно было выполнить в течение конечного промежутка времени с помощью карандаша и бумаги).

  • Основные алгоритмические структуры.

следование (последовательное выполнение действий);

ветвление (выбор одного из двух вариантов действий);

цикл-пока (повторение действий, пока не будет нарушено условие, выполнение которого проверяется в начале цикла).

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

выбор (выбор одного варианта из нескольких в зависимости от значения некоторой величины);

цикл-до (повторение действий, пока не будет нарушено условие, выполнение которого проверяется в конце цикла);

счетный цикл (цикл с заданным числом повторений).

  • Схема и псевдокод алгоритма.

Схемы используются для формального описания алгоритмов. На изображение схем алгоритмов существует ГОСТ 19.701-90, согласно которому каждой группе действий соответствует блок особой формы.

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

  • Технология программирования.

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

  • Структурное программирование.

Технология структурного программирования базируется на процедурной декомпозиции, при которой программа представляется в виде иерархической структуры блоков. Структурный подход к программированию был предложен в 70-ых годах ХХ века Э.Дейкстрой, разработан и дополнен Н.Виртом. Цель структурного программирования — повышение качества и надежности разрабатываемых программ, сокращение сроков разработки.

Основные положения структурного программирования

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

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

Разработка программы ведется пошагово, методом "сверху-вниз".

Сначала разрабатывается структура основной программы, которая должна состоять в основном из вызовов функций, каждая из которых выполняет определенное действие. Вместо самих функций, в программу вставляются "заглушки". "Заглушка"- это функция, имеющая "пустое" тело, то есть "заглушка" ничего не делает. Полученная программа отлаживается. После того, как программист убедился, что функции вызываются в правильном порядке, то есть структура основной программы верна, последовательно разрабатываются функции-"заглушки". При этом разработка каждой функции ведется также, как и основной программы. Разработка программы заканчивается тогда, когда не останется ни одной "заглушки". Такая последовательность разработки программы позволяет программисту отлаживать небольшой логически законченный фрагмент программы. При этом ошибки локализуются именно в отлаживаемой функции. К разработке следующей функции можно переходить только тогда, когда данная функция будет работать безошибочно.

Кроме этого программы должны быть "самодокументированы". Это предполагает широкое и грамотное использование комментариев и идентификаторов.

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

  • Понятие языка программирования.

Язы́к программи́рования — формальная знаковая система, предназначенная для записи компьютерных программ.

  • Синтаксис и семантика языка программирования.

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

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

  • Характеристика языка программирования Си.

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

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

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

  • Алфавит языка Си. Идентификаторы.

Алфавит языка программирования — множество символов, допустимых при построении конструкций программы.

Алфавит языка Си включает:

строчные, прописные буквы латинского алфавита (a...z, A...Z) и символ подчеркивания _ (строчные и прописные буквы различаются)

цифры (0...9)

специальные знаки: . , ; + - * / = < > % & ! ( ) { } ^ | ? : [ ] ^ ~' " # \

служебные слова: char, short, int, long, float, double, enum, struct, union, signed, unsigned, void, auto, extern, register, static, break, case, continue, default, do, else, for, goto, if, return, switch, while, sizeof, typedef.

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

Из символов алфавита в соответствии с правилами синтаксиса строят различные конструкции или лексемы.

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

Лексемами языка Си являются:

идентификаторы

ключевые слова

константы

знаки операций

разделители

Простейшей из них является конструкция идентификатор.

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

  • Выражение. Оператор.

Выражение — это конструкция языка Си, имеющая значение.

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

Оператор — это конструкция языка Си, которая вызывает выполнение действия.

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

простые операторы

блоки операторов (блоки, составные операторы)

управляющие операторы

Простой оператор или оператор-выражение — это выражение, заканчивающееся символом ; (точка с запятой).

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

Блок операторов (блок, составной оператор) — это последовательность операторов, заключенная в фигурные скобки {}.

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

"Тело" функции также представляет собой блок операторов.

Управляющие операторы — операторы языка Си, реализующие ветвления алгоритма, циклы и передачу управления.

Все управляющие операторы начинаются с ключевого слова, такого как: if, while, for и т.д.

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

Арифметические операции язык Си — операции, реализующие арифметические действия.

Аддитивные операции

сложение (+)

вычитание (-)

Мультипликативные операции

умножение (*)

деление (/)

получение остатка от деления (%)

Изменение знака (унарный минус) (-)

Приоритеты определяются таблицей приоритетов.

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

объект типа char в выражении всегда временно преобразуется в тип int. Преобразования из младшего в старший тип (снизу вверх) выполняются в случае необходимости. Например, если выражение содержит операнды типов int и double, то операнд типа int будет временно преобразован в тип double.

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

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

Именующие выражение = Выражение

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

Именующее выражение — выражение, определяющее объект, которому может быть присвоено какое-либо значение, например, переменную или элемент массива.

Приоритет операций присваивания определяется таблицей приоритетов

Составные операции присваивания вида ор= работают следующим образом:

выражение1 ор= выражение2

эквивалентно выражению

выражение1 = выражение1 ор выражение2

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

Таблица 1

Составная операция присваивания Эквивалентное выражение

x += 50 x = x + 50

x -= 50 x = x - 50

x *= 50 x = x * 50

x /= 50 x = x / 50

x %= 50 x = x % 50

x *= a + b x = x * (a + b)

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

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

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

Объект типа float или double = значение выражения типа char или int

Объект типа char или int = значение выражениея типа float или double

Объект меньшего размера = значение выражения большего размера.

Объект большего размера = значение выражения меньшего размера

В первом варианте присваивание обычно не влечет никакой потери данных. Значение выражение типа char или int будет помещено в область памяти, отведенную для float или double. При этом объект, представленный в формате целых чисел, преобразуется в формат с плавающей точкой для вещественных чисел.

  • Операция приведения типа.

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

(тип)операнд

Тип задается ключевым словом, определяющим тип данных.

  • Операции инкрементации и декрементации.

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

операнд++

++операнд

Операция инкрементации ++ добавляет к операнду единицу.

операнд--

--операнд

Операция декрементации -- вычитает из операнда единицу.

Операндом может быть именующее выражение, например, имя переменной.

Приоритет этих операций определяется таблицей приоритетов языка Си (Приоритеты операций).

Следующие три строки увеличивают переменную x на 1:

x = x + 1;

++x;

x++;

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

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

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

Операции отношений — операции языка Си, которые используются для сравнения двух числовых значений.

Приоритет данных операций определяется таблицей приоритетов языка Си (Приоритеты операций).

Значением операции отношения (например, x < max) может быть либо истина, либо ложь. Язык Си присваивает значение 0 ложному отношению и 1 — истинному отношению. На самом деле, любое ненулевое выражение в Си считается истинным, а нулевое — ложным.

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

В языке Си существуют следующие логические операции: логическое умножение И — коньюнкция (&&), логическое сложение ИЛИ — дизьюнкция(||), логическое отрицание НЕ (!).

Приоритеты логических операций определяются таблицей приоритетов (Приоритеты операций).

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

  • Побитовые операции.

Побитовые операции — это операции, работающие с отдельными битами операндов. Операнд должен быть целочисленным, т.е. иметь тип long long, long, unsigned, int, shor или char.

Приоритеты побитовых операций приведены в таблице приоритетов (Приоритеты операций).

Поразрядное дополнение (~) – это унарная операция, результатом которой является значение, полученное поразрядным дополнением операнда, т.е. каждый бит со значением 0 заменяется на 1 и наоборот.

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

Исключающее ИЛИ (^) — значением выражения, использующего эту операцию, является поразрядное исключающее ИЛИ ее операндов.

Поразрядное сложение ИЛИ (|) — значением выражения, использующего эту операцию, является поразрядное логические сложение двух операндов.

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

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

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

  • Управляющий оператор if-else.Условная операция.

Управляющий оператор, реализующий ветвление алгоритма.

Условная (тернарная) операция- операция языка Си, которая по действию аналогична оператору if-else (Управляющий оператор if).

Синтаксис условной операции:

выражение1 ? выражение2 : выражение3

Если выражение1 истинно, значением всего выражения будет значение выражения2, иначе — выражения3.

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

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

Это единственная операция, составленная из двух символов, разделенных между собой выражениями (в отличии от операций &&, ||, >=, <= и т.д.). Это единственная операция, требующая три операнда.

  • Управляющий оператор switch.

Оператор switch — управляющий оператор языка Си, реализующий алгоритмическую структуру выбор.

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

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

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

{

case константа1: операторы

case константа2: операторы

. . .

default: операторы

}

Выражение в скобках должно быть целого типа (можно использовать символьные константы, так как их тип целый). Выражение вычисляется и сравнивается с различными константами, записанными после ключевого слова case. Допускается использование констант целого или символьного типа или константное выражение указанных типов (например, 5, 'a', 2048/512). Переменные или вызовы функций использовать нельзя. Если подходящая константа найдена, вычисления продолжаются с оператора, следующего за словом case, соответствующим этой константе. Затем выполняются все последующие операторы вплоть до появления оператора break или завершающей оператор switch скобки }. Метки case могут располагаться в любом порядке, но значения соответствующих констант должны быть различными.

switch, case, default и break — ключевые слова. Оператор break вызывает немедленный выход из оператора switch. Распространенная ошибка состоит в пропуске оператора break, когда необходим выход из оператора switch.

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

  • Управляющие операторы breakcontinuegoto.

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

Управляющий оператор break осуществляет немедленный выход из циклов while, do-while и for. Одиночный оператор break не может использоваться для выхода из более чем одного уровня вложения циклов.

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

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

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

goto метка;

Метка — это идентификатор, завершаемый двоеточием, который помечает оператор.

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

Использование goto оправдано, если есть множество вложенных циклов.

  • Цикл while.

Оператор цикла while — управляющий оператор языка Си, реализующий выполнение цикла-пока в алгоритме.

  • Цикл do-while.

Оператор цикла do-while — управляющий оператор языка Си, реализующий выполнение цикла-до в алгоритме.

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

  • Цикл for. Операция продолжения ("запятая").

Оператор цикла for

Оператор цикла for — управляющий оператор языка Си, реализующий выполнение цикла в алгоритме.

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

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

  • Функции. Объявление, определение и вызов функции. Назначение стека.

Функция — это именованный фрагмент программы. Данные могут передаваться в функцию и функция может возвращать значение.

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

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

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

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

Программы легче читаются, так как детали “скрыты” внутри функций.

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

Определение функции может иметь одну из двух форм:

возвращаемый_тип имя_функции (список объявлений формальных параметров)

{

объявления /* тело функции */

опреаторы

}

возвращаемый_тип имя_функции (список формальных параметорв)

объявление формальных параметров

{

объявления /* тело функции */

опреаторы

}

Оператор объявления функции (объявление прототипа функции) имеет следующий вид:

возвращаемый_тип имя_функции (список объявлений типов параметров);

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

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

Если объявление типа функции опущено, компилятор будет использовать правило умолчания K&R и установит для нее тип int. Для функций стандарта K&R компилятор не выполняет контроля типов.

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

  • Формальные и фактические параметры функции.

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

Формальный параметр указывается при объявлении и определении функций.

  • Возвращаемое значение функции. Оператор return.

Функция может передавать одно значение обратно в вызывающую функцию.

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

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

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

return [выражение];

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

Функция может иметь более одного оператора return.

  • Рекурсивные функции.

Функция в языке программирования Си может быть рекурсивной, т.е. может вызывать сама себя. Каждый раз, когда функция вызывает себя, на стек помещается новый кадр. Функция должна вызывать себя условно, например, внутри оператора if, иначе бесконечная рекурсия переполнит стек.

  • Классы памяти.

Класс памяти - характеристика переменной, которая определяет способ ее хранения .

Язык Си реализует следующие классы памяти:

автоматический

регистровый

внешний

статический

Характеристики классов памяти:

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

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

размещение связанных с идентификатором значений в памяти.

Класс

Область действия

Время жизни

Место хранения

Размещение массивов, структур

Значение по умолчанию

Автоматический

Блок

Исполнение блока

Стек

Да

Неопределено

Регистровый

Блок

Исполнение блока

Регистр

Нет

Неопределено

Внешний

От объявления до конца программы или файла

Время работы программы

Область данных

Да

Null

Статический внешний

От объявления до конца файла

Время работы программы

Область данных

Да

Null

Статический внутренний

Блок

Время работы программы

Область данных

Да

Null

  • Массивы. Объявление массива. Инициализация массива. Доступ к элементу массива.

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

Массивы являются производными типами данных, создаваемыми из существующих типов данных.

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

тип идентификатор[длина измерения 1][длина измерения 2]...[длина измерения n];

Инициализация массива — это присваивание элементам массива начальных значений.

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

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

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

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

  • Массив как аргумент функции.

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

Адрес массива — адрес первого элемента массива.

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

  • Массив символов.

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

char buf[1024];

Строки в языке Си должны заканчиваться признаком конца строки — “нулевым” символом '\0', т.е. байтом, все биты которого равны 0. Библиотечные функции, которые работают со строками, “ищут” нулевой символ, так как это единственный способ определить конец строки. Таким образом, при объявлении символьного массива, в котором будет храниться строка, необходимо предусмотреть дополнительный байт для признака конца строки.

  • Однотипная обработка одномерных массивов.

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

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

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

  • Переформирование массивов.

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

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

  • Одновременная обработка массивов.

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

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

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

  • Поиск в массиве.

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

  • Сортировка массива. Метод выбора.

Сортировка — это процесс упорядочивания информации по определенному признаку.

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

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

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

Вычислительная сложность O(const) означает, что время решения задачи данным методом не зависит от размерности, O(n) — время работы пропорционально размерности задачи, O(n2) — время работы пропорционально квадрату размерности задачи и т.д.

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

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

Метод выбора - один из самых простых прямых методов сортировки.

Находим минимальный элемент массива размерностью n. Найденный элемент меняется местами с первым элементом. Затем процесс повторяется, начиная со второго элемента массива и т.д.

  • Сортировка массива. Метод вставки.

Метод вставки — один из прямых методов сортировки.

В исходном состоянии считаем, что сортируемая последовательность состоит из двух последовательностей: уже сортированной (на первом шаге состоит из единственного — первого элемента) и последовательности, которую еще необходимо сортировать. На каждом шаге из сортируемой последовательности извлекается элемент и вставляется в первую последовательность так, чтобы она оставалась сортированной. Поиск места вставки осуществляется с конца первой последовательности, сравнивая вставляемый элемент ai с очередным элементом сортированной последовательности aj. Если элемент ai больше aj, его вставляют вместо aj+1, иначе сдвигают aj вправо и уменьшают j на единицу. Поиск места вставки завершают, если элемент вставлен или достигнут левый конец массива. В последнем случае элемент ai вставляют на первое место.

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

  • Сортировка массива. Метод обменов.

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

Алгоритм метода обмена основан на сравнении пары соседних элементов. Если расположение элементов не удовлетворяет условиям сортировки, то их меняют местами. Сравнения и перестановки продолжаются до тех пор, пока не будут упорядочены все элементы. Определить, что элементы упорядочены, можно, считая количество выполненных перестановок: если количество перестановок равно нулю, то массив отсортирован.

  • Указатели: объявление, инициализация, использование. Адресная арифметика.

Указатель — это переменная, содержащая адрес.

Указатель должен быть объявлен также, как объявляются обычные переменные, но перед идентификатором должен стоять символ *.

Для чего используются указатели?

Для эффективного доступа к данным.

Для разработки гибких программ.

Для изменения переменных, передаваемых в функцию.

Для работы с динамически распределяемой памятью.

Для доступа по аппаратно-фиксированным адресам в системных программах.

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

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

Целое число можно сложить с указателем или вычесть из него.

Указатель можно сравнивать с другим указателем.

Указатель можно вычесть из другого указателя.

Указателю можно присвоить значение нулевого указателя — константы NULL.

Указатель можно сравнивать с нулевым указателем.

Другие арифметические операции над указателями недопустимы.

  • Использование указателя как аргумента функции. Указатель — возвращаемое значение функции.

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

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

Int *f(void)

{

. . .

}

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

  • Доступ к аргументам командной строки.

Аргументы командной строки — это множество слов, из которых состоит командная строка.

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

argc (сокращение от argument count)- первый параметр функции main(), имеет смысл счетчика аргументов. Это количество слов, на которые разбивается символами промежутков командная строка.

argv (сокращение от argument vector- вектор аргументов) — второй параметр функции main(). Во время выполнения программы на языке Си слова из командой строки размещены в виде символьных строк в программном адресном пространстве. В этой же памяти запоминается и завершаемый нулем (NULL) массив адресов (указателей) этих строк.

  • Структуры. Объявление структуры. Инициализация структуры. Доступ к элементу структуры (операция "точка").

Структура — это набор элементов, которые могут иметь различные типы.

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

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

Задание шаблонов и объявление структур

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

Шаблон структуры представляет собой список объявлений переменных, описывающий элементы структуры .

struct [имя_шаблона] {список_элементов};

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

Пример 1

struct emp {

char name[21];

char id[8];

double salary; /*это шаблон, память не выделяется */

};

int main ()

{

struct emp prgmr; /*это объявление: выделяется память под переменную prgmr*/

int num;

...

}

int f(void)

{

struct emp supervisor; /*это объявление: выделяется память под переменную supervisor*/

...

}

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

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

Инициализирующая запись - это заключенный в фигурные скобки список, элементы которого разделяются запятыми и являются константами. Любые неинициализированные элементы внешних или статических структур по умолчанию равны 0. Значения неинициализированных элементов автоматических структур неопределены.

Операция доступа к элементу структуры — операция "точка"(.), результат которой — значение элемента структуры.

имя_структуры.имя_элемента_структуры

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

  • Указатели на структуру. Доступ к элементу структуры (операция "стрелка").

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

Операция доступа к элементу структуры через указатель

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

имя_указателя->имя_элемента

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

После того, как указатель sp инициализирован и указывает на элемент массива структур staff[0], следующие выражения эквиваленты:

staff[0].salary /*имя_структуры.имя_элемента*/

sp->salary /*имя_указателя->имя_элемента*/

  • Массивы структур. Использование структуры как аргумента функции. Структура- возвращаемое значение функции.

Массив структур — это массив, каждый элемент которого является структурой. В памяти элементы массива структур размещаются последовательно.

Для обработки элементов массива структур используется операия доступа к элементу массива (квадратные скобки).

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

Функция может возвращать структурное значение.

В языке Си реализована операция копирования структур — присваивание значений элементов одной структуры элементам другой структуры того же типа при помощи операции присваивания. Первые компиляторы Си не обеспечивали этой возможности.

В прим. 1 показано, как в функцию передается структура и как функция возвращает структурное значение.

Пример 1

#include <stdio.h>

#include "emp.h" /* содержит шаблон структуры emp */