
- •Глава 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()
Присваивание начального значения
Очень важно, чтобы все счетчики и аккумуляторы имели присвоенное начальное значение. Вы помните, что оба алгоритма увеличивают (или уменьшают) текущее значение переменной на определенную величину. Если не присвоить начальное значение, то эта величина будет прибавлена к случайному содержимому области памяти, зарезервированной для переменной. Инициализация переменной очищает содержимое памяти, так же как нажатие клавиши Clear на калькуляторе.
В качестве примера обратимся к Листингу 6.7, содержащему программу расчета среднего арифметического значения трех чисел. Допустим, в области памяти, отведенной для переменной total, содержится случайное значение 1827. Если переменной не было присвоено начальное значение
total = 0;
то, когда мы вводим первое число 75, первый аккумулятор должен будет выполнить следующую математическую операцию:
total = 1827 + 75
Присваивание начального значения 0 дает уверенность в том, что математические расчеты будут выполнены правильно:
total = 0 + 75
Проектирование программы
Теперь, когда вы умеете выполнять математические операции, используя операторы, вы можете проектировать программы с более сложной логической структурой, а следовательно, возрастает вероятность появления ошибок. Вам потребуется дополнительное время, чтобы убедиться, что ваша программа работает именно так, как вы планировали, и выдает действительно правильные результаты. Рассмотрим несколько примеров, демонстрирующих «подводные камни», которые могут вам встретиться.
Остерегайтесь логических ошибок
Ранее в этой же главе мы приводили пример программы для расчета недельного заработка (см. Листинг6.4). Компиляция этой программы пройдет без ошибок, и вы можете пользоваться ею некоторое время, прежде чем обнаружится главный изъян, а именно, в программе подразумевается, что служащий работает, по меньшей мере, 40 часов в неделю, или, что то же самое, минимальной возможной оплатой является оплата сорокачасовой рабочей недели. Если это действительно так, то никаких проблем не возникнет. Но что, если работник работает меньше сорока часов в неделю и должен получать зарплату в соответствии с реально отработанным временем? Если в эту программу ввести значение отработанных часов меньшее, чем 40, все расчеты окажутся неверными. Проблема содержится в инструкции
total = (40 * rate) +((hours - 40) * (rate * 2));
Во-первых, даже если кто-то работал меньше 40 часов, все равно значение оплаты одного часа будет умножено на 40, как указано в действии 40 * rate. Во-вторых, результат операции hours - 40 окажется отрицательной величиной. Это отрицательное значение будет умножено на оплату часа работы, увеличенную вдвое, и полученный результат прибавлен к основной зарплате. Добавление отрицательной величины приведет к уменьшению исходного значения, и в результате работник потеряет из заработка оплату в двойном размере за каждый час, недостающий до40.
Решение этой проблемы приводится в следующих главах. Пока же поиск решения представляется менее важной задачей, чем ясное понимание сущности проблемы.
Ищите образцы
Когда вы пишете программу, ищите образцы. Отыскивайте инструкции, которые будут использоваться неоднократно, возможно, лишь с небольшими изменениями. Если вы увидите какие-то закономерности, это поможет лучше понять, как работает программа, и позволит впоследствии без труда написать сходную с ней.
В качестве примера возьмем знакомую программу, в которой мы использовали деление нацело, чтобы набрать определенную сумму денег (см. Листинг6.2). Следующую последовательность инструкций можете рассматривать как образец:
twenties = amount / 20;
r20 = amount % 20;
tens = r20 / 10;
r10 = r20 % 10;
fives = r10 / 5;
ones = r10 % 5;
Обратите внимание на то, что переменные справа от знака равенства используются дважды: один раз с оператором деления (/), второй раз с
Рис.
6.12. Образец в программе из Листинга
6.2
оператором получения остатка от деления нацело (%). Заметьте также, что результат вычисления остатка от деления нацело используется в следующей за ним строке. На рис.6.12 проиллюстрирован приведенный образец.
Эту программу можно легко расширить распространением приведенного образца на другие уровни. Например, если вы хотите использовать банкноты достоинством 50 долларов, то можете модифицировать программу, добавив следующие строки:
fifties = amount / 50;
r50 = amount % 50;
twinties = r50 / 20;
r20 = r50 % 20;
В тот же образец мы добавили две новые инструкции и слегка видоизменили строку, в которой рассчитывается количество двадцатидолларовых банкнот.