Динамическое управление памятью (new, delete).

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

Для выделения памяти под любую переменную используется операция new [2]:

указатель = new имя_типа инициализатор

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

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

delete указатель

осуществляется явное освобождение памяти.

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

23. Динамические массивы в языке программирования с++.

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

int *mas1; // одномерный массив

mas1=new int[n];

float *mas2; // двумерный массив

mas2 = new float [n*n];

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

24. Использование указателей при обработке массивов в языке программирования с++.

25. Описание функций, фактические и фоpмальные паpаметpы в языке программирования с++.

Программа в языке С++ состоит из функций. Функции – относительно самостоятельные фрагменты программы, спроектированные для решения конкретных задач и снабженные именем [2]. С одной из них, главной, уже знакомы. Функции аналогичны программам в миниатюре и и меют общее название подпрограммы. Главное отличие простой функции от главной в том, что с главной функции начинается выполнение программы, а все остальные функции вызываются либо главной, либо из других функций. Применение функций (подпрограмм) дает возможность сэкономить память за счет размещения многократно повторяющихся частей программ в функции, а также возможность конструировать программу как набор отдельных подпрограмм, что, в свою очередь, позволяет работать группе программистов над сложной задачей. Даже в том случае, если некоторая задача решается в одной функции и одним программистом, лучше оформить ее решение в виде подпрограмм, поскольку функции повышают уровень модульности, облегчают чтение, внесение изменений и коррекцию ошибок в программе.

Общая форма записи заголовка функции:

<тип> <имя> ([<список формальных параметров>])

Здесь <имя> - правильный идентификатор, который используется для обращения к функции;

<тип> - тип возвращаемого функцией результата;

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

Вызов функции производится при помощи оператора вызова функции:

<имя >(<список фактических параметров>);

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

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

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

Символьная переменная – это величина размером в 1 байт, которая используется для представления литер и целых чисел в диапазоне от 0 до 255 или от –128 до 127. Диапазон зависит от того, знаковая это переменная или нет. Символьные константы заключаются в апострофы.

Для ввода символов можно использовать специальные функции ввода-вывода. Функция getchar () получает один символ, поступающий с клавиатуры, и передает его выполняющейся в данный момент программе. Функция putchar() получает один символ, поступающий из программы, и передает его для вывода на экран.

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

28. Стpуктуpы и объединения в языке программирования с++.

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

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

год выпуска автомобиля (целый тип);

объем цилиндра (целый тип).

Объявление структуры:

struct < имя типа >{

< сп. полей >

};

Здесь struct ключевое слово; < имя типа > правильный идентификатор; < сп. полей > список полей, представляющий собой последовательность разделов, между которыми ставится точка с запятой.

Со структурами в «близком родстве» находятся объединения, которые описываются с помощью ключевого слова union [11]. Синтаксис описания объединения отличается от описания структур только ключевым словом:

union < имя типа >{

< сп. полей >

};

Здесь < имя типа > правильный идентификатор; < сп. полей > список полей, представляющий собой последовательность разделов, между которыми ставится точка с запятой.

29. Битовые поля в языке программирования с++.

В отличие от других языков программирования язык Си обеспечивает доступ к одному или нескольким битам в байте или слове. Внутри структур и объединений могут в качестве их компонентов использоваться битовые поля. Каждое битовое поле представляет целое или беззнаковое целое значение, занимающее в памяти фиксированное число битов (от 1 до 16). Битовые поля могут быть только элементами структур, объединений и классов, т. е. они не могут быть самостоятельными объектами программ. Битовые поля не имеют адресов, нет указателей и ссылок на битовые поля. Они не могут объединять-ся в массивы. Назначение битовых полей – обеспечить удобный доступ к от-дельным битам данных. Чаще всего битовые поля используют при работе с флажками, которые могут принимать только два значения, что позволяет экономить память.

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

struct <имя>{

<тип поля> имя поля1: длина в битах;

<тип поля> имяполя2: длина в битах;

<тип поля> имя поля N: длина в битах;

}

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

struct w{

int a:9;

int :7;

int b:9;

};

30. Двоичные файлы в языке программирования с++.

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

Открытие двоичного файла производится той же функцией, как в тек-стовом файле, но тип открываемого файла явно указывается:

in=fopen("input.dat","rb");

Для организации прямого доступа к компонентам двоичного файла служит встроенная функция fseek:

fseek ( in, offset, wherefrom )

Здесь in - указатель файла прямого доступа; offset - выражение типа long, указывающее число байт смещения от точки, определяемой третьим параметром функции; wherefrom указывает точку, от которой следует начинать отсчет смещения, заданного вторым аргументом. Для этого определены следующие константы:

#define SEEK_SET 0

#define SEEK_CUR 1

#define SEEK_END 2

Значение 0 - смещение от начала файла.

Значение 1 - смещение от текущей позиции файла.

Значение 2 - смещение от конца файла.

31. Классы памяти. Область действия имен в языке программирования с++.

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

В языке С++ различают четыре класса памяти:

· автоматический (auto)

· внешний (extern)

· статический (static)

· регистровый (register)

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

32. Текстовые файлы в языке программирования с++.

Текстовый файл можно представить как набор строк произвольной длины. Для деления на строки используется управляющий символ ’\n’. Он является файлом последовательного доступа. Логически текстовый файл можно представить как именованную цепочку байтов, имеющую начало и конец. Чтение (или запись) из файла (в файл) ведется байт за байтом от начала к концу. Перед первым обращением к функциям ввода-вывода указатель файла стоит в его начале и указывает на первый компонент. После каждого чтения или записи указатель сдвигается на заданное количество байт. Такой способ доступа называется последовательным. Текстовые файлы оказываются переносимыми с одного типа компьютера на другой, если символы, содержащиеся в файле, принадлежат стандартному набору символов (т. е. не используются дополнительные символы, такие, например, как символы псевдографики фирмы IBM)

33. Аргументы главной функции в языке программирования с++.

Эта функция может иметь два параметра argc и argv, которые передаются из внешнего окружения. Соглашение о передаче параметров в большей степени определяется операционной системой, чем самим языком С++. Параметр argc имеет тип int и определяет число передаваемых параметров, которые могут быть приняты за имя и аргументы программы. Параметр argv имеет тип char *[] и указывает на начало массива строк, являющихся передаваемыми параметрами. Каждая строка заканчивается нуль-символом. Система использует пробелы, чтобы сообщить о конце одной и начале другой строки символов.

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

35. Перегрузка функций в языке программирования с++.

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

36. Шаблоны функций в языке программирования с++.

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

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

Шаблон семейства функций состоит из двух частей – заголовка шаблона:

template <class type>

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

37. Подставляемые функции в языке программирования с++.

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

inline int FCUBE(int x)

{

return x*x*x;

}

b = FCUBE(a);

c = FCUBE(a++);

inline-подстановка не может содержать операторов управления if, for, case, switch, while.

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

38. Значения параметров функции по умолчанию в языке программирования с++.

В С++ фоpмальным паpаметpам функций могут быть пpисвоены значения по умолчанию. Если параметр имеет значение по умолчанию, то все параметры, стоящие справа от него тоже должны иметь значение по умолчанию [7]. Эти значения передаются функции, когда данный параметр не указан при ее вызове.

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

void drawсircle(int x = 100, int y = 100, int r = 100)

или

void drawсircle(int = 100, int = 100, int = 100) .

Тогда вызовы этой функции будут проинтерпретированы в зависимости от передаваемых параметров:

drawcircle(); // Окружность с центром (100, 100), радиусом 100

drawcircle(200); // Окружность с центром (200, 100), радиусом 100

drawcircle(200, 300); // Окружность с центром (200, 300), радиусом 100

drawcircle(200, 300, 200); // Окружность с центром (200, 300), радиусом 200

drawcircle(, , 50); // Ошибка

Наши рекомендации