- •Глава 1 основы программирования
- •Компьютерная программа
- •Языки программирования
- •Компиляторы
- •Расширения имен файлов
- •Интерпретатор
- •Скорость
- •Переносимость
- •Структурирование
- •Библиотеки функций
- •Необходимые пояснения
- •Что такое объектно-ориентированное программирование
- •Что Си может и чего не может
- •Этапы программирования
- •План программы
- •Текст программы
- •Компиляция программы
- •Компоновка программы
- •Тестирование программы
- •Изучение основ программирования
- •Что нужно, чтобы писать программы
- •Вопросы
- •Упражнения
- •Глава 2
- •Структура программы
- •Прописные и строчные символы
- •Инструкция return
- •Использование комментариев
- •Понятие параметров
- •Директива #include
- •Проектирование программы
- •Глава 3 переменные и константы
- •Символьные данные
- •Целочисленные величины
- •Вещественные числа
- •Почему надо использовать целые числа?
- •Константы и переменные
- •Имена констант и переменных
- •Определение констант
- •Почему используют константы?
- •Определение переменных
- •Присваивание значения
- •Определение строковой переменной
- •Типы данных и функции
- •Литералы
- •Проектирование программы
- •Глава 4
- •Функция puts()
- •Функция putchar()
- •Двойственность символьных переменных
- •Управляющие коды
- •Код «новая строка»
- •Код «табуляция»
- •Код «возврат каретки»
- •Код «возврат на шаг»
- •Код «перевод страницы»
- •Отображение специальных символов на экране монитора
- •Многогранная функция printf()
- •Вывод чисел
- •Перевод строки
- •Преобразование типов данных
- •Форматированный вывод
- •Выбор правильных средств вывода информации
- •Проектирование программы
- •Глава 5
- •Функция gets()
- •Функция getchar()
- •«Для продолжения нажмите Enter»
- •Оператор получения адреса &
- •Функция scanf()
- •Входной поток
- •Использование функции scanf()
- •Выбор соответствующих средств ввода данных
- •Будьте осторожны при использовании scanf()
- •Неинициализированные переменные
- •Используемые алгоритмы ввода
- •Глава 6 операторы
- •Арифметические операторы
- •Деление нацело
- •Типы данных и операторы
- •Выражения
- •Приоритет операторов и порядок вычислений
- •Используемые алгоритмы обработки данных
- •Счетчики
- •Операторы инкремента
- •Аккумуляторы
- •Операторы присваивания
- •Присваивание начального значения
- •Проектирование программы
- •Остерегайтесь логических ошибок
- •Ищите образцы
- •Диагностические проблемы
- •Глава 7 для чего нужны функции
- •Как использовать функции
- •Переменные в функциях
- •Автоматические (локальные) переменные
- •Внешние (глобальные) переменные
- •Статические переменные
- •Передача параметров
- •Возвращаемые значения
- •Возврат значений типа float
- •Использование return() в функции main()
- •Использование макроопределений
- •Проектирование программы
- •Автоматические или внешние переменные?
- •Неправильный ввод
- •Глава 8 позвольте компьютеру принимать решения
- •Условия
- •Составные инструкции
- •Конструкция if...Else
- •Дополненный Опросник
- •Логические операторы
- •Вложенные инструкции if
- •Конструкция switch/case/default
- •Проверка чисел с плавающей точкой и строк
- •Проектирование программы
- •Проверка правильности ввода
- •Глава 9 циклы
- •Использование цикла for
- •Создание паузы в программе
- •Составные инструкции
- •Использование переменных
- •Вложенные циклы
- •Использование цикла do...While
- •Вложенные циклы do
- •Использование цикла while
- •Комбинирование циклов разных типов
- •Проектирование программы
- •Использование флагов
- •Использование инструкции break
- •Глава 10 массивы и строки
- •Массивы
- •Определение массива
- •Ввод значений в массив
- •Работа с массивами
- •Просмотр массива
- •Поиск в массиве
- •Передача массива функции
- •Использование массивов
- •Сравнение двух строк
- •Определение длины строки
- •Присваивание строк
- •Слияние строк
- •Массивы строк
- •Проектирование программы
- •Глава 11 структуры и указатели
- •Использование структур
- •Определение структуры
- •Определение структурных переменных
- •Присвоение начального значения
- •Использование структуры
- •Массивы структур
- •Структуры и функции
- •Указатели
- •Указатели и функции
- •Глава 12 вывод на диск и принтер
- •Что такое файловая структура
- •Указатель на файл
- •Как открыть файл
- •Как избежать ошибок выполнения
- •Как закрыть файл
- •Функции ввода и вывода
- •Работа с символами
- •Посимвольное чтение из файла
- •Работа со строками
- •Чтение строк
- •Форматированный ввод и вывод
- •Чтение форматированных файлов
- •Работа со структурами
- •Чтение структур
- •Чтение в массив
- •Дополнение файла новыми данными
- •Текстовый и двоичный форматы
- •Двоичный формат
- •Печать данных
- •Инструкции
- •Проектирование программы
- •Глава 13 как собрать все вместе
- •Прикладная программа
- •Глобальные определения
- •Функция main()
- •Добавление записей: функция addcd()
- •Удаление записи: функция delcd()
- •Редактирование данных: функция chcd()
- •Изменение номера ячейки: функция chloc()
- •Вывод записи на экран: функция locate()
- •Печать записей: функция plist()
- •Сортировка записей: функция sort()
Использование структуры
Член структуры всегда является частью структуры. Нельзя обратиться к структурному элементу как к таковому. Например, если вы попытаетесь присвоить значение члену cost структуры CD, используя следующий синтаксис
cost = 23.13;
компилятор сгенерирует ошибку, вызванную тем, что переменная cost не была определена. Для переменной с таким именем не была зарезервирована никакая область памяти. Переменная, которая вас интересует, называется disc, и именно она содержит элемент с именем cost. Для того чтобы обратиться к члену структуры, необходимо указать его вместе с именем переменной, используя следующий формат:
structure_variable.member_name
Такая запись означает, что необходимо указать имя структурной переменной, поставить точку, а затем указать имя члена структуры, как это сделано в инструкциях:
gets(disc.name);
gets(disc.description);
gets(disc.category);
disc.cost = 16.95;
disc.number = 5;
Эти инструкции говорят компилятору, в какую именно область памяти следует поместить введенное значение, например, в член name структурной переменной disc.
Получение значений членов структуры осуществляется аналогичным образом, с точкой между именем структурной переменной и именем члена. В Листинге11.1 приведен текст программы, в которой вводится, а затем отображается на экране информация о картотеке компакт-дисков. В тексте программы нет ни одного случая, когда бы имя члена структуры использовалось без указания имени структурной переменной.
Вводить и выводить значения элементов структуры можно в любом порядке, не обязательно придерживаться именно того, который указан в описании структуры.
Листинг 11.1. Использование структуры при вводе и выводе.
/*CD1.c*/
struct CD
{
char name[20];
char description[40];char category[12];
float cost;
int number;
} disc;
main()
{
puts("Введите сведения о диске\n\n");
printf("Введите название: ");
gets(disc.name);
printf("Введите описание: ");
gets(disc.description);
printf("Введите категорию: ");
gets(disc.category);
printf("Введите цену: ");
scanf("%f", &dics.cost);
printf("Введите номер ячейки: ");
scanf("%d", &disc.number);
puts("Введена следующая информация о диске:\n\n");
printf("Название: %s\n", disc.name);
printf("Описание: %s\n", disc.description);
printf("Категория: %s\n", disc.category);
printf("Цена: %6.2f\n", disc.cost);
printf("Номер п/п: %d\n", disc.number);
}
Массивы структур
До сих пор мы работали с эквивалентом только одной регистрационной карточки. Но мы определили структуру с тем, чтобы хранить информацию обо всей коллекции записей. Для этого надо использовать не одиночную переменную, а массив. Создавая массив структур, мы создаем массив шаблонов. Такой массив можно определить, используя индекс с именем структурной переменной:
struct CD disc[10];
Таким образом, мы резервируем десять областей памяти, каждая из которых обладает достаточным объемом, чтобы хранить целую структуру (рис.11.7). Обращение к элементу массива происходит путем указания соответствующего индекса после имени самой структурной переменной, а не члена структуры:
gets(disc[0].name);
gets(disc[1].name);
В Листинге 11.2 приведен текст программы, использующей массив структур для выполнения задачи, которая может встретиться в реальной жизни, а именно, для заполнения регистрационных карточек, составляющих картотеку коллекции компакт-дисков.
Листинг 11.2. Использование массива структур.
/*CD2.c*/
struct CD
{
char name[20];
har description[40];
har category[12];
float cost;
int number;
} disc[10];
main()
{
int index, repeat;
har flag;
flag = 'Y';
index =0;
do
{
puts("Введите сведения о диске
#%d\n", index);
printf("Введите название: ");
gets(disc[index].name);
printf("Введите описание: ");
gets(disc[index].description);
printf("Введите категорию: ");
gets(disc[index].category);
printf("Введите цену: ");
scanf("%f", &dics[index].cost);
printf("Введите номер ячейки: ");
scanf("%d", &disc[index].number);
index++;
if(index < 10)
{
printf("Желаете ввести
данные о следующем диске? Да -Y, нет -N");
scanf("%C", &flag);
}
}
while (index < 10 && (flag == 'Y' || flag == 'y'));
puts("Название Номер п/п");
for (repeat = 0; repeat < index; repeat++)
printf("%s %d\n", disc[repeat].name,
disc[repeat].number);
}
Рис. 11.7. Массив структур
Определение массива, включающего 10 элементов disc, является частью определения структуры:
} disc[10];
Переменная flag ведена для того, чтобы пользователь мог указать, хочет ли он продолжить ввод информации, если заполнено меньше 10«карточек». Цикл do обеспечивает ввод элементов массива: пять пунктов (членов структуры) для каждого элемента массива (регистрационной карточки в картотеке коллекции). Переменная index используется как индекс в процессе создания картотеки.
После ввода значений каждого элемента массива, программа спрашивает пользователя, хочет ли он заполнить следующую карточку. После ввода значений всех 10элементов массива запрос больше не предъявляется.
В цикле do используется следующее условие:
while (index < 10 && (flag == 'Y' || flag == 'y'));
Логический оператор И указывает на то, что оба условия должны выполняться одновременно: значение переменной index должно быть меньше десяти, и переменная flag должна иметь значение 'Y' или 'y'. Если бы в условии не были поставлены внутренние скобки, компилятор Си скомбинировал бы первые два условия и трактовал всю инструкцию как условие ИЛИ (рис.11.8). И если в
Рис. 11.8. Интерпретация условия при отсутствии внутренних круглых скобок
этом случае переменная flag примет значение 'y', цикл будет повторяться и после ввода значений всех элементов.
Когда будут введены данные последнего элемента массива (карточки), значение переменной index окажется на единицу больше количества элементов массива. Эта переменная в дальнейшем используется в цикле for, в котором на дисплей выводится информация о содержании компакт-дисков и их местонахождении.
Обратите внимание на то, что все обращения к членам структуры включают имя переменной c указанием индекса массива.