Структуры. Битовые поля в структурах. 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Структуры. Битовые поля в структурах.



Язык С допускает использование в структурах особого типа полей так называемых битовых полей. Поле битов – это группа соседних (двоичных) разрядов (бит), расположенных в области памяти переменной целого типа. Использование данных полей делает возможным доступ к отдельным битам более крупных объектов, например, байтов или слов. Целесообразно использование полей бит в том случае, когда для хранения информации в структуре данных достаточно несколько бит.

Общий синтаксис описания битового поля:

тип [имя]: ширина;

Поле Тип: в С для определения битового поля разрешено использовать любой тип, интерпретируемый как целый: char, short, int, long (с модификаторами signed, unsigned), перечисления.

Поле Ширина: каждому полю выделяется столько бит, сколько указано в поле ширина. Данное выражение должно иметь неотрицательное целое значение.

Поле Имя: ссылка на битовое поле выполняется по имени. Если имя в данном поле не указано, то запрошенное количество бит будет отведено, но доступ к ним будет невозможен.

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

 

struct имя_структуры

{ тип [имя1]: ширина;

тип [имя2]: ширина;

тип [имяN]: ширина;

};

 

Пример объявления шаблона и определения переменных:

 

struct bitfld

{ signed a:1;

unsigned b:2;

int:4;

int c:4;

int:0;

} bt1, bt2;

 

Объединения.

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

Итак, ссылаться в данный момент времени можно только на один элемент и, соответственно, только на один тип данных. Задача программиста – обеспечить, чтобы на данные, хранящиеся в объединении, ссылались, как на данные соответствующего типа.

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

Перечисления.

Перечисление — это набор именованных целых констант. Перечисления довольно часто встречаются в повседневной жизни. Вот, например, перечисление, в котором приведены названия монет, используемых в Соединенных Штатах:

penny (пенни, монета в один цент), nickel (никель, монета в пять центов), dime (монета в 10 центов), quarter (25 центов, четверть доллара), half-dollar (полдоллара), dollar (доллар)

Перечисления определяются во многом так же, как и структуры; началом объявления перечислимого типа служит ключевое слово enum. Перечисление в общем виде выглядит так:

enum тег { список перечисления } список переменных;

Здесь тег и список переменных не являются обязательными. (Но хотя бы что-то одно из них должно присутствовать.) Следующий фрагмент кода определяет перечисление с именем coin (монета):

enum coin { penny, nickel, dime, quarter, half_dollar, dollar};

Тег перечисления можно использовать для объявления переменных данного перечислимого типа. Вот код, в котором money (деньги) объявляется в качестве переменной типа coin:

enum coin money;

С учетом этих объявлений совершенно верными являются следующие операторы:

money = dime;if(money==quarter) printf("Денег всего четверть доллара.\n");

Главное, что нужно знать для понимания перечислений — каждый их элемент представляет целое число. В таком виде элементы перечислений можно применять везде, где используются целые числа. Каждому элементу дается значение, на единицу большее, чем у его предшественника. Первый элемент перечисления имеет значение 0. Поэтому, при выполнении кода

printf("%d %d", penny, dime);

на экран будет выведено 0 2.

Работа с файлами. Потоки. Буфер.

Файл.

Файл – это именованная совокупность данных, хранящаяся на каком-либо носителе (дискета, винчестер, CD), и имеющая определённые атрибуты.

1) Текстовые файлы.

2) Бинарные файлы.

Т.ф. рассматриваются как строки, состоящие из непробельных символов, разделённых пробельными символами. Каждая строка заканчивается символом конца строки.

Пробельные символы:

- пробел

\n

\t

\v

\f

\r

Потоки

Абстрактный канал связи, который создаётся в программе для обмена данными с реальными физическим устройством(файлом).

Поток создаётся в момент открытия файла.

Некоторые потоки создаются автоматически.

По направлению передачи, потоки бывают

1)входной(input)

2)выходной(output)

3) двунаправленный(i/o)

По способу создания:

1) Автоматически создаваемые потоки, которые связаны со стандартными системными устройствами в\в.

Stdin, stdout, stderr, printf, scanf

2) явно создаваемые потоки (для обмена данными с файлом)

3) явно создаваемые потоки для обмена данными со строкой в RAM.

Буфер

При работе с потоками различают буферизированный и небуферизированный в/в.

Buffer – область оперативной памяти, которую используют средства в/в для промежуточного хранения данных, передаваемых между программой и устройством. Системный и программный буфер.

Библиотека stdio. Связь с файлами. Открытие и закрытие файла.

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

Возвращаемое функцией значение нужно сохранить и использовать для ссылки на открытый файл. Если произошла ошибка при открытии файла, то возвращается NULL.

Функция открытия файла fopen() содержит два параметра, оба являются строковыми литералами:

FILE * fopen(char *filename, char *mode);

Первый задает физическое местонахождение (путь) и имя открываемого файла, а второй – тип доступа к файлу (режим открытия файла), который может принимать следующие значения:

 

“r” Открыть файл для чтения.
“w” Открыть файл для записи. Если файл существует, то его содержимое теряется.
“a” Открыть файл для записи в конец файла. Если файл не существует, то он создается.
“r+” Открыть файл для чтения и записи. Файл должен существовать.
“w+” Открыть файл для чтения и записи. Если файл существует, то его содержимое теряется.
“a+” Открыть файл для чтения и записи в конец файла. Если файл не существует, то он создается.

 

К комбинациям вышеперечисленным литералов могут быть добавлены также “t” и “b”.

“t” – открыть файл в текстовом режиме.

“b” – открыть файл в бинарном (двоичном) режиме.

Библиотека stdio. Текстовые файлы – чтение и запись.

Чтение и запись в файл последовательного доступа

Данные хранятся в файлах для того, чтобы их можно было в случае необходимости извлечь и обработать. Для работы с файлами в библиотеке языка С содержится множество функций. Рассмотрим самые распространенные: fprintf(), fscanf(), fgets(), fputs(). Формат параметров этих функций очень похож на формат функций printf(), scanf(), gets(), puts(). Схожи не только параметры, но и действия. Отличие состоит лишь в том, что printf() и другие работают по умолчанию с консолью (экран, клавиатуры), а fprintf(), fscanf(),fgets(), fputs() – с файлами (в том числе и со стандартными потоками stdin – стандартный поток ввода, stdout – стандартный поток вывода), поэтому у них добавлен параметр, являющийся указателем на структуру FILE.

Итак fprintf() – это функция форматированного вывода из файла, а fscanf() – функция форматированного ввода в файл.

int fprintf(FILE *f, const char форматированная_строка, …);

int fscanf(FILE *f, const char форматированная_строка, …);

Пример:

#include<stdio.h>

void main()

{ int a;

FILE *f;

if(!(f= fopen(“readme.txt”, “r+t”)))

{ printf(“Невозможно открыть файл”);

return; }

for(a=0;a<100;a+=3)

fprintf(f, “%d”,a);

fcloce(f);

}

int fputs(char *string, FILE *f);

Функция fseek()

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

int fseek(FILE *f, long int offset, int whence);

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

SEEK_SET – смещение (поиск) выполняется от начала файла.

SEEK_CUR – смещение выполняется от текущей позиции указателя.

SEEK_END – смещение выполняется от конца файла.

Эти символические константы (макроопределения) определены как целочисленные значения. Константе SEEK_SET соответствует 0, SEEK_CUR – 1, SEEK_END -2.

Величина смещения может быть как положительной, так и отрицательной, но нельзя сместиться за пределы файла.



Поделиться:


Последнее изменение этой страницы: 2016-04-08; просмотров: 420; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.223.32.230 (0.022 с.)