Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Экзамен по информатике.docx
Скачиваний:
25
Добавлен:
22.09.2019
Размер:
1.18 Mб
Скачать
  1. Принципы структурного программирования.

Данная методология основывается на трёх положениях:

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

  2. Повторяющиеся фрагменты программы могут оформляться в виде подпрограмм.

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

  1. Структурное программирование: три базовые конструкции.

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

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

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

  • структура выбора — однократное выполнение одной из двух или более операций, в зависимости от выполнения некоторого заданного условия;

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

Структура следования встроена в C++. Пока не указано иное, компьютер выполняет операторы C++ один за другим в той последовательности, в которой они записаны.

C++ обеспечивает три типа структур выбора альтернатив:

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

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

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

C++ обеспечивает три типа структур повторения, называемых:

  • Структура повторения while выполняет действие, пока проверяемое условие истинно.

  • Структура повторения do/while похожа на структуру повторения while. Сперва выполняется действие, а затем проверяется условие. Действия выполняется до тех пор, пока условие истинно.

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

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

  1. Основные операторы.

1.4.2 Операторы Выражения Самый обычный вид оператора – выражение;. Он состоит из выражения, за которым следует точка с запятой. Например: a = b*3+c; cout «„ «go go go“; lseek(fd,0,2); 1.4.3 Пустой оператор Простейшей формой оператора является оператор: ; Он не делает ничего. Однако он может быть полезен в тех случаях, когда синтаксис требует наличие оператора, а вам оператор не нужен. 1.4.4 Блоки Блок – это возможно пустой список операторов, заключенный в фигурные скобки: (* a=b+2; b++; *) Блок позволяет рассматривать несколько операторов как один. Область видимости имени, описанного в блоке, простирается до конца блока. Имя можно сделать невидимым с помощью описаний такого же имени во внутренних блоках. 1.4.5 Оператор if Программа в следующем примере осуществляет преобразование дюймов в сантиметры и сантиметров в дюймы. Предполагаемся, что вы укажете единицы измерения вводимых данных, добавляя i для дюймов и c для сантиметров: #include «stream.h» main() (* const float fac = 2.54; float x, in, cm; char ch = 0; cout «„ "введите длину: "; cin “» x »» ch; if (ch == 'i') (* // inch – дюймы in = x; cm = x*fac; *) else if (ch == 'c') // cm – сантиметры in = x/fac; cm = x; *) else in = cm = 0; cout «„ in «« " in = " «« cm «« « cm\n“; *) Заметьте, что условие в операторе if должно быть заключено в круглые скобки. 1.4.6 Операторы switch Оператор switch производит сопоставление значения с множеством констант. Проверки в предыдущем примере можно записать так: switch (ch) (* case 'i': in = x; cm = x*fac; break; case 'c': in = x/fac; cm = x; break; default: in = cm = 0; break; *) Операторы break применяются для выхода из оператора switch. Константы в вариантах case должны быть различными, и если проверяемое значение не совпадает ни с одной из констант, выбирается вариант default. Программисту не обязательно предусматривать default. 1.4.7 Оператор while Рассмотрим копирование строки, когда заданы указатель p на ее первый символ и указатель q на целевую строку. По соглашению строка оканчивается символом с целым значением 0. while (p != 0) (* *q = *p; // скопировать символ q = q+1; p = p+1; *) *q = 0; // завершающий символ 0 скопирован не был Следующее после while условие должно быть заключено в круглые скобки. Условие вычисляется, и если его значение не ноль, выполняется непосредственно следующий за ним оператор. Это повторяется до тех пор, пока вычисление условия не даст ноль. Этот пример слишком пространен. Можно использовать операцию ++ для непосредственного указания увеличения, и проверка упростится: while (*p) *q++ = *p++; *q = 0; где конструкция *p++ означает: «взять символ, на который указывает p, затем увеличить p.» Пример можно еще упростить, так как указатель p разыменовывается дважды за каждый цикл. Копирование символа можно делать тогда же, когда производится проверка условия: while (*q++ = *p++) ; Здесь берется символ, на который указывает p, p увеличивается, этот символ копируется туда, куда указывает q, и q увеличивается. Если символ ненулевой, цикл повторяется. Поскольку вся работа выполняется в условии, не требуется ни оного оператора. Чтобы указать на это, используется пустой оператор. С++ (как и C) одновременно любят и ненавидят за возможность такого чрезвычайно краткого ориентированного на выразительность программирования*. – * в оригинале expression-oriented (expression – выразительность и выражение). (прим. перев.) 1.4.8 Оператор for Рассмотрим копирование десяти элементов одного вектора в другой: for (int i=0; i«10; i++) q[i]=p[i]; Это эквивалентно int i = 0; while (i«10) (* q[i] = p[i]; i++; *) но более удобочитаемо, поскольку вся информация, управляющая циклом, локализована. При применении операции ++ к целой переменной к ней просто добавляется единица. Первая часть оператора for не обязательно должна быть описанием, она может быть любым оператором. Например: for (i=0; i«10; i++) q[i]=p[i]; тоже эквивалентно предыдущей записи при условии, что i соответствующим образом описано раньше.

  1. Пустой оператор.

  2. Оператор присваивания (синтаксис, логика работы, полная и сокращённая форма, порядок выполнения, контекст вычисления, пример).

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

  4. Условный оператор (синтаксис, логика работы, пример).

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

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

  7. Оператор выбора (синтаксис, логика работы, пример).

  8. Цикл с предусловием.

  9. Цикл с постусловием.

  10. Цикл с параметром.

  11. Взаимозаменяемость циклов.

  12. Оператор break.

  13. Оператор continue

  14. Оператор ?: (синтаксис, логика работы, пример).

  15. Ссылки (понятие, способы применения).

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

