5.1 Типы доступа

В следующих параграфах автор определяет 2 основных типа доступа для файлов в Cи:

1)      Последовательные файлы использовались на заре развития компьютерной техники, так как запись на перфоленту или магнитную ленту могла вестись только последовательно.

2)      Файлы с произвольным доступом. С появлением жестких дисков, которые позволяют обращаться к любым участкам памяти в любое время, появились файлы с произвольным доступом.

В последовательных файлах позиционирование компонентов производится неявно и не подчиняется влиянию программы. В файлах с произвольным доступом операции считывания и записи дополняются указанием индекса компонентов. При этом индекс компонентов отсчитывается, как правило, от 1. Вместе с тем файл с произвольным доступом обладает сходством с типом данных "массив".

Доступ к различным периферийным устройствам в C осуществляется с помощью указателей. При этом файл должен открываться до начала доступа и закрываться после. Для выполнения этих функций используется стандартный файл C-библиотеки <stdio.h>.

Что касается самого распространенного типа файлов – текстовых, то в C они представляют собой файлы, компоненты которых буквы, т.е. символы типа char. Все тексты мы разделяем на строки, и здесь встает проблема: как определить конец строки, когда реализация текстовых файлов во всех программах разная?

В Си используется, так называемый, буферный вывод. Это значит, что выводится только тогда, если конец строки посылается устройству вывода, или выводится совсем, если программа завершает свои действия.

Здесь используют следующие функции языка C:

·           int putc(int c, FILE *f) - записывает символы в текстовые файлы.

·           int getc(FILE *f) – читает символы из файла.

·           int puts(const char *s) – записывает последовательность символов в файл.

·           char *gets(char *s) – чтение последовательности из файла.

При бинарном вводе и выводе данные представлены в допустимой форме, а внутреннее изображение в памяти перенесет (побайтово) данные в файл. Например, для бинарной записи переменных величин long нужно 4 байт памяти. Необходимое количество памяти зависит от величины числа и соответственно от его формата.

Функция fwrite записывает указанное количество элементов данных равной величины в файл. Здесь должны передаваться:

·   Адрес первого элемента данных.

·   Величина отдельного элемента данных.

·   Количество записываемых элементов данных

·   Выходной файл

Затем автор рассказывает, как получить доступ к отдельным наборам данных файла с произвольным доступом. Для этого в C используются следующие команды:

int fseek(FILE *f, long offset, int origin)

Эта функция ставит указатель на определенную позицию в пределах файла. Функция позиционирует смещение (offset), которое считается в байтах. Значение origin устанавливается в соответствии со смещением (SEEK_SET oder 0 – смещение из начала файла, SEEK_END oder 1 – смещение из текущей позиции, SEEK_CUR oder 2 – смещение из конца файла)

Функция long ftell (FILE *f) указывает текущую позицию в файле, на которой находится указатель файла. В случае ошибки ftell принимает значение -1.

Функция void rewind (FILE *f) перемещает указатель на начало файла и удаляет значение ошибки.

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


6. Указатель

В этой главе автор рассказывает об одном из важнейших понятий программирования в C – указателях.

6.1 Основы указателя

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

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

·   при передаче параметра

·   при обработке массивов

·   для обработки текста

·   для доступа к специальным ячейкам памяти

Обозначаются указатели следующим образом: int *pc; , т.е. переменная pc является указателем тип int.

При этом используют преимущественно два типа указателей:

1.         Оператор адреса &, который применяется к объекту, доставляющему адрес этого объекта. Например, pc=&c.

2.         Смысловой оператор *, который применяет указатель к объекту, находящемуся в этой ячейке. Например, c=*pc; *pc=5;

Особенно важным является то, что * и & имеют более высокий приоритет, чем арифметические операторы. При этом если используются несколько операторов указателя последовательно, то выражение обрабатывается справа налево.

Аргументы указателя обладают возможностью обращаться к объектам функции из другой функции и изменять их.

Автор также показывает, что с указателями можно проводить определенные арифметические операции и операции сравнения. Разрешены, конечно, только такие операции, которые ведут к осмысленным результатам. К указателям могут целочисленные значения прибавляться и вычитаться из них. К указателям могут также применять декремент.

