5.6. Статические переменные. 120
5.8. Блочная структура. 122
5.9. Инициализация. 123
5.10. Рекурсия. 126
5.11. Препроцессор языка «C». 128
5.12. Заголовочные файлы.. 130
6. УКАЗАТЕЛИ И МАССИВЫ.. 132
6.1. Указатели и адреса. 132
6.2. Указатели и аргументы функций. 134
6.3. Указатели и массивы.. 136
6.4. Адресная арифметика. 139
6.5. Указатели символов и функции. 143
6.6. Указатели – не целые. 146
6.7. Многомерные массивы.. 147
6.8. Массивы указателей; указатели указателей. 150
6.9. Инициализация массивов указателей. 154
6.10. Указатели и многомерные массивы.. 155
6.11. Командная строка аргументов. 156
6.12. Указатели на функции. 160
7. СТРУКТУРЫ.. 164
7.1. Основные сведения. 164
7.2. Структуры и функции. 166
7.3. Массивы структур. 169
7.4. Указатели на структуры.. 174
7.5. Структуры, ссылающиеся на себя; двоичные деревья. 176
7.6. Поиск в таблице. 181
7.7. Битовые поля. 184
7.8. Объединения. 186
7.9. Определение «нового» типа данных. 188
8. ДИНАМИЧЕСКОЕ РАСПРЕДЕЛЕНИЕ ПАМЯТИ. 190
РАБОТА СО СПИСКАМИ.. 190
8.1. Динамическое выделение и освобождение памяти. 190
8.2. Понятие списка; основные виды списковых образований. 191
8.3. Создание и удаление списка. 194
8.4. Программы позиционирования для работы со списками. 197
9. ВВОД, ВЫВОД И ФОРМАТНЫЕ ПРЕОБРАЗОВАНИЯ.. 200
ДАННЫХ.. 200
9.1. Обращение к стандартной библиотеке. 200
9.3. Форматный вывод: функция printf 203
9.4. Форматный ввод: функция scanf 205
9.5. Форматные преобразования в памяти. 208
9.6. Доступ к файлам. 209
9.7. Обработка ошибок: stderr и exit 212
9.8. Ввод и вывод строк. 213
9.9. Несколько разнообразных функций. 215
ЛИТЕРАТУРА.. 217
Современный специалист по прикладной информатике или инженер по информационным системам должен уметь программировать. Ему не обязательно быть профессиональным системным программистом или «хакером». Дело в том, что и при разработке, и при эксплуатации сложных компьютерных систем требуется адаптировать соответствующее программное обеспечение. При этом нужно написать или изменить какую-то программу, создать новый программный интерфейс для работы с профессионально-ориентированной компьютерной системой, перепрограммировать систему контроля данных, написать новую программу загрузки базы данных и др.
Практика показывает, что в последнее время большинство таких работ проводится с применением языка «С++» (по-русски произносится как «си плюс плюс»), который в настоящее время является одним из самых популярных языков программирования. Это универсальный язык, для которого характерны экономичность выражения, современный поток управления и структуры данных, богатый набор операторов. Язык «C++» не является ни языком «очень высокого уровня», ни «большим» языком, и не предназначается для некоторой специальной области применения, но отсутствие ограничений и общность языка делают его более удобным и эффективным для многих задач, чем языки, предположительно более мощные. По разнообразному количеству средств, предоставляемых программистам, его можно считать одним из самых эффективных языков, но, иногда, – и самых эффектных, и самых сложных. Все перечисленные обстоятельства объясняют, почему нами этот язык выбран в качестве базового.
В язык «C++» в качестве основного, базового средства включен более старый язык «C» (по-русски произносится как «си», поэтому некоторые авторы пишут его название как «Си»), который первоначально предназначался для написания операционной системы Unix; он был разработан и реализован Деннисом Ричи. Операционные системы Unix и Windows, компиляторы с языка «C++» и большинство прикладных программных систем сейчас создаются на языке «C++». Этот язык, однако, не связан с какими-либо определенными аппаратными средствами или системами, и на нем легко писать программы, которые можно пропускать без изменений на любом компьютере или ЭВМ, имеющей C-компилятор.
Целью первого учебного курса «Основы алгоритмизации и программирования» является обучение основам программирования. В это время студент, не будучи асом алгоритмизации, не сможет по достоинству оценить возможности объектно-ориентированного программирования, предоставляемые «C++». Поэтому сначала обучение ведется на классическом языке «С» (он входит в состав любой версии «С++) с минимальным привлечением дополнительных средств, имеющихся в «C++».
В результате второго учебного курса студенты, получившие изрядный опыт по описанию алгоритмов средствами традиционного языка «C», совершенствуют свое мастерство, и средствами объектно-ориентированного программирования языка «C++» делают программы более эффективными и компактными.
Третий учебный курс «Программирование приложений для Windows» предназначен для развития навыков реализации реальных проектов, создания Windows-приложений (Windows applications). При этом используются все ранее изученные средства. В соответствии с этими тремя курсами учебно-методическое обеспечение также разделено на 3 части.
Мы не претендуем на оригинальность изложения теоретического материала по программированию. При создании данного учебного пособия нами использовались хрестоматийным образом данные из книг, пособий и справочников известных авторов: М.И. Болски, Б. Кернигана, Д. Кнута, Д. Дж. Круглински, А.Б. Крупника, Д. Ритчи, Г. Шилдта.
В качестве основного методического приема используется прагматический подход, изложенный в знаменитой книге Б. Кернигана и Д. Ритчи «Язык программирования Си», – это обучение на «живых» примерах.
Однако имеется и оригинальный материал. Например, глава 8 «Динамическое распределение памяти. Работа со списками» (в первой части книги), а также весь практикум по программированию.
Учебное пособие предназначено для студентов младших курсов компьютерных специальностей.
Редактор, профессор А.А. Емельянов
В.1. Том Сойер рисует на заборе
«Том появился на тротуаре с ведром извёстки и длинной кистью в руках. Он оглядел забор, и всякая радость отлетела от него, а дух погрузился в глубочайшую тоску. Тридцать ярдов дощатого забора в девять футов вышиной! Жизнь показалась ему пустой, а существование – тяжким бременем».
Марк Твен, «Приключения Тома Сойера»
Память компьютера похожа на длинный-предлинный забор, правда, покрашенный совсем не так, как хотелось бы тетушке Полли. Представим себе, что Том со своими дружками покрыли известкой не все доски забора, а, скажем, только первую, вторую, четвертую, седьмую... и т. д.:
1 1 0 1 0 0 1 0 1 1 0 0 1 1 1 0 1 1 0 0 1 1 0 0
Поступая так, Том Сойер и его команда, конечно же, не подозревали, что полосатый забор можно рассматривать как двоичный код, в котором единице соответствует светлая, а нулю – темная, непокрашенная доска. Каждая доска может быть только в двух состояниях, следовательно, она способна нести один бит информации. Число различных состояний двух идущих подряд досок уже равно четырем, поскольку каждому из двух состояний первой доски соответствуют два состояния второй. Легко понять, что восемь идущих подряд досок можно выкрасить
2 ´ 2 ´ 2 ´ 2 ´ 2 ´ 2 ´ 2 ´ 2 = 28 = 256 способами.
Иными словами, в восьми битах можно уместить 256 разных чисел (от 0 до 255, например), а этого вполне достаточно, чтобы закодировать любую букву. Поскольку «забор» в нашем примере состоит из 24 досок (цифр), он пригоден для того, чтобы закодировать сразу три буквы.
Какие же буквы показаны на заборе? Ответ на этот вопрос зависит от договоренности: какому числу соответствует та или иная буква. Первое число (11010010) на заборе равно (в привычном нам десятичном представлении) 210, второе (11001110) – это 206, третье (11001100) равно 204. И вся эта тройка соответствует в операционной системе Windows, скорее всего установленной у вас на компьютере, слову «ТОМ».
Цифра 8 возникла в нашем шуточном примере не случайно. Ведь восемь битов (досок в заборе тетушки Полли) составляют байт – ячейку памяти минимального размера, к которой имеет доступ компьютер. Можно сказать, что память компьютера состоит из последовательности идущих друг за другом ячеек – байтов. В этих ячейках хранятся нули и единицы, которые могут быть чем угодно: буквами, цифрами или выполняемыми компьютером командами.
Представим себе, что компьютерная программа написана на заборе, а роль процессора играет образцовый брат Тома – Сид. Том сидит на бочке и жует яблоко, а Сид отправляется к тому месту забора, где записана первая команда. Стоит еще раз подчеркнуть: в памяти компьютера, как и на заборе, хранятся последовательности нулей и единиц. Поэтому нужно заранее знать, с какой ячейки (байта) 5 начинается программа, чтобы не перепутать команды процессора и данные.
Итак, предположим, что команда начинается с 31-го байта, то есть с 241-й доски забора. Подойдя к ней, Сид ищет число, там записанное, в специальной справочной таблице, которую вынужден носить с собой. Из этой таблицы он узнает, что делать дальше. Может, например, оказаться, что прочитанный Сидом байт – лишь часть команды процессора, и чтобы выполнить ее, необходимо знать содержимое нескольких следующих ячеек.