?

1

2

// структура объявления ссылок

/*тип*/ &/*имя ссылки*/ = /*имя переменной*/;

При объявлении ссылки перед её именем ставится символ амперсанда "&", сама же ссылка должна быть проинициализирована именем переменной, на которую она ссылается. Тип данных, на который указывает ссылка, может быть любым, но должен совпадать с объектом, на который ссылается, то есть с типом данных ссылочной переменной. Для удобства, будем называть  переменную, на которую ссылается ссылка  "ссылочной переменной". Любое изменение значения содержащегося в ссылке повлечёт за собой изменение этого значения в переменной, на которую ссылается ссылка. Разработаем программу, в которой объявим ссылку на объект типа int.

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

// №1.cpp: определяет точку входа для консольного приложения.

 

#include "stdafx.h"

#include <iostream>

using namespace std;

 

int main(int argc, char* argv[])

{

    int value = 15;

    int &reference = value; // объявление и инициализация ссылки значением переменной value

    cout << "value     = " << value     << endl;

    cout << "reference = " << reference << endl;

    reference+=15; // изменяем значение переменной value посредством изменения значения в ссылке

    cout << "value     = " << value     << endl; // смотрим, что получилось, как будет видно дальше значение поменялось как в ссылке,

    cout << "reference = " << reference << endl; //  так и в ссылочной переменной

    system("pause");

    return 0;

}

В строке 10 объявлена ссылка reference типа int  на переменную value. В строке 13 суммируется значение переменной value с числом 15, черезссылку reference. Результат работы программы (см. Рисунок 1).

Рисунок 1 - Ссылки в С++

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

Ссылки, как правило, в большинстве случаев используют в функциях как ссылки-параметры или ссылки-аргументы.  Напомню, что в языке программирования С++ в функции передаются данные по значению и по ссылке. Так вот, когда происходит передача по значению, те данные, которые необходимо передать, нужно сначала скопировать, а когда передаётся большой объём данных, то только на передачу затрачивается большое количество времени и ресурсов. В таком случае необходимо использовать передачу по ссылке, в этом случае данные копировать нет необходимости, так как к ним обеспечен прямой доступ, но нарушают безопасность данных, хранимых в ссылочных переменных, так как открывают прямой доступ к этим данным. Хотя далее мы рассмотрим, как обеспечить целостность данных и скорость их передачи. Для этого, разработаем программу, в которой создадим три функции, аргументы в которых будут передаваться по значению и по ссылке. Вдобавок ко всему этому  ещё и передачу через указатель осуществим. Частенько возникает путаница между указателями и ссылками, на первый взгляд и ссылки и указатели работают одинаково, но разница все, же есть и весьма значительная.

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

// reference.cpp: определяет точку входа для консольного приложения.

 

#include "stdafx.h"

#include <iostream>

using namespace std;

 