Можно указатели посредством операторов >,> =, <, <=, != и == сравнивать друг с другом. Всевозможные арифметические и логические операции, не описанные выше, не разрешены с указателями.

6.2 Указатель и массив

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

Присваивание pa = *a [0] показывает, что pa указывает на 0-ой элемент массива a, т.е. pa содержит адрес a [0]. Вместо этого можно записать следующее: pa = a;

К отдельным элементам массива можно обращаться 3 различными способами:

·           a [i] - i-ый элемент массива

·           * (pa+i) - указатель pa + i * (длина элементов массива a)

·           * (a+i) начало массива + i * (длина элементов a)

Таким образом, каждое значение индекса массива может определяться также как значение смещения указателя и наоборот. Выражение pa + i не значит, что к pa значение i прибавляется, а i устанавливает смещение объекта от pa.

Многомерные массивы можно задавать через указатели следующим образом:

Matrix[1][2]=*(Matrix[1]+2)

Matrix[1][2]=*(*(Matrix+1)+2)

Matrix[1][2]=*(*Matrix+1*M+2)

Так называемые структурные указатели имеют несколько другое обозначение:

Указатель на структурную переменную -> название элемента

Например, punkt.px соответствует (*punkt)-> px

Так как структура указателей и массивов очень похожа, то далее автор объясняет как составить массив указателей.

Массив указателей - это массив, состоящий из элементов-указателей. Вектор указателей определяется следующим образом:

Тип исходных данных *Имя вектора[]

Эту запись необходимо отличать от указателя на вектор:

(*Имя вектора) []

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

Например, char *Z[3], где происходит определение массива с 3 элементами, которые являются соответственно указателями типа char. При этом Z является указателем на массив с 3 указателями char.

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

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

Указатель на функцию в C записывается следующим образом:

Тип возврата (*Имя функции) (Аргументы функции)

Здесь необходимо обратить особое внимание на то, что имя функции стоит в скобках. Если мы запишем без скобок *Имя функции (), то функция будет возвращать значение указателя.

Функциональные указатели можно использовать в следующих случаях:

·   Как переменную-указатель, которая на функцию указывает.

·   Распределять значения функциональных указателей.

·   Определять массивы функциональных указателей.

·   Передавать указатель на функцию как параметр.

·   Получать указатель на функцию как возвращенное значение.

Таким образом, профессор обращает также особенное внимание на широкое использование указателей при программировании в С. Это, в общем-то, оправданно довольно высоким быстродействием программ с указателями, но может привести к дополнительным ошибкам программирования из-за трудностей восприятия указателей.



Информация о работе «Алгоритмы и структуры данных. Программирование в Cи»
Раздел: Информатика, программирование
Количество знаков с пробелами: 61871
Количество таблиц: 4
Количество изображений: 0

Похожие работы

Скачать
29246
1
2

... , которая определяет последовательность действий над некоторыми объектами и после конечного числа шагов приводит к по лучению требуемого результата. ЭВМ — исполнитель алгоритмов. Обсуждение методических вопросов изучения темы «Алгоритмы работы с величинами» буде проводить в программистском аспекте. Составление любой программы для ЭВМ начинается с построения алгоритма. Как известно, всякий ...

Скачать
29193
3
0

... профессором Н. Виртом, язык назван в честь французского математика и по замыслу автора предназначался для обучения программированию. Однако язык получился на столько удачным, что стал одним из основных инструментов прикладных и системных программистов при решении задач вычислительного и информационно-логического характера. В 1979 году был подготовлен проект описания языка – Британский стандарт ...

Скачать
17900
0
0

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

Скачать
9572
0
0

... процедуры и функция (программирование) функции макросы * глобальная переменная глобальные переменные * класс программирование классы * Обобщённое программирование шаблоны Обычно стандартная библиотека содержит основные алгоритмы и структуры данных, необходимые для: * работы с динамически распределяемая память динамической памятью * файловыми операциями ввода-вывода * операциями ввода- ...

0 комментариев


Наверх