Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Informatika_1_1fedorova_1

.pdf
Скачиваний:
37
Добавлен:
09.06.2015
Размер:
18.73 Mб
Скачать

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

(31)Передача параметров-функций в подпрограмму.

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

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

Пример:

typedef int(*func)(int a, int b); int call_func(int a, int b) { return a + b;

}

void function(int a, int b, func f) { int sum = f(a, b);

std::cout << "Sum = " << sum << std::endl;

}

int main() {

function(5, 2, &call_func);

}

(32)Рекурсивные функции, примеры.

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

Возможна более сложная схема: функция А вызывает функцию В, а та в свою очередь вызывает А.Это называется сложной или косвенной рекурсией. При этом оказывается, что описываемая первой подпрограмма должна вызывать еще не описанную подпрограмму. Чтобы это было возможно, требуется использовать опережающее описание, в С++ это прототипы функций. В общем случае подпрограмма может содержать вызов других подпрограмм, в том числе она может вызывать саму себя void Rec(int a){if(a>0)then Rec(a-1);cout<<a;} Не всегда полезна рекурсия, если рекурсию моно заменить одним циклом, то лучше это сделать.

#include<iostream> using namespace std; void r(int x) { } void f(int x)

{

cout << "!"; ((void(*)(int))(int*)(-!x&int((int*)&r)|int((int*)&f)&-!!x))(x-1);

}

int main()

{

f(8); return 0;

}

33. ПОНЯТИЕ СТРУКТУРНОГО ПРОГРАММИРОВАНИЯ, ЭТАП ПРОЕКТИРОВАНИЯ КОМПОЗИЦИЯ И ДЕКОМПОЗИЦИЯ, ПОНЯТИЕ СТАТИЧЕСКОЙ И ДИНАМИЧЕСКОЙ СТРУКТУРЫ ПРОГРАММЫ, СПЕЦИФИКАЦИЯ ПРОГРАММЫ.

Структурное программирование методология разработки программного обеспечения, в основе которой лежит представление программы в виде иерархической структуры блоков. Предложена в 1970-х годах Э. Дейкстрой и др. В соответствии с данной методологией любая программа строится без использования оператора goto из трёх базовых управляющих структур: последовательность, ветвление, цикл; кроме того, используются подпрограммы. При этом разработка программы ведётся пошагово, методом «сверху вниз».

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

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

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

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

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

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

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

34. ПОНЯТИЕ ЧАСТИЧНОЙ И ПОЛНОЙ КОРРЕКТНОСТИ ПРОГРАММЫ,

ПРАВИЛА ВЫВОДА ОБЩИЙ ВИД, ПРАВИЛА КОНСЕКВЕНЦИИ.

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

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

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

Общий вид: H1, H2,…,Hr

H

если соотношения H1, H2,…,Hr ВЫПОЛНЯЮТСЯ, то Н тоже выполняется.

первое правило консеквенции: {P} S {R} , R -> Q

{P} S {Q}

Второе правило консеквенции: P -> R , {R} S {Q}

{P} S {Q}

35. ПРАВИЛА ВЫВОДА ДЛЯ ОПЕРАТОРОВ С/С++: ПУСТОГО, ПРИСВАИВАНИЯ, СОСТАВНОГО.

Для пустого: {P}{P}

Для оператора присваивания: {Pex} X = e; {P}

Для составного: если S есть{S1 , S2} и имеют место {P} S1 {R} и {R} S2 {Q}, то истинно и {P} {S1 , S2} {Q}

{P} S1 {R} , {R} S2 {Q}

{P} {S1 , S2} {Q}

Полный условный оператор:

37. ПРАВИЛА ВЫВОДА ДЛЯ ЦИКЛОВ С ПРЕДУСЛОВИЕМ И

ПОСТУСЛОВИЕМ.

38. ПРИМЕР ДОКАЗАТЕЛЬСТВА ПРАВИЛЬНОСТИ ПРОГРАММЫ.

39. ЗАПУСК НА ВЫПОЛНЕНИЕ ПРОГРАММЫ С ПАРАМЕТРАМИ.