int sum_by_value(int );// суммирование по значению

int sum_by_reference(int &);// суммирование по ссылке

int sum_by_pointer(int *); // суммирование по указателю

 

int _tmain(int argc, _TCHAR* argv[])

{

    int value = 10;

    cout << "sum_by_value     = " << sum_by_value(value)     << endl;

    cout << "value = " << value   << endl; // значение переменной осталось неизменным

    cout << "sum_by_reference = " << sum_by_reference(value) << endl;

    cout << "value = " << value   << endl; // значение переменной изменилось

    cout << "sum_by_pointer     = " << sum_by_pointer(&value)  << endl;

    cout << "value = " << value   << endl; // значение переменной изменилось ещё раз

    system("pause");

    return 0;

}

 

int sum_by_value(int value)// функция принимающая аргумент по значению

{

    value += value;

    return value;

}

 

int sum_by_reference(int &reference) // функция принимающая аргумент по ссылке

{

    reference += reference;

    return reference;

}

 

int sum_by_pointer(int *ptrvalue)// функция принимающая аргумент через указатель

{

    *ptrvalue += *ptrvalue;// арифметика с указателем

    return *ptrvalue;

}

Начальное значение осталось неизменным в случае передачи по значению, тогда как передача по ссылке и через указатель изменили значение передаваемой переменной. Таким образом, нет необходимости использовать глобальные переменные при необходимости изменения значения передаваемой переменной, нужно воспользоваться ссылкой или указателем. В случае использования указателя строка 18 нельзя забывать про операцию взятия адреса, так как аргументом является указатель. В случае со ссылкой, достаточно указать только имя переменной и всё строка 16. Результат работы программы (см. Рисунок 2).

Рисунок 2 - Ссылки в С++

В чём же разница между указателями  и ссылками? Основное назначение указателя – это организация динамических объектов, то есть размер, которых может меняться (увеличиваться или уменьшаться). Тогда как ссылки предназначены для организации прямого доступа к тому, или иному объекту. Главное отличие состоит во внутреннем механизме работы. Указатели ссылаются на участок в памяти, используя его адрес. А ссылки ссылаются на объект, по его имени (тоже своего рода адрес). Если нет необходимости изменить передаваемое значение в ссылочной переменной, но нужно выиграть в скорости, используйте спецификатор const в объявлении параметров функций. Только так и можно защитить данные от случайного их изменения или полной потере.

?

1

2

int sum_by_reference(const int &reference) // функция принимающая аргумент по ссылке

// квалификатор const не даёт изменить передаваемый аргумент внутри функции

  1. Подпрограммы (синтаксис, виды подпрограмм, контекст, пример).

  2. Оператор return.

  3. Прототипы функций (понятие, назначение, способы применения).

  4. Библиотеки функций. Оператор #include.

  5. Создание пользовательских библиотек.

  6. Способы передачи параметров в функции.

  7. Способы передачи значения из одной функции в другую.

  8. Рекурсия (понятие, правила написания рекурсивных подпрограмм, прямая и обратная и косвенная рекурсии).

Рекурсивной функцией называется функция, вызывающая саму себя в своем теле. Необходимо ещё раз подчеркнуть, что «самовызов» будет рекурсивным только в том случае, если находится в теле функции. Как мы видели ранее, «самовызов» в списке параметров не является рекурсивным. Обычно различают прямую и косвенную рекурсию. Если в теле функции явно используется вызов той же самой функции, то имеет место прямая рекурсия (self-calling), как в приведенных примерах. Если две или более функций взаимно вызывают друг друга, то имеет место косвенная рекурсия. Обычно косвенная рекурсия возникает при реализации программ синтаксического анализа методом рекурсивного спуска. Прекрасным примером рекурсивной функции является быстрая сортировка Хоора. Сама схема алгоритма является рекурсивной, поэтому написать итеративную программу достаточно сложно, что можно увидеть в книге Н.Вирта [9] и в [30]. Схема функции выглядит так:

Код C++

1

2

3

4

5

6

void QuickSort(A, 1, n)

{  //--Выбрать разделяющий элемент с номером  1<k<n

   //--Разделить массив А относительно k-го элемента

   QuickSort(A, 1, k-1);    //-рекурсивный вызов с левой частью

   QuickSort(A, k+1, n);   //-рекурсивный вызов с правой частью

}