Similar presentations:
Библиотеки функций. Раздел 2. Передача параметров в командной строке
1.
А. Г. ЕпифанскийОсновы Алгоритмики
Кафедра программного обеспечения систем
радиоэлектронной аппаратуры
Тема VIII
Библиотеки функций
Раздел 2. Передача параметров в командной строке
Семестр — первый
2.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
Сегодня мы начинаем построение библиотеки функций, позволяющих
автоматизировать процесс передачи параметров в программу через
командную стоку.
В начале рассмотрим постановку задачи, сформулируем запросы со стороны
прикладного алгоритма к функциям библиотеки. Отсюда получим список
параметров, которые необходимы в основном объекте — представлении
командной строки. Очевидно, что основной объект представляет собой
массив (вектор), в котором для каждого потребного программе парамера
предусмотрен свой элемент — описание атрибутов параметра, которые
имеют актуальное значение.
Под актуальным значением мы подразумеваем то значение, с которым
программа будет выполнять свой алгоритм.
Составление кода функций начнем, как было указано ранее, с
составления заголовочных файлов. Файлов будет два: а) заголовочный
файл декларации объекта параметра и функций библиотеки и б )
заголовочный файл с прототипом основного объекта.
3.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
В программировании передача параметров может осуществляться при
помощи двух способов идентификации: ключевой и позиционной. В первом
случае перед каждым передаваемым значением помещается имя параметра,
а затем само значение. Второй способ — передача значений параметра по
местоположению. Оба способа обладают своими преимуществами и
недостатками. Преимущество одного способа представляет недостаток
другого и наоборот.
Передача «по ключу» требует кроме записи самого значения, запись
идентификатора или ключа, идентифицирующего значение с параметром,
что требует затрат дополнительной памяти для имени и дополнительной
работы по распознаванию ключа. Второй свободен от указанного расхода
памяти, но требует либо помещения всех значений для сохранения порядка
следования параметров, либо специального метода указания пропущенного
значения.
Как видим, определить заранее какой способ может быть предпочтителен не
всегда просто. Обычно, это решение принимает разработчик ПО.
4.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
В нашем случае способ передачи параметров в программу уже принят
разработчиками системы, поэтому нам остается только следовать этому
решению. Параметры в системе UNIX программе передаются через командную
строку как и ключевым способом, так и позиционным. Здесь нет никакой мистики.
Значения параметров настройки программы всегда передаются через ключи, а
данные для обработки иногда через список, т. е. без ключей. Это когда количество
их не определено. Однако, такой смешанный способ передачи значений
параметров подразумевает строгий порядок — в начале следуют ключевые
параметры, затем список значений неключевых.
Следует попутно заметить, что при вызове функции параметры передаются
всегда позиционным способом.
Другое замечание касается постановки задачи. Задачу на построение библиотеки
функций мы ставим в условиях, когда не все представляют себе потребность в
подобной библиотеке. Начинаем мы так, потому, что очень скоро, при
рассмотрении следующем примера, мы будем этой библиотекой пользоваться.
5.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
Постановка задачи.
Требуется построить набор функций, которые при запуске программы
проанализируют командную строку и выберут все, заранее
предопределенные при создании программы параметры, значения
которых требуется для выполнения алгоритма с соответствующими
ключами, и заполнят идентифицированный при помощи ключа элемент
основного объекта с точки зрения наличия ключа в командной строке,
наличия значения данного параметра в командной строке, заполнения
заданного значения в элементе для передачи этого значения в
ассоциации с параметром данного ключа.
В постановке указаны все необходимые атрибуты элемента основного
объекта, которые потребуются нам для дальнейшего использования функций
библиотеки. Но нет указания на то, как этими атрибутами пользоваться. В
течении данной и следующей лекций мы попробуем описать уточнения
предложенной постановки, устраняющие этот недостаток.
6.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
В начале заметим, что определить было ли значение ключа «введено» в
командной строке или нет и получить значение в элемента основного объекта
являются различными вопросами, не смотря на кажущуюся абсурдность
данного вопроса. При разработке программы само наличие ключа в
командной строке может быть сигналом, отдельно от наличия самого
значения. Другими словами, значение ключа может отсутствовать в
командной строке, и быть задано при подготовке программы. Это называется
значением по умолчанию.
Кроме того, могут быть ключи не требующие значений или не принимающие
значений! И здесь снова нет никаких загадок — мы должны использовать все
возможные комбинации ключей и значений параметров для обеспечения
максимально возможной гибкости функций библиотеки при написании
алгоритма, опирающегося на данный набор библиотечных функций. На это
стоит обратить внимание.
При составлении библиотек нет малозначащих мелочей.
7.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
Приступим к составлению объекта, ассоциируемого с ключевым параметром.
Первое замечание. В системе UNIX принято часто используемые ключевые
параметры идентифицировать одно символьным ключом. Это удобно со
многих точек зрения, если не считать, что число букв любого алфавита
ограничено. Для идентификации начала ключа принято использовать символ '' (минус). Особое значение имеет сдвоенные символы минус ('--'). В некоторых
случаях они означают, что на этом ключе парсер (функция разборщик,
анализатор командной строки) должен закончить свою работу. Обычно, это
означает, что когда задача сама вызывает следующую программу, все
следующие за этим ключом часть командной строки передаются в
вызываемую программу. В большинстве же случаев, сдвоенным символом
минус следует много символьный ключ.
Заметим, что часто одно символьные ключи, если они не принимают значений,
могут записываться подряд за одним символом минус.
Выше мы описали некоторый сложившийся стандарт правил системы UNIX. Однако, бывают
исключения. Так в качестве идентификатора ключа могут использоваться некоторые другие
символы, не задействованные в кодировании файловых идентификаторов и не имеющие
специального значения для команд утилит SHELL. Например, может использоваться символ '+'.
8.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
Итак, каждый ключевой параметр командной строки начинается с символа
идентификации ключа. Поскольку ключ может идентифицироваться
несколькими символами, начнем нашу структуру, назовем ее struct cmd_item{ }, с
элемента типа char, следующим параметром поместим сам ключ.
Если вы решите, что в набор ключей будут входить только одно символьные ключи, то под
имя ключа достаточно тоже оставить один символ — char. Если вы предпочитаете
реализовать более универсальный подход, то есть два способа это сделать: а) выделить
один символ под первую букву (ключи всегда как и идентификаторы должны начинаться с
буквы) один символ, т. е. char, а остальные поместить в строку, а в объект поместить
указатель на эту строку. Нулевое значение этого указателя будет означать, что ключ
кодируется одним символом. Мы в дальнейшем ограничимся односимвольным вариантом.
При самостоятельной разработке студенты вольны принимать решение самостоятельно.
Одно замечание относительно того, что в структуру мы поместили указатель вместо строки.
Строка символов может иметь различную длину. Для получения универсального варианта
структуры лучше выбирать типы, имеющие стандартную длину.
Следующим элементом поместим целое число. Использовать это число мы
будем как битовую «маску» — это когда каждый бит или несколько битов
этого числа имеет свое отдельное значение.
9.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
Теперь осталось два элемента разрабатываемой структуры. Первый это
собственно значение параметра. Это должна быть строка, так как ее оператор
вводит при вызове программы. Второй элемент пусть текст, который объясняет то
каким образом должен использоваться при вызове программы текущий ключ.
Ниже приведен пример кода с определением полученной структуры.
struct cmd_item
{
char sng;
char key;
int mask;
char * val;
char * usg;
};
/* key start symbol */
/* first key letter
*/
/* bits mask
*/
/* value - pointer to string */
/* pointer to help text */
Структура вместо элементов неопределенного размера ссылается на них через
указатель. Как отмечалось выше, если студент пожелает включить много
символьные ключи, он должен добавить указатель на «продолжение» имени
ключа без первого символа.
10.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
Рассмотрим, каким образом мы можем теперь определить «всю» командную строку,
полностью?
Это связан стем, что при разработке программы число ключевых, а также не
ключевых параметров индивидуально. При этом, мы хотим сохранить
универсальность нашей библиотеки.
Для определения всех необходимых параметров, которые могут быть указаны в
командной строке, мы используем следующую конструкцию языка C/C++.
struct cmd_item[] =
{
{
'-', 'h', 0, NULL, “Cause to print help this text”
},
.
some lines definition */
{
.
0,
.
.
.
.
.
0, 0, NULL, NULL
}
} CmdItemsList;
Этот фрагмент текста определения массива структур, определяющий число
элементов «по факту». Пусть это будет файл ”cmd_config.h”.
./*
11.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
Приведенный выше пример определяет массив из заданного по факту числа
элементов. Каждый элемент определяется как группа параметров,
соответствующих одному элементу структуры, которые заключены в
фигурные скобки. Значения параметров разделены запятыми. Каждый
элемент структуры также разделены запятыми. Число элементов структуры
произвольно.
Компилятор сам определяет число элементов массива, необходимых для
размещения значений всех элементов структур.
Обратите внимание на последний элемент структуры. Все значения этого
элемента равны нулю. Таким образом, мы в коде имеем возможность
определить окончание списка элементов структуры. Можно подсчитать
число элементов «в ручную», но это не удобно — при каждом изменении
числа элементов придется править код. Приведенный пример указывает, как
это может быть сделано автоматически: при переборе всех элементов в
массиве нулевой элемент всегда указывает на исчерпание списка.
12.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
И теперь, когда определена структура каждого элемента, соответствующего
отдельному ключ, а также структура массива, задающего общую структуру
командной строки, мы можем приступить непосредственно составлению
списка функций библиотеки.
Очевидно, функции библиотеки можно разбить на две группы. В первой
группе будут сосредоточены функции, которые вызываются из программы и
которые, тем самым, определяют функциональное наполнение библиотеки.
Во вторую группу поместим те функции, которые исполняют
вспомогательные функции, например поиск элемента по заданному ключу.
Определить список «внешних» функций достаточно легко — все
потребности программистов сосредоточены на том, чтобы получить
максимально удобно подробную информацию о наличии в комендной
строке того или иного ключа, а также, получить ссылку на значение ключа и
информацию о том, как было задано это значение.
Что никак нельзя сказать о вспомогательных функциях.
13.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
По указанной выше причине оставим на время вспомогательные функции и
начнем с функций внешних определяющих функциональность библиотеки.
Первыми двумя функциями следует считать функцию разбора командной
строки cmd_parser(.,.) и функцию cmd_usage(.) печати на экран содержания,
ранее определённого массива Cmd_Items_List.
Функция cmd_parser(.,.,.) будет принимать три значения, два из которых
передает система программе в виде аргументов функции main(.,.), а третий,
который в действительности является первым, адрес массива структур
описания командной строки. Два следующих аргумента — число «слов» в
командной строке и массив адресов строк, содержащих значения этих слов.
Сигнатура функции cmd_parser(.,.,.) имеет вид:
typedef struct cmd_item CMD_HLDR;
CMD_HLDR * cmd_parser(CMD_HLDR *, int argc, char * argv[]);
14.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
Обратите внимание на новое в нашем курсе «резервированное слово» языка
C/C++, т. е. typedef, которое означает просто определение имени нового типа, а
именно типа объекта CMD_HDLR (command line holder) — структура, содержащая
описание командной строки. Очевидно это будет единственный раз, когда
программист получит доступ к адресу структуры, если разбор командной строки
завершился успешно. В противном случае программа вернет значение NULL.
Использование этой функции (а также следующей из первой пары) очень просто.
Следующий фрагмент кода иллюстрирует это:
#include ”cmd_parser.h”
#include ”cmd_config.h”
int main(int argc, char * argv[])
{
if ( cmd_parser(CmdItemList, argc, argv) == NULL )
{
cmd_usage(”Cmd parsing error”);
Exit(0);
}
.
.
.
.
.
. /* function more code */
}
15.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
Приведенный выше фрагмент кода дает представление о том, как выглядят
сигнатуры первых двух функций нашей библиотеки, как их использовать и
как обработать ошибку несоответствия командной строки шаблону.
Поскольку мы ранее выписали строгое определение только первой функции,
сделаем это и для второй — cmd_usage(.).
void cmd_usage(constant char *);
Вторая функция предназначена распечатать шаблон командной строки на
экран. В начале печати выводится строка, адрес которой передается в
качестве единственного аргумента. Если аргумент имеет нулевое значение,
никакой дополнительной информации не выдается.
На этом мы прервемся. На следующей лекции продолжим рассматривать
прототипы функций библиотеки. Студенты могут начинать строить
необходимые файлы на практических занятиях и самостоятельно.
16.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
Продолжение предыдущей лекции
17.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
Приведенный на предыдущем слайде фрагмент кода дает представление о
том, как можно инициировать «базу данных» командной строки и придать
начальные значения ключам из командной строки. Другими словами,
заполнить зоготовленный, при разработке программы, массив описания
командной строки актуальными значениями.
Обратим внимание на то, что функция cmd_parser(.,.,.) возвращает адрес
переданного ей в первом аргументе адреса базы данных описания
командной строки. В момент возврата адреса, значения полей оказываются
преобразованными в соответствии с алгоритмом обработки командной
строки и реальным содержанием значений полей командной строки.
В случае обнаружения ошибок в командной строке, возвращается значение
нуль. В этом случае необходимо выдать сообщение на экран и прекратить
выполнение задачи. При этом сообщение должно быть дополнено
содержанием полей базы данных на момент на момент окончания
обработки. Для этого использована вторая функция cmd_usage(.).
18.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
Заметим, что в приведенном примере использования указанных функций
не предусмотрена передача в вызывавшую функцию значения ошибки.
Для передачи кода ошибки, если студент решает дополнить алгоритм такой
опцией свой алгоритм обработки командной строки, можно стандартным
для системы UNIX и технологии программирования на языке C/C++, а
именно передачей значения кода ошибки в переменной, стандартно
определяемой в заголовочных файлах переменной, определяемой в
программном модуле как extern int errno. Но следует учитывать, что через
эту переменную передаются в пользовательскую программу ошибки,
определенные в библиотечных функциях библиотеки GLIBC. Поэтому
пользовательские значения ошибок начинать с номера больше чем 256
или, даже, 512, чтобы избежать интерференции с кодами ошибок,
передаваемыми системой.
Еще раз обращаю внимание слушателей, что разрабатываемую библиотеку
функций предлагается использовать во всех дальнейших разработках.
19.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
Теперь перейдем к выработке функций, которые помогут программисту в
разработке программ, управляемых параметрами из командной строки.
Студенты не должны удивляться подходу, когда мы выписываем сигнатуры
функций но не разрабатываем коды самих функций. В программировании
это подход или технология называется «Программирование с верху вниз».
Такой подход применяется всегда при разработке прикладных программ.
Этот подход мы будем использовать на протяжении всего курса. При
разработке прикладных программ будем сначала составлять алгоритм,
заменяя некоторые части кода или выражений функциями. Если требуемая
функция будет найдена в какой-либо библиотеке, мы применим эту
функцию, если подходящей функции обнаружить не удается, будем
разрабатывать собственную.
Здесь следует сделать замечание: при разработке прикладных задач,
функции не обязательно должны иметь «широкий спектр применимость».
Но выделение отдельной функции не должно затруднять понимания самого
алгоритма при чтении, сохраняя, тем самым, прозрачность кода.
20.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
Итак, вернемся к нашей библиотеке.
Поставленная нами в начале раздела задача — разработать библиотеку
функций, а не прикладную программу. В этом случае возникает вопрос: как
соотносится постановка задачи с сформулированной выше технологией
разработки программ сверху вниз. Ответ следующий. Для тестирования
функций вновь разрабатываемых библиотек требуется использовать их в
составе прикладных программ. Правда, прикладная задача, в данном
случае, является «тестером», т. е. инструментом тестирования и отладки.
Кроме того, применяемый нами подход имеет важное значение в части
самого алгоритма разработки прикладных программ. По этой причине,
первый наш код это функция main(.,.). По этой же причине, в
действительности, уже приведенного кода достаточно для начала
кодирования заголовочных файлов, функций тестирования, а также
первых функций библиотеки, даже если сами определения этих функций
еще не построены.
21.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
Будем называть функции, которые не выполняют никакого действия, а
только имитируют работу, «пустыми» функциями. Тогда пустые функции
будут служить для имитации работы алгоритма. Цель этого, начать как можно
раньше проверку, т. е. отладку кода. В дальнейшем такие пустые функции
будем наполнять содержанием, создавая, тем самым, алгоритм задачи.
Учитывая все сказанное, мы можем приступить к кодированию программы
«тестер» для нашей разрабатываемой библиотеки. Заметим, отладку кода
можно вести на любом уровне, тестирование кода возможно только в
составе прикладной программы.
Итак, студенты обязаны в выделенной для разработки директории начать
составлять три заголовочные файла, указанные ранее. Наименования
файлов, типов объектов, функций могут выбираться каждым разработчиком
самостоятельно. Для ориентации в написанном коде необходимо с самого
начала писать сопроводительную документацию.
Хороший пример описания — формат файлов утилиты man.
22.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
Начиная разработку с заголовочных файлов, мы строим описание всех
необходимых объектов, Эволюция которых составит основу нашей
прикладной задачи.
После того, как построение заголовочных файлов завершено, можно
приступать к написанию кодов для самих функций.
Функции прикладной части программы и библиотечные функции должны
быть разнесены по различным модулям. При наполнении содержанием
модулей следует начинать с вызовов заголовочных файлов. Заголовочные
файлы, формирующие объекты (когда под объект выделяется память), а не
только их декларации, должны вызываться только в том случае, есть
определенные в них объекты действительно необходимы в этих модулях.
Это связано с выделением под эти объекты памяти. Обратите внимание, если
требуется использовать глобальные объекты в нескольких модулях, то для
их объявления следует использовать модификатор extern, кроме одного
модуля, где благодаря определению объекта под него будет выделена
память.
23.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
Следует сразу предупредить, что определение объектов с одним именем в
нескольких модулях без использования модификаторов extern или static
приведет к сообщениям об ошибках при попытке собрать эти модули в
одном исполняемом файле.
Хороший стиль — минимальное число глобальных объектов.
Выбрав два модуля — прикладной программы тестирования и модуль
библиотеки, и подготовив функцию main(.,.) по приведенному образце,
можно уже приступать к отладке полученного кода. Не забывайте, что для
сборки исполняемого кода необходимо указать как прикладной, так и
библиотечный модули. Пусть вас не смущает, что полученные таким
образом исполняемые файлы содержат только пустые функции. Иногда
пустые функции называют заглушки.
Скомпилировать без ошибок и запустить на исполнение такие функции
можно только в том случае, если каждая из них возвращает значение, если
это требуется согласно декларации.
24.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
В случае, когда компиляция и сборка исполняемого файла прошли без
сообщений об ошибках, можно запустить этот модуль на исполнение.
Очевидно наличие в модуле с пустых функций говорит лишь о том, что мы
получили некоторую заготовку для нашей задачи. Теперь можно приступить к
наполнению наших пустых функций содержанием.
Для этого предлагаю дополнить функцию main(.,.) следующим кодом:
.
.
.
.
int main(int argc, char * argv[])
{
.
.
.
.
If ( cmd_tstkey('h') )
{
cmd_usage(NULL);
exit(0);
}
/*
*/
exit(0);
}
.
.
more code
-
-
25.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
Здесь присутствует новая функция, о которой мы еще не упоминали.
Сигнатура функции int cmd_tstkey(char).
Назначение функции проверить: был ли указанный в аргументе одно
символьный ключ задан в командной строке? (В данном случае проверяется
ключ '-h'.) Если функция возвращает ненулевое значение, то ответ
положительный. Согласно приведенному коду в этом случае, вызывается
функция печати содержания базы на экран.
Код функции-заглушки cmd_tstkey(.) может быть представлен как:
int cmd_tstkey(char c)
{
return TRUE;
}
Для начала трех функций-заглушек вполне достаточно, чтобы составить два
модуля и начать строить исполняемый модуль в целях отладки.
26.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
В программировании имеются два схожих термина: отладка и тестирование.
Первый применяется для обозначения процедуры поиска ошибок, в
частности, для выявления ошибок при компиляции и сборке программных
модулей в исполняемый модуль. (Английский термин — debugging.)
Второй — тестирование — для процедуры проверки правильности
исполнения кодом заданного алгоритма.
Процедура тестирования, как и отладки, направлены на выявление ошибок.
Но ошибки могут быть синтактические, которые вылавливает компилятор
или редактор связей, а могут быть семантические, т. е. смысловые, которые
утилиты построения программ не обнаруживают. Такие ошибки может
выловить только автор алгоритма. Не всегда такие ошибки определить
кодировщику. Это приводит к тому, что если код пишется отдельно от
автора алгоритма, тестирование превращается в достаточно сложную
задачу.
Вопросу тестирования будет посвящена специальная дисциплина.
27.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
Здесь мы приведем некоторые простейшие приемы, позволяющие вести
отладку алгоритма, т. е. тестирование.
В этих приемах нет ничего сверх мудрого — это визуализация прохода
алгоритмом того или другого места в программном коде во время
выполнения программы. Это можно осуществить при помощи вставления в
код отладочных печатей.
Первый прием это идентификация места, откуда выдается отладочная
печать. Во время выполнения программы при большом числе строк печати,
трудно бывает сразу определить место, в котором выдается сообщение. При
большом числе модулей и большом числе функций в каждом из модулей,
необходимость идентификации места выдачи сообщений превращается в
неразрешимую задачу, особенно с учетом ограниченности размеров экрана.
28.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
Поэтому, в самом начале разработки программ, а именно, при разработке и
начале кодирования модуля, каждый модуль необходимо
идентифицировать при помощи следующем кода:
static constant char * fid = ”cmd_parser.o”;
Этот текст помещается в самом начале модуля. (Напомним, что модуль
исходного кода и файла исходгого кода это синонимы).
Теперь, если необходимо в каком-то месте функции, пусть для
определенности это будет функция cmd_tstkey(.) , вставить печать, для
идентификации, что это часть кода сработала, вставляется код:
printf(”%s cmd_tstkey() \n”, fid);
Очевидно, эта печать идентифицирует место выдачи. Если требуется
вывести на экран какие-то значения, формат и значения могут бы
дополнены в эту строку вызова функции печати.
29.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
В заключительной части рассмотрения некоторых технологических
особенностей алгоритма создания программного продукта обратимся к
методам хранения информации о состоянии основных объектов
создаваемой библиотеки функций, которыми являются описания ключей.
Ранее, при составлени структуры cmd_item, которая является носителем
информации о состоянии ключей, в структуру был включен элемент —
маска состояний. Это набор элементов, число значений которых ограничен
обычно двумя — бинарное значение - «да» или «нет», которое может быть
представлено одним битом, или несколькими значениями, для хранения
которых достаточно нескольких битов. В программировании для этих целей
обычно отводится целые без знаковые числа. Это может быть короткое (16
бит) или длинное (32 бита) целое число.
Мы выбрали 32-х битовое целое число, хотя заведомо в нашем случае число
состояний каждого из объектов будет меньше. Далее нам следует способ
работы с битовой маской и способ кодирования значений в удобной форме.
30.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
Итак, для хранения каждого состояния общее число битов разделяется на
необходимое число групп, когда в каждой группе число бит в два раза
меньше, чем число состояний, дополненное до четного значения. Например,
в случае, когда нам необходимо хранить информацию о том был ли в
командной строке представлен данный ключ, число значений равно двум:
да или нет. Для хранение этой достаточно одного бита. Обычно, значение
«да», т. е. «правда» или «true», кодируется единицей, значение «нет», т. е.
«ложь» или «false», нулем.
Удобным способом записи значения является любая система счисления на
основе степени 2. Для определения, скажем места в целом слове полезно
слово разбить на байты и использовать шестнадцатеричную систему
счисления. Можно использовать восьмеричную систему. Но такая форма
кодировки не полностью заполняет все биты целого числа, как 16-битового,
так и 32-битового. В языке C/C++ для шестнадцатеричной системы
используется запись в виде: 0x12345678, т. е. по две шестнадцатеричной
цифре в каждом байте.
31.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
Для задания значения одного или нескольких битов следует применять не
арифметические, а «маскирующие» операции. К таким операциям относятся
И, ИЛИ, исключающее ИЛИ и НЕТ:
И
ИЛИ
(AND)
(OR)
0
1
0
0
0
1
0
1
исключающее ИЛИ
(XOR)
0
1
0
0
1
1
1
1
0
1
0
0
1
1
1
0
Логические операции в языке C/C++ кодируются символами '&','|', '^'.
Операция НЕТ ('~') просто заменяет нули единицами и наоборот.
Для того, чтобы в каком-то бите числа была записана единица необходимо
выполнить операцию присваивания, если другие биты остаются нулями:
int mask = 0x00000008;
32.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
Очевидно это была продемонстрирована операция начального
присваивания значения. Если присвоено должно быть другое значение,
необходимо в представить его в шестнадцатеричной форме.
Если число уже содержит значение, то для изменения некоторых битов,
например второго бита во втором байте, необходима операция '|':
mask = mask | 0x00000200;
Для проверки установлен бит или нет используется операция '&':
(mask & 0x0000200)
Для сброса ранее установленного бита нужна операция:
mask = mask & (~0x00000200);
Студентам предлагается самостоятельно проверить правильность выполнения
операции. Операция должна очистить бит (сделать его нулем) вне зависимости от его
первоначального значения.
33.
Основы АлгоритмикиТема VIII — Библиотеки функций
2. Передача параметров в командной строке
Кодирование битовых значений, как, впрочем, и любых других, нельзя
назвать удобным. Поэтому их лучше определять через операцию:
#define 'имя' 'шестнадцатеричное значение'
где 'имя' — любое допустимое в C/C++ наименование переменной (и добавим
констант), а 'шестнадцатеричное значение' это представление «true» для
одного из значений ключа. Например, приведенные выше значения
0x00000080 можно зарезервировать за тем, что ключ был задан в командной
строке, а 0x0000200 за значением задано значение в командной строке. В
этом случае код определений констант будет выглядеть так:
#define KEY_IN_CMD 0x00000080
#define VAL_IN_CMD 0x00000200
Имена переменных и констант могут выбираться произвольно; в структуре
cmd_item для элемента mask указываются не битовые значения, а
наименования констант. Указанные маскирующие операции применимы и к
константам.
34.
Основы АлгоритмикиТема Тема
VII - Алгоритм
VIII — Библиотеки
построения
функций
программ
2. Передача параметров в командной строке
СПАСИБО
ЗА ВНИМАНИЕ
ПРОШУ ЗАДАВАТЬ ВОПРОСЫ