- •Глава 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()
Языки программирования
Третье требование к программе— это язык, который понятен компьютеру.
Глубоко в недрах компьютера находится микропроцессор. Микропроцессор— это интегральная микросхема, которая управляет всем, что происходит в компьютере (рис.1.1).
Когда программа командует компьютеру отобразить сообщение на экране или напечатать его на принтере, микропроцессор посылает соответствующие электрические сигналы, которые говорят компьютеру, в какой области памяти можно отыскать нужное сообщение и куда его следует отправить. По большей части работа микропроцессора остается недоступной для наблюдателя, он загружает программу и полагает, что микропроцессор знает свое дело. Однако чтобы понять, как работает программа, необходимо иметь хотя бы самое элементарное представление о том, как действует микропроцессор.
Физически микропроцессор выполняет всего четыре действия. Он может перемещать данные из одной области памяти в другую, изменять данные в конкретной области, проверять, содержит ли конкретная область памяти определенные данные, и изменять последовательность выполнения инструкций. Все эти действия выполняются путем посылки, приема и отслеживания состояния электрических сигналов.
Электрические сигналы, с которыми имеет дело компьютер, могут иметь только два состояния (в зависимости от уровня напряжения): высокий уровень напряжения— электрический сигнал есть (состояние «включен») либо низкий уровень— электрический сигнал отсутствует (состояние «выключен»). Для того чтобы выполнить любую задачу, мы задаем микропроцессору последовательность сигналов в состоянии «включен» или «выключен». На рис.1.2 для примера приведена последовательность состояний электрических сигналов, необходимая для того, чтобы напечатать символ «А»*.
Для того чтобы задавать инструкции компьютеру на самом низком уровне, используется цифра 0, означающая состояние «выключен», и цифра 1,
* Здесь и далее на рисунках приведены не конкретные последовательности машинных команд, а лишь дано общее представление о них. (Прим.ред.)
Рис. 1.2. Ряд последовательных сигналов «включен» или «выключен»говорит микропроцессору, что ему делать, в данном случае—взять символ из памяти и послать на принтер
означающая состояние «включен». Мы называем это двоичными цифрами (битами)* или двоичными кодами, так как они основаны на двоичной системе счисления, в которой, как известно, все числа представлены только при помощи комбинаций нулей и единиц.
На заре компьютерных технологий программа выполнялась путем непосредственной манипуляции сигналами «включен», «выключен». Микропроцессоров тогда не существовало, и техник должен был вручную переводить ряды выключателей из одного состояния в другое, действуя, таким образом, как контроллер. Выполнение какой-нибудь задачи требовало правильной установки тысяч отдельных сигналов и, естественно, создание программы отнимало огромное количество времени и сил.
* От английского binary digit, bit. (Прим.перев.)
Рис. 1.3. Транслятор с языка ассемблера преобразует инструкциив двоичные коды
По мере развития электронной техники появилась возможность загружать программу в компьютер сразу, а затем заставлять его выполнять содержащиеся в программе инструкции. Такой способ программирования все еще требовал длительной процедуры задания последовательностей тысяч отдельных цифр 0 и 1, и так продолжалось до тех пор, пока не был разработан язык программирования ассемблер.
Ассемблер представляет задачу, адресованную непосредственно микропроцессору, используя мнемонические коды. Мнемонические коды— это несложные для запоминания слова или аббревиатуры, представляющие завершенное задание для микропроцессора. Например, код MOV указывает компьютеру на то, что некую информацию следует переместить из одной области памяти в другую, а код JMP указывает, что необходимо перейти в другую область памяти. Таким образом, вместо того, чтобы составлять последовательные ряды 0 и 1, программист на ассемблере может использовать мнемонические коды, подобные приведенным выше, каждый из которых представляет собой восемь или более бит.
Как показано на рис. 1.3, транслятор с ассемблера переводит эти коды в информацию о состояниях отдельных электрических сигналов, понятную компьютеру. Так как каждый мнемонический код соотносится непосредственно
Рис. 1.4. Сравнение языка Си, ассемблера и двоичных кодов
с внутренними функциями микропроцессора, программа, написанная на ассемблере, выполняется предельно быстро, но само программирование на этом языке отнимает достаточно много времени и требует написания исходных программ большого объема.
В настоящее время большинство программистов работают с языками высокого уровня, где инструкции задают с помощью человеческих слов, а не мнемонических кодов или 0 и 1. Каждое слово представляет практически завершенную операцию, а не одно задание для микропроцессора. Например, функция языка Си puts()* указывает компьютеру, что некая информация должна быть выведена на дисплей. Для выполнения этой же функции может потребоваться использование большого количества мнемонических кодов ассемблера и сотен бит.
Рис. 1.4 демонстрирует простую инструкцию, используемую языком Си и Си++ для вывода какого-нибудь слова на экран, и примерные эквиваленты той же инструкции, написанные на ассемблере и в двоичных кодах. Вы можете сами решить, какой язык программирования кажется более легким для чтения и создания текстов программ.
Разумеется, сам по себе компьютер не понимает, что означает функция puts() и другие инструкции языков высокого уровня, поэтому, прежде чем компьютер реально сможет выполнить задание, оно должно быть переведено на его собственный язык— язык двоичных кодов.
* От английского put string. (Прим.перев.)
Операцию по переводу человеческих слов в двоичные коды можно выполнить двумя способами, которые называют компиляцией и интерпретацией.