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

Вопрос№9 Передача данных в параметрах по значению

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

тип_результата ммя_функции (тип_параметра имя_параметра);

Вопрос№10 Передача данных в параметрах по ссылке

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

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

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

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

Вопрос№11 Параметры по умолчанию

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

Параметр по умолчанию проходит проверку типа во время описания функции и вычисляется во время ее вызова. Задавать параметр по умолчанию можно только в прототипе функции и только для последних аргументов, используя формат тип имя_функции (, тип_параметра имя_параметра = значение_по_умолчанию);

например:

Вопрос№12 Параметры функции main

В большинстве программ нет необходимости использовать аргументы функции main. В этом случае она описывается как

int main() или int main(void)

В Borland C++ возможно использовать до трех параметров в качестве аргументов main. Аргументы main возвращают параметры командной строки загруженной программы. Прототип main при этом примет вид

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

где argc – число параметров командной строки;

argv[] – вектор указателей строк значений параметров, где первый соответствует полному имени загруженной программы.

env[] – вектор указателей на строки переменных окружения command.com.

Вопрос№13 Параметры-массивы и параметры-структуры

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

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

void compute1(int* vec_ptr, int vec_size); // один способ

struct Tvector // другой способ с помощью структуры

{ int* ptr; // указатель на целочисленный массив

int size; // размер массива

};

void compute2(vec v);

При использовании в качестве параметров функций переменных-структур возможно следующее:

1) использование для передачи данных по значению;

2) использовать для передачи данных по ссылке.

При передаче данных по ссылке внутри тела функции используется указатель на структуру. Доступ к данным полей структуры выполняется с помощью оператора «стрелка» (->). Который автоматически выполняет операцию разыменовывания. Формат:

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

_поля

ВОПРОС№14 Рекурсивной называется подпрограмма, которая внутри своей операторной части вызывает саму себя.

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

int fac(int n) {return (n>1) ? n*fac(n-1) : 1; }

Что может быть переписано в виде:

int fac(int n)

{ if (n > 1) return n*fac(n-1);

else return 1;

}

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

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

ВОПРОС№15 С функцией можно делать только две операции: вызывать ее и брать ее адрес. Указатель, полученный взятием адреса функции, можно затем использовать для вызова этой функции. Указатель на функцию объявляется в формате:

тип_функции (*имя_указателя)(список_аргументов);

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

имя_указателя = &имя_вызываемой_функции;

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

(*имя_указателя)(список_фактических_параметров);

Например:

void error(char* p) { /* тело функции */ }

void (*efct)(char*); // указатель на функцию

void f()

{ efct = &error; // efct указывает на error

(*efct)("error"); // вызов error через efct

}

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

Статический модуль в языках С и С++ образуется из двух файлов:

  1. заголовочного h-файла, который является интерфейсом модуля,

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

Структура заголовочного файла расписана выше, а состав файла реализации следующий:

  1. директива #include “заголовочный файл модуля”, подключает h-файл;

  2. список include-подключения внешних ресурсов других модулей;

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

  4. описание внешних (extern) переменных, объявленных в других модулях проекта, которые не подключены с помощью include;

  5. собственные внутренние функции модуля, используемые только внутри модуля;

описание функций, прототипы которых объявлены в h-файле модуля

ВОПРОС№17 DLL аналогичны модулям, но существуют следующие различия:

  • DLL могут экспортировать в качестве ресурсов в другие DLL и программы только функции;

  • DLL подключаются не статически, а динамически;

  • DLL могут создаваться только для защищенного режима MS DOS или Windows.

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

По структуре текст DLL похож на программы, за исключением:

  1. главная функция не main (или WinMain), а DllEntryPoint, которая в среде C++Builder 6.0 объявляется с помощью пункта File/New/Wizard DLL и имеет вид

#include <windows.h>

#pragma argsused

int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)

{ // здесь помещается текст

return 1;

}//---------------------------------------------------------------------------

  1. экспортируемые из библиотеки функции объявляются в следующем формате:

extern “C” __declspec(dllexport) тип_результата имя(список параметров)

ВОПРОС№18 Объектный тип данных – это структурированный тип данных, обладающих основными свойствами объектно-ориентированного программирования:

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

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

в) наследование - порождение нового объектного типа (потомка) от старого (предка) с сохранением доступа у потомка к коду и данным предка;

г) полиморфизм - задание одного имени действию, которое передается вверх и вниз по иерархии объектов, с реализацией этого действия способом, соответствующим каждому объекту в иерархии

В С++ общий формат объявления объектного типа (класса) следующий

class имя_объектного_типа

{ поля частного раздела private ;

прототипы членов-функций раздела private;

public :

поля общего раздела public ;

прототипы членов-функций раздела public;

} имена_объектов_класса;

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

тип_поля имя_поля;

Описания прототипов членов-функций обоих разделов выполняется аналогично обычным подпрограммам С++

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

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

Определение функций-членов класса производится до определения тела функции main программы или в части реализации внешнего модуля. При этом в заголовке функции-члена класса указывается составное имя:

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

{ тело функции члена класса

}

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

имя_объекта.имя_функции(список фактических параметров);

ВОПРОС№19 Создания нового порожденного объектного типа в С++ производится после описания предка по следующей схеме

class имя_класса_потомка : тип_доступа_к_ресурсам имя_класса_предка

{ новые поля данных класса частной секции класса

прототипы новых функций членов частной секции

protected : новые поля данных класса защищенной секции

прототипы новых функций членов защищенной секции

public : новые поля данных класса публичной секции

прототипы новых функций членов публичной секции

} объекты класса;

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

Тип доступа к ресурсам может быть задан тремя способами:

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

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

ВОПРОС№20 В составе класса могут входить две специальные функции:

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

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

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

class имя_типа_класса

{ поля раздела private ;

прототипы членов-функций раздела private;

public :

поля раздела public ;

имя_класса(список_параметров); // описание конструктора

~имя_класса(); // описание деструктора

прототипы членов-функций раздела public;

} имена_объектов_класса;

Определения тел конструктора и деструктора выполняется аналогично обычным членам-функциям, только без указания возвращаемого типа результата выполняется аналогично обычным подпрограммам С++.

имя_класса :: имя_класса (список формальных параметров)

{ тело конструктора

}

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

имя_класса :: ~имя_класса ()

{ тело деструктора

}

ВОПРОС№21 Дружественная функция описывает свой прототип внутри секции public класса, к полям объектов которого она может иметь доступ, аналогично функциям-членам класса, но с указанием вначале слова friend. Формат описание дружественной функции внутри класса

class имя_класса

{ …

public :

friend тип_результата имя_функции(параметры функции);

} список объектов класса;

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

ВОПРОС№22 Inline-функция языка программирования С++ отличается от обычной тем, что ее тело передается в каждую точку вызова вместо генерации кода вызова.

Имеется два способа определения inline-функций членов класса.

При первом способе общая форма прототипа inline-функции в составе класса использует зарезервированное слово inline и имеет общий вид

inline тип_результата имя_функции (список параметров);

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

inline тип_результата имя_класса::имя_функции (список параметров)

{ тело функции };

Второй способ определения inline-функций членов класса позволяет сразу в классе описать вместе с прототипом и тело функции. При этом не указывается слово inline.

class имя_класса

{ . . .

тип_результата имя_функции (список параметров) {тело функции;};

. . .

};

В качестве inline-функций следует использовать короткие функции. Только в этом случае достигается эффективность кода программы.