Добавил:
okley
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Программирование C++ (1 сем, мага) / Лабы / Лабораторная работа №4
.pdf
Министерство науки и высшего образования Российской Федерации
Федеральное государственное автономное образовательное учреждение высшего
образования
«Национальный исследовательский ядерный университет «МИФИ»
Кафедра экспериментальной ядерной физики и космофизики (№7)
Программирование на С и С++
Отчет по лабораторной работе № 4
Выполнил:
студент группы M22-105 Васильева А.П.
Москва, 2022

Цель работы: знакомство с функциями, в том числе с функциями переменного числа
аргументов.
Задачи работы: реализовать функцию с переменным числом аргументов, которая
заполняет массив указателей.
При этом тип массива – unsigned char*, размерность соответствует номеру телефона
(четным цифрам). Началом массива будет число, которое представляет собой сумму трех
символов, находящихся в середине файла. Значения остальных элементов получаются с
использованием операции инкремента.
Введение
Функции представляют собой программные блоки, которые могут вызываться из
разных частей программы. При вызове в них передаются некоторые переменные, константы,
выражения, являющиеся аргументами, которые в самих процедурах и функциях
воспринимаются как формальные параметры. При этом функции возвращают значение
определенного типа, которое замещает в вызвавшем выражении имя вызванной функции.
Тип возвращаемого значения может быть любым, кроме массива и функции. Могут
быть также функции, не возвращающие никакого значения. В заголовке таких функций тип
возвращаемого значения объявляется void. Если тип возвращаемого значения не указан, он
по умолчанию считается равным int.
Передача параметров в функцию осуществляется тремя способами:
• по значению;
• по адресу;
• по ссылке.
Макрос, определяемый директивой препроцессора #de fi ne, это символическое имя
некоторых операций. Как и в случае символических констант, идентификатор макроса
заменяется на замещающий текст до начала компиляции программы. Но сначала в
замещающий текст подставляются значения параметров, а затем уже этот расширенный
макрос подставляется в текст вместо идентификатора макроса и списка его параметров.
Иногда в функции требуется передавать некоторое число фиксированных параметров и
неопределенное число дополнительных параметров. Тогда заголовок функции имеет вид:
тип имя_функции(список аргументов, …)

Для работы с этими параметрами в файле stdarg.h определен тип списка va_list и
три макроса: va_start, va_arg и va_end.
Макрос va_start имеет синтаксис: void va_start(va_list ap, lastfix) –
начинает работу со списком, устанавливая его указатель ap на первый передаваемый в
функцию аргумент из списка с неопределенным числом аргументов. Параметр latfix – имя
последнего из обязательных аргументов функции.
Макрос va_arg имеет синтаксис: type va_arg(va_list ap, type) – возвращает
значение очередного аргумента типа type из списка. Перед вызовом значение ap должно быть
установлено вызовом va_start или va_arg. Каждый вызов переводит указатель ap на
следующий элемент.
Макрос va_end имеет следующий синтаксис: void va_end(va_list ap) –
завершает работу со списком, освобождая память. Он должен вызываться после того, как с
помощью va_arg прочитан весь список аргументов.

Ход работы
Написана программа, имеющая следующий код:
Согласно номеру телефона, требовалось создать массив указателей размерности
[6][7][1]. Три символа в середине файла – 0x20, 0x20, 0x20. Следовательно, первый
элемент массива: 0x20 + 0x20 + 0x20 = 0x60.
В блоке main() программы создается массив указателей arr, а так же вычисляется
величина, которой должен быть равен первый элемент массива:
До вызова функции SetArrayValues (соответственно до заполнения массива) массив
имел следующий вид:

Заполнение массива происходит в функции:
void SetArrayValues(unsigned char firstElValue,
unsigned char** arrayEl, int arrayDimension, …)
Тип функции void – функция не возвращает никакого значения.
Аргументы функции:
• unsigned char firstElValue – значение, которому должен быть равен
первый элемент массива. Передается по значению.
• unsigned char** arrayEl – указатель на первый элемент массива
указателей. Передается по адресу, поэтому функция может выполнять операции
над элементами массива. До заполнения массива его элементы содержат
указатели на произвольные ячейки памяти. Так, первый элемент массива
содержит указатель на ячейку памяти с адресом 0x7ffff7fa86bc, хранящую
значение 0х2:
• int arrayDimension – размерность массива (в случае одномерного
массива – 1, в случае двумерного – 2 и т.д.).
• … – аргументы, соответствующие количеству элементов измерений массива.
Число аргументов будет отличатся для массивов разных размерностей.
Сначала в функции определяется общее количество элементов в массиве. Для работы с
аргументами функции, описывающими измерения массива, создается объект argPtr типа
va_list и с помощью макроса va_start его указатель устанавливается на первый из
аргументов, следующих за arrayDimension. В цикле for с помощью макроса va_arg
получаем значения каждого из аргументов, описывающих размерность массива, и путем их
перемножения получаем количество элементов в массиве.

После определения количества элементов в массиве работа со списком завершается –
вызывается макрос va_end.
Требуется заполнить массив указателей, т.е. элементы массива должны хранить адреса
на определенные ячейки памяти, содержащие конкретные значения. Для этого в работе
создан массив ptr типа unsidned char, первый элемент которого равен firstElValue,
а последующие получены с помощью операции инкремента. Элементы массива указателей –
адреса соответствующих элементов массива ptr.
Заполнение массива ptr и массива указателей происходило в цикле for. До входа в цикл
массив ptr имел следующий вид:
Значения и адреса элементов массива ptr, а также массива указателей, который
требуется заполнить в функции в процессе работы цикла:
После выхода из тела функции массив указателей заполнен указателями:

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

Заключение
В лабораторной работе освоена работа с массивами указателей и функциями с
переменным числом аргументов:
1. Создан трехмерный массив указателей размерности [6][7][1].
2. Реализована функция, заполняющая массив указателей произвольной
размерности.
3. Работа с аргументами функции, число которых может варьироваться,
осуществлялась с помощью списка va_list и макросов: va_start, va_arg и va_end.
Соседние файлы в папке Лабы