Если программу запускать через командную строку, то существует возможность передать какую-либо информацию этой программе, для этого и существуют параметры argc и argv[]. Параметр argc имеет тип данных int, и содержит количество параметров, передаваемых в функцию main. Причем argc всегда не меньше 1, даже когда мы не передаем никакой информации, так как первым параметром считается имя функции. Параметр argv[] это массив указателей на строки. Через командную

строку можно передать только данные строкового типа. Так вот именно через параметр argv[] и передается какая-либо информация. Пример:

#include <iostream> using namespace std;

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

if (argc > 1) // если передаем аргументы, то argc будет больше 1

cout << argv[1]<<endl; // вывод второй строки из массива указателей на строки

else

cout << "Not arguments" << endl;

return 0;

}

40. ФУНКЦИИ ДЛЯ РАБОТЫ С ФАЙЛАМИ ПОСЛЕДОВАТЕЛЬНОГО ДОСТУПА К ДАННЫМ.

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

get(ch). Извлекает один символ в переменную символьного типа ch. Пример:

in.get(ch);

getline(str). Извлекает символы в строковую переменную str до ограничителя ‘/n’.

Пример: in.getline(str);

getline(str, X). Извлекает X символов в строковую переменную str. Пример:

in.getline(str, 20);

getline(str, ch). Извлекает символы в строковую переменную str до ограничителя символьного типа ch. Пример: in.getline(str, ‘$’);

put(ch). Записывает один символ ch в поток. Пример: out.put(ch); eof()- Проверяет не достигнут ли конец файла. Пример: if (!in.eof());

peek(). Возвращает следующий символ потока, или значение EOF, если достигнут конец файла. Пример: while (in.peek() != EOF);

read(). Считывает из вызывающего потока указанное количество байт и передает их в

буфер. Пример: in.read((char*) &i, sizeof(double));

write(). Записывает в соответствующий поток из буфера указанное количество байт.

Пример: out.write((char*) &i, sizeof(double));

41. ФУНКЦИИ ДЛЯ РАБОТЫ С ФАЙЛАМИ ПРЯМОГО ДОСТУПА К ДАННЫМ.

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

seekg(). Устанавливает указатель в позицию с номером внутри файла для чтения.

Примеры: in.seekg(4); in.seekg(4, in.end);

seekp(). Устанавливает указатель в позицию с номером внутри файла для записи.

out.seekp(4); out.seekp(4, out.end);

tellg(). Возвращает текущую позицию указателя потока ввода.

streampos n = in.tellg();

tellp(). Возвращает текущую позицию маркера потока вывода. streampos n = out.tellp();

42. ШАБЛОНЫ ФУНКЦИЙ, ОПРЕДЕЛЕНИЕ И НАЗНАЧЕНИЕ.

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

Объявление и определение шаблонов в С++. Так выглядит шаблон функции определения минимума:

template <typename T> T min(T a, T b) { return a < b ? a : b;

}

template используется для обозначения функции-шаблона. typename T определяет параметр, который будет хранить информацию о том, какой именно тип данных был передан в шаблон. T возвращаемое значение, min название, (T a, T b) аргументы, а далее идет тело функции.

Для вызова этой функции можно просто использовать её имя: min( 1, 2 );

min( 'a', 'b' );

min( string( "abc" ), string( "cde" ) );

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

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

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

Основные свойства параметров шаблона.

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

-Имена параметров должны быть уникальными во всем определении шаблона.

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

-В списках параметров, если их несколько, перед каждым записывается ключевое слово class и разделяется ','.

-Нельзя к одному ключевому слову записать несколько идентификаторов.

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

функции.

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

43. ШАБЛОНЫ ФУНКЦИЙ, ОСОБЕННОСТИ ИХ ИСПОЛЬЗОВАНИЯ.

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

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

Пример программы для нахождения наибольшего элемента в паре.

#include <iostream> using namespace std;

template <class T> T GetMax (T a, T b) { T result;

result = (a>b)? a : b; return (result);

}

int main () { int i=5, j=6, k;

long l=10, m=5, n; k=GetMax<int>(i,j); n=GetMax<long>(l,m); cout << k << endl; cout << n << endl;

return 0;

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]