- •Структура программы на языке Си. Этапы выполнения программы
- •1.1. Алфавит языка Си
- •1.2. Лексемы
- •1.3. Идентификаторы и ключевые слова
- •1.4. Знаки операций
- •1.5. Литералы (константы)
- •1.6. Комментарии
- •1.7. Общая структура программы на языке Си.
- •1.8. Функциональная и модульная декомпозиции
- •1.9. Этапы обработки программы.
- •1.10. Роль препроцессора.
- •1.11. Ошибки
- •2. Переменные и константы. Типы данных
- •2.1. Основные типы данных
- •2.2. Декларация (объявление) объектов
- •2.3. Константы в программах
- •2.4. Целочисленные константы
- •2.5. Константы вещественного типа
- •2.6. Символьные константы
- •2.7. Строковые константы
- •3. Обзор операций
- •3.1. Операции, выражения
- •3.2. Арифметические операции
- •3.3. Операции сравнения
- •3.4. Логические операции
- •4. Операции (продолжение).
- •4.1. Операция присваивания
- •Примеры недопустимых выражений:
- •4.2. Сокращенная запись операции присваивания
- •4.3. Преобразование типов операндов бинарных операций
- •4.4. Преобразование типов при присваивании.
- •4.5. Операция явного приведения типа
- •4.6. Операция «,» (запятая)
- •5. Стандартная библиотека языка Си
- •5.1. Стандартные математические функции
- •5.2. Потоковый ввод-вывод
- •5.3. Консольные функции вывода данных на экран
- •5.4. Консольные функции ввода информации
- •5.5. Ввод-вывод в оконных приложениях.
- •Советы по программированию
- •6. Операторы языка с.
- •7. Составление разветвляющихся алгоритмов
- •7.1. Условные операторы
- •If (выражение) оператор;
- •If (выражение) оператор 1 ;
- •If (выражение 1) оператор 1;
- •If (выражение 2) оператор 2;
- •If (выражение 3) оператор 3;
- •7.2. Оператор выбора альтернатив (переключатель)
- •7.3. Условная операция «? :»
- •8. Составление циклических алгоритмов
- •8.1. Оператор с предусловием while
- •8.2. Оператор цикла с постусловием do – while
- •8.3. Оператор цикла с предусловием и коррекцией for
- •8.4. Вложенные циклы.
- •9. Операторы передачи управления.
- •9.1. Оператор безусловного перехода goto
- •9.2. Операторы continue, break и return
- •10. Массивы
- •10.1. Одномерные массивы
- •10.2. Примеры алгоритмов, использующих одномерные массивы.
- •10.3. Многомерные массивы
- •10.4. Примеры алгоритмов, использующих двумерные массивы.
- •10.5. Компонента StringGrid
- •11. Размещение данных и программ в памяти пэвм
- •11.1. Общие понятия.
- •11.2. Кодирование целых чисел.
- •11.3. Кодирование вещественных чисел.
- •11.4. Кодирование символов.
- •Примеры кодов символов:
- •Стандартная часть таблицы символов (ascii)
- •Дополнительная часть таблицы символов
- •11.5. Операция sizeof
- •11.6. Побитовые логические операции. Операции над битами
- •11.7. Кодирование программы.
- •11.8. Регистры
- •12.1. Строки как нуль-терминированные массивы char.
- •12.2. Русификация консольных приложений.
- •12.3. Строки как переменные типа AnsiString.
- •12.4. Преобразования строковых типов.
- •12.5. Тип String в консольных приложениях.
- •13. Функции пользователя и классы памяти.
- •13.1. Сущность и предназначение функций.
- •13.2. Определение и вызов функции.
- •13.3. Прототип функции.
- •13.4. Область видимости.
- •13.5. Классы памяти объектов в языке Cи.
- •13.6. Разбиение программы на модули.
- •14. Структуры и объединения
- •14.1. Понятие структуры
- •14.2. Декларация структурного типа данных
- •14.3. Объявление структурных переменных
- •14.4. Обращение к полям структуры
- •14.5. Операции со структурой как единым целым
- •14.6. Вложенные структуры
- •14.7. Массивы структур
- •14.8. Размещение структурных переменных в памяти
- •14.9. Битовые поля
- •14.10. Объединения
- •15. Генерация псевдослучайных чисел.
- •16. Файлы в языке с
- •16.1. Типы файлов.
- •16.2. Открытие файла
- •16.3. Закрытие файла
- •16.4. Запись - чтение информации
- •А) Посимвольный ввод-вывод
- •Б) Построчный и форматированный ввод-вывод
- •В) Блоковый ввод-вывод
- •Int fflush(file *stream);
- •16.5. Текстовые файлы
- •16.6. Перенаправление стандартного ввода-вывода
- •16.7. Бинарные файлы
- •16.8. Дополнительные полезные функции
- •16.9. Простейший пример создания собственной базы данных
- •17. Указатели
- •17.1. Определение указателей
- •17.2. Связь указателей и массивов.
- •17.3. Операции над указателями (косвенная адресация)
- •17.4. Операции над указателями (косвенная адресация)
- •17.5. Массивы указателей.
- •17.6. Указатели на указатели.
- •17.7 . Указатели как параметры функций.
- •Void f1(int, const double *);
- •17.8 . Указатели на структуры
- •17.9. Ссылка
- •17.10. Указатели на функции
- •Id_функции(список аргументов);
- •18. Работа с динамической памятью
- •18.1. Динамическое выделение и освобождение памяти.
- •18.2. Создание одномерного динамического массива.
- •18.3. Создание двуxмерного динамического массива.
- •19. Операция typedef
- •20. Отладка и пошаговое выполнение программы
В) Блоковый ввод-вывод
Функции блокового ввода-вывода читают из файла или записывают в файл заданное число байт без их преобразования. Другими словами, они способны записать в файл любую переменную или массив в том же двоичном представлении, в каком они хранятся в машинной памяти; а впоследствии таким же образом прочесть их оттуда. Поэтому они являются самым удобным средством сохранения на диск данных программы для их последующего прочтения этой же программой.
Недостатком подобного способа сохранения является то, что полученный файл не будет иметь текстовый формат, и читать из него данные в правильном виде способна лишь программа, «знающая» порядок и типы хранения в нем данных. Тем не менее, если хранимые данные содержат символы (тип char), то они обычно будут видны при просмотре «Блокнотом», часто вперемежку со специальными символами.
Блоковый ввод-вывод осуществляется следующими функциями:
int fread (void *p, int size, int n, FILE *f) |
- считывает n блоков по size байт каждый из файла f в область памяти с адресом p (необходимо заранее отвести память под считываемый блок); |
int fwrite (void *p, int size, int n, FILE *f) |
- записывает n блоков по size байт каждый из области памяти с адресом p в файл f.
|
В функциях блокового ввода-вывода количество байт задается несколько сложным образом: вводится термин «блок». Это – совершенно условная единица, под которой понимается любое заданное конкретное число байт. Программист должен указать как «размер блока», так и «число блоков»; реальное количество байт будет их произведением. Такой формат удобен при чтении/записи массива как целого.
Результатом этих функций является количество успешно прочтенных/записанных блоков. Оно равно n, либо меньше (при невозможности прочесть/записать n блоков). Неравенство результата значению n является признаком либо сбоя, либо достижения конца файла.
Например, если в файле хранится массив целых чисел, и его размер неизвестен (известно лишь, что он не превосходит 10000), то и весь массив, и его длину можно прочесть одной командой:
int a[10000],n;
n=fread(a, sizeof(int), 10000, f);
Здесь мы пытаемся прочесть в массив 10000 «блоков», где каждый блок – одно число типа int; реально будет прочтено столько чисел, сколько есть в файле, и это количество присвоено n.
Замечание. Функции блокового ввода-вывода трудно применить к переменной типа String, т.к. в типе String (см. тему «Строки») текст хранится отдельно от самой переменной, представляющей собой лишь указатель на этот текст. Если необходимо выполнить блоковый ввод-вывод структуры, содержащей текст, рекомендуется поэтому ее текстовые поля объявлять не как String, а как массив char.
г) Проверка достижения конца файла
Вместо вышеописанных способов определения «невозможности дальнейшего чтения», для проверки достижения конца файла можно пользоваться функцией feof() :
int feof(FILE *f) ;
Она возвращает ненулевое значение, если до этого была совершена неудачная попытка чтения за концом файла. Таким образом, если feof() не равно нулю, то достигнут конец файла, и при этом последнее прочтенное из файла значение является ложным и должно быть проигнорировано.
Можно также использовать описанную ниже функцию filelength().
д) Сброс буфера файла
Заметим, что если после записи данных файл не был закрыт, часть «записанных» данных может не сохраниться. Это связано с тем, что данные вначале записываются в буфер файла, и лишь после его заполнения, либо закрытия файла – на диск. Если нужно, не закрывая файл, тем не менее гарантировать, что все операции ввода-вывода физически исполнены, можно вызвать функцию «сброса буфера» файла fflush() :