|
Программирование >> Структура ядра и системные вызовы
struct Stat *statp = new stat; if (statp) (void)memset( (void*)statp, NULL, sizeof ( struct stat ) ); Функция bzero в BSD UNIX инициализирует всю область памяти NULL-символами. Эта функция может быть реализована через функцию memset следующим образом: void bzero ( char *memp, int len ) (void)memset( memp, NULL, (size t)len ); Функция memcmp сравнивает первые len байтов из двух областей памяти, на которые указывают аргументы meml и тет2. Эта функция возвращает ноль, если первые len байтов этих областей памяти идентичны, положительное значение - если область meml содержит символы, которые лексикографически больше символов в тет2, отрицательное значение - если область meml содержит символы, которые лексикографически меньше символов в тет2. Приведенные ниже операторы проверяют равенство двух переменных типа struct stat. int cmpstat ( sttudt stat* Statpl, struct stat* statp2 ) return memcmp((void*)statpl, (void*)statp2, sizeof(struct stat)); Функция strcmp может быть реализована с помощью функции memcmp следующим образом: int my strcmp (const char* strl, corti№char* str2 ) ( . -m-- .:,int lenl = strlen ( strl ), len2 r.-Strlen ( str2 ); ,y if ( lenl > len2 ) lenl = len2; , : ..return memcmp ( (void*)strl, (void*)str2, lenl ); Более того, в BSD UNIX функция bcmp тоже может быть реализована через функцию memcmp: #define bcmp ( si, s2, n ) memcmp( (void*)si, (void*)s2, (size t)n) Функция тетеру копирует первые len байтов данных из области памяти, на которую указывает src, в область памяти, на которую указывает dest. Эта функция возвращает адрес области памяти dest. Функция Ьсору в операционной системе BSD UNIX может быть также реализована с помошью функции тетеру: ♦define Ьсору(src, dest, n) memcpy((void*)dest, (void*)src, (size t)n) Заметим, что функции bcopy, bcmp и bzero не определены в стандарте ANSI С, но они широко используются в UNIX-rq)orpaMMax. Функция тетеру может быть использована для реализации функции strcpy: ♦define strcpy( dest, src ) \ memccpy( (void*)dest, (void*)src, \0, (size t)strlen( src ) ) Функция memccpy копирует данные из области памяти, на которую указывает аргумент src, в область памяти, на которую указывает аргумент dest. Функция либо копирует данные до первого появления символа, указанного в аргументе ch (включая и этот символ), либо копирует первые len байтов. Функция тетссру может быть использована для реализации функции strncpy: ♦define strncpy( dest, src, n ) \ memccpy( (void*)dest, (void*)src, \0, (size t)n ) Функция memchr производит поиск в первых len байтах области памяти, на которую указывает аргумент тетр, и возвращает адрес первого экземпляра символа ch в этой области или NULL, если ch не найден. Функция memchr может быть использована для реализации функции strchr. ♦define strchr( str,ch ) memchr( (void*)str, ch, (size t)strlen( str )) 4.5. <malloc.h> в заголовке <malloc.h> объявляется набор функций, предназначенных для динамического распределения и осюбождения памяти. Программисты, работающие на С++, редко используют эти функции, применяя вместо них операторы neww delete, выполняющие те же действия. Тем не менее функция realloc, объявленная в заголовке <malloc.h>, может быть использована для динамического регулирования объема памяти, а оператор new в С++ такой возможности не предоставляет. Использование функции realloc подробно описывается нрже. В заголовке файла <malloc.h> объявляются такие функции: void* malloc (const size t size ); void* calloc (const size t num record, const size t size per record ); void Л-ее (void* memp ); void* realloc (void* old memp, const slze t new size ); Пользователи уже должны быть знакомы с тем, как применяются функции malloc, calloc и free. В частности, оба следующих оператора вьщеляют динамическую память объемом 1048 байтов: char* meml = (char*)malloc( 1048 ) ); стиль С char* nem2 = new char [ 1048 ]; стиль С++ функция calloc подобна функции malloc, за исключением того, что она гарантирует инициализацию каждого элемента вьщеленной памяти значением 0. Функция free, как и оператор delete, используется для освобождения динамической памяти. Представленный ниже оператор освобождает динамическую память, на которую указывает переменная тетГ. free (meml); Функция realloc используется для регулирования размера динамической памяти, вьщеленной функцией malloc или calloc. Это очень полезно при управлении массивом, который может изменять свой размер в ходе выполнения процесса. Например, программа, сохраняющая данные, которые вводятся пользователем со стандартного ввода, не может знать наперед, сколько строк данных будет получено от пользователя. В такой ситуации с помощью функции realloc можно обеспечить динамическое выделение именно того объема памяти, который нужен для хранения вводимых пользователем данных в каждый текущий момент времени. Заметим, что в рассматриваемом случае для сохранения пользовательских входных данных можно применять связный список или массив фиксированного размера. По сравнению с массивом (статическим или размещаемым динамически) связный список имеет некоторые недостатки. Поскольку каждая запись связного списка требует памяти для следующего указателя, то он занимает больший объем памяти, чем массив, при том же количестве элементов. Более того, создание и обработка связных списков, как правило, требует больше времени, чем выборка данных из массивов. Недостатком массива фиксированного размера в сравнении с массивом, размещаемым динамически, является то, что он требует предварительного выделения всей памяти для сохранения максимально возможного количества входных данных - следовательно, он менее эффективен в использовании памяти, чем динамически размещаемые массивы. Кроме того, при использовании массива фиксированного размера устанавливается ограничение на максимально возможное количество входных данных, что может оказаться весьма нежелательным для пользователей. При использовании динамически размещаемого массива подобные ограничения не возникают. То есть динамически размещаемый массив оказывается более предпочтительным, чем связный список, в тех случаях, когда доступ к хранимым данным производится часто и порядок их не меняется. Кроме того, динамически размещаемый массив предпочтительнее статического еще и потому, что его размер может изменяться (уменьшаться или увеличиваться) со временем, а задание верхнего предела размера оказывается непрактичным. Функция realloc принимает два аргумента. Первый аргумент, old memp, содержит адрес предварительно вьщеленной области динамической памяти, второй, new size - размер новой области динамической памяти в байтах. Значение ne\v size может быть больше или меньше размера старой области памяти, обозначенной аргументом old memp. Функция realloc пытается отрегулировать размер старой области динамической памяти под new size. Если это не получается, то выделяется новая область динамической памяти new size. Затем функция копирует максимально возможный объем данных из старой области памяти в новую, и старая область памяти освобождается. Если размер новой области памяти больше размера старой, то содержимое памяти в новой области, не инициализированное данными старой памяти, не определяется. в приведенной ниже программе malloc. С показано использование функции realloc для сохранения пользовательских входных данных, поступающих со стандартного ввода: ♦include <iostream.h> ♦include <string.h> ♦ include <maHoc.h> ♦ include <maHoc.h> int mainO char** inList = 0, buf [256];. int numin = 0, max size = 0; /* получить от пользователя все входные строки */ while (cin. getline (buf, sizeof (buf))) { , if ( ++numln > max si2e ){ * max size += 2; if ( !inList ) . . inList = (char**),calloc (max size, sizeof (char*) ) ; else inList (char**! realloc (inUst, sizeof (char*) *max size); } ~ /* сохранить входную строку */ inList[numIn-l} = (char*)malloc( strlen( buf )+1 ); strcpy( inList[numIn-1], buf ); /* напечатать все входные строки пользователя */ while ( -numIn >= 0; ){ cout numIn : inList[numIn] endl; free( inList[numIn) ); free ( inList ); return 0; Эта программа читает строки со стандартного ввода. По мере того как программа считывает каждую строку, строка сохраняется в массиве inList. Размер массива wLw/регулируется динамически на основании фактического числа прочитанных входных строк. Переменные maxjsize и numIn содержат соответственно текущий размер массива inList и число фактически прочитанных входных строк. Если значение numIn совпадает с max size и читается новая входная строка, то значение max size увеличивается на два, а размер массива inList увеличивается на два элемента путем вызова функции realloc. После того как будут прочитаны все входные строки и в стандартном входном потоке встретится признак конца файла, программа пошлет все сохраненные строки на стандартный вывод в порядке, обратном порядку чтения, и по пути освободит всю динамическую память. Отметим, что в этом примере первое выделение памяти массиву inList производится через вызов calloc. Это объясняется тем, что если попытаться вьшелить динамическую память с помощью функции realloc, т.е. таким образом: char* memp = (char*)realloc( О, new size ) TO в некоторых UNIX-системах будет вьщано сообщение об ошибке, связанной с сегментацией (например, в Sun OS 4.1.x), тогда как в других системах функция realloc будет работать. Следовательно, для обеспечения переносимости программ необходимо избегать присваивания значения NULL первому аргументу при любом вызове realloc. Наконец, динамическая память, выделенная вызовами malloc, calloc и realloc должна освобождаться только функцией free, а память, выделенная оператором new,- только оператором delete. 4.6. <time.h> в заголовке <time.h> объявляется набор функций, предназначенных для вызова системных параметров времени. Они могут применяться для определения местного времени и даты, времени и даты в универсальном формате (UTC), а также статистических данных об использовании процессами времени центрального процессора. В заголовке <time.h> объявляются функции:
Функция time возвращает количество секунд, прошедших со дня официального рождения ОС UNIX - 1 января 1970 года. Результат типа timej хранится в возвращаемом значении функции и по адресу timv, если он не равен NULL. Функция ctime возвращает значения местного времени и даты в следующем формате: Sun Sept. 16 01:03:52 1997\n Функция ctime почти всегда используется с функцией time дня получения значений местного времени и даты: time t timv = time ( О ) ; cout << local time: << ctime( stimv ) Функции localtime и gmtime получают адрес переменной типа time t и возвращают адрес записи типа struct tm, предназначенной только для чтения. Принимаемый аргумент типа timet должен быть установлен предьщущим вызовом функции time, и возвращаемая запись типа struct tm содержит информацию о времени и дате соответственно по местному времени и в формате иТС. Запись типа struct tm может быть передана в функцию asctime для получения символьной строки в том же формате, что и у возвращаемого значения ctime. Тип данных struct tm определен в заголовке <time.h>. Приведенные ниже операторы иллюстрируют использование этих функций: finclude <time.h> time t timv = time( 0 ); struct tm *local tm = localtime( stimv ); struct tm *gm tm = gmtime( Stimv ); cout local time stamp: asctime(local tm ); cout UTC time stamp: asctime( gm tm ); Следующая функция воадращает значение, соотаетствующее моменту времени, отстоящему от текущего на указанное количество часов: const char* time stamp(long offset hours ) ( time t timv = time( 0 ); получить текущее время timv offset hours * 60 * 60; преобразовать смещение в секунды return ctime ( stimv ); вернуть новое значение времени Функция mktime противоположна функциям localtime и gmtime. Она получает адрес записи типа struct tm и возвращает для нее значение типа timet. Кроме того, функция mktime нормализует выходные данные, приводя их к общепринятому виду для любой произвольной даты в формате UTC (начиная с 00:00:00 1 января 1970 года по 03:14:07 UTC 19 января 2038 года включительно). Покажем программу, с помощью которой можно вычислить, на какой день недели приходрггся 5 апреля 1999 года: finclude <iostream.h> finclude <time.h> static struct tm time str; main 0 { time t tmv; time str.tm year = 1999 - 1900; год = 1999 time str.tm mon =4 - 1; time str.tm mday = 5; инициализировать все поля в О месяц = April день = 5
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |