Лекции.Орг


Поиск:




Категории:

Астрономия
Биология
География
Другие языки
Интернет
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Механика
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Транспорт
Физика
Философия
Финансы
Химия
Экология
Экономика
Электроника

 

 

 

 


Двоичные файлы и процедуры ввода-вывода. Примеры использования.

Ответ:

Бинарный (двоичный) поток:

· Последовательность произвольных байтов

· Не рассчитан на интерпретацию в качестве последовательности текстовых символов;

· Для ввода/вывода данных следует применять функции чтения/записи блоков памяти

Текстовый поток:

· Частный случай бинарного потока (файла);

· Рассматривается как последовательность символов;

· Некоторые служебные символы могут присутствовать в потоке, но не выводиться на экран;

· Для чтения/записи данных необходимо применять функции, аналогичные функциям консольного ввода / вывода (fprintf / fscanf, fputs / fgets, fputc / fgetc)

Двоичный ввод/вывод

При использовании текстового режима работы сфайлами при вводе/выводе данных выполняетсяпреобразование из строки или в строку.

Как результат:

· Потеря точности для вещественных чисел;

· Увеличение размера файла (каждая десятичная цифра в записи числа – отдельный ASCII-код, 8 битов);

· Замедление ввода/вывода

double num = 1./3.;

fprintf(fp, “%f”, num);

// вфайл - строка: “0.333333”

Функции чтения/записи данныхв двоичном виде работают сданными в том же виде, в какомони хранятся в программе.

Удобны для ввода/выводабольших объемов данных(массивов, структур и т.п.)известного размера.

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

 

 

Прототип функции Назначение
int fwrite (const char * array,size_t size,size_t          count, FILE * stream); Записывает блок данных в поток. Таким образомзапишется массив элементов array в текущую позицию впотоке. Для каждого элемента запишется size байт. Индикатор позиции в потоке изменится на число байт,записанных успешно. Возвращаемое значение будет равно count в случаеуспешного завершения записи. В случае ошибкивозвращаемое значение будет меньше count.
int fread(void *ptr,size_t size,size_t count,FILE *stream);   Читает блок данных из потока. Будет прочитано countэлементов размером size каждый. Все они будут записаны впамять, начиная с адреса ptr. Индикатор позиции в потокеизменится на число байт, прочитанных успешно. Возвращаемое значение будет равно count в случаеуспешного завершения записи. В случае ошибкивозвращаемое значение будет меньше count.

do

{

act_read = fread(buffer, sizeof(char), BUF_NUM, fin);

fwrite(buffer, sizeof(char), BUF_NUM, fout);

}

while (act_read == BSIZE);

 

Понятие указателя. Статические и динамические переменные. Функции для работы с динамической памятью. Примеры.

Ответ:

Виды указателей

Переменная-указатель предназначен для хранения адреса памяти

В языке Си различают три вида указателей:

· Указатель на объект.

· Указатель на void.

· Указатель на функцию.

Указатель не является самостоятельным типом, он всегда связан с каким-либо другим конкретным типов.

Понятие указателя

Переменная в программе – это объект, который имеет:

· Имя, которое соответствует адресу того участка памяти, который ей выделен.

· Тип, который соответствует размеру выделенного участка памяти.

· Значение, которое соответствует содержимому этого участка памяти.

· Имя и тип переменной (ее адрес и размер) не может изменяться, а значение – может изменяться.

Указатель – это переменная, которая содержит адрес другой переменной:

Независимо от того, на переменную какого типа (и размера) указывает указатель, размер переменной-указателя всегда постоянный и зависит от используемой модели памяти (как правило – 4 байта).

Причины использования указателей:

· Возможность просто передать адрес участка памяти (переменной) вместо копирования содержимого этого участка памяти (возможно очень большого размера)

· Возможность работы в разных местах программы с одним и тем же фрагментом данных, а не с его отдельными копиями

Объявление указателя

Синтаксис описания переменной-указателя:

тип * имя;

Где:

тип – тип переменной, на которую может указывать указатель;

имя – идентификатор переменной типа указатель, т.е. обычное имя переменной

Рекомендуется при объявлении переменной- указателя использовать префикс или суффикс ptr – это улучшит "читабельность" программы.

int *t;

double *ptr_d;

char *count_Ptr;

int **ptr_P;

К переменным-указателям на объекты можно применять следующие базовые операции (операторы):

· Присваивание (инициализация)

· Разыменование

· Взятие адреса переменной-указателя (адрес адреса)

· Сложение указателя с целочисленным значением

· Инкремент, декремент указателя

· Вычитание из указателя целочисленного значения

· Вычисление разности двух указателей

· Сравнение двух указателей (только для указателей на объекты одинакового типа)

Статические и динамические переменные

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

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

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

Для работы с динамической памятью в языке С используются следующие функции: malloc, calloc, free, realloc.
Рассмотрим их подробнее.

void *malloc(size_t size);

В качестве входного параметра функция принимает размер памяти, которую требуется выделить. Возвращаемым значением является указатель на выделенный в куче участок памяти.
Для выделения памяти под 1 000 000 int`ов необходимо выполнить следующий код:

int * p = malloc(1000000*sizeof(int));
Если ОС не смогла выделить память (например, памяти не хватило), то malloc возвращает 0.
После окончания работы с выделенной динамически памятью нужно освободить ее. Для этой цели используется функция free, которая возвращает память под управление ОС.

void free(void *ptr);

В качестве входного параметра в free нужно передать указатель, значение которого полученно из функции malloc. Вызов free на указателях полученных не из malloc (например, free(p+10)) приведет к неопределенному поведению. Это связанно с тем, что при выделении памяти при помощи malloc в ячейки перед той, на которую указывает возвращаемый функцией указатель операционная система записывает служебную информацию (см. рис.). При вызове free(p+10) информация находящаяся перед ячейкой (p+10) будет трактоваться как служебная.

void *calloc(size_t nmemb, size_t size);

Функция работает аналогично malloc, но отличается синтаксисом (вместо размера выделяемой памяти нужно задать количество элементов и размер одного элемента) и тем, что выделенная память будет обнулена. Например, после выполнения

int * q = (int *) calloc(1000000, sizeof(int))
q будет указывать на начало массива из миллиона int`ов инициализированных нулями.

void *realloc(void *ptr, size_t size);

Функция изменяет размер выделенной памяти (на которую указывает ptr, полученный из вызова malloc, calloc или realloc). Если размер указанный в параметре size больше, чем тот, который был выделен под указатель ptr, то проверяется, есть ли возможность выделить недостающие ячейки памяти подряд с уже выделенными. Если места недостаточно, то выделяется новый участок памяти размером size и данные по указателю ptr копируются в начало нового участка.



<== предыдущая лекция | следующая лекция ==>
Понятие файла. Общие функции для работы с файлами. Примеры. | на безосновательную остановку транспортного средства
Поделиться с друзьями:


Дата добавления: 2018-11-11; Мы поможем в написании ваших работ!; просмотров: 656 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Есть только один способ избежать критики: ничего не делайте, ничего не говорите и будьте никем. © Аристотель
==> читать все изречения...

2268 - | 2218 -


© 2015-2025 lektsii.org - Контакты - Последнее добавление

Ген: 0.014 с.