
- •Язык программирования Си
- •Содержание
- •Литература
- •1. Введение в язык Си
- •История создания языка Си
- •Сравнение с другими языками программирования
- •Пользование компилятором
- •Внутренняя структура программы на языке Си для ibm pc (альтернативные модели распределения памяти)
- •Интегрированная среда Borland c
- •2.1 Основные компоненты интегрированной среды Borland c
- •2.2 Загрузка интегрированной среды Borland c
- •2.3. Основной экран Borland c
- •2.4. Выход из системы Borland c
- •2.5. Получение помощи
- •2.6. Редактор Интегрированной среды
- •2.6.1. Основные характеристики редактора интегрированной среды.
- •2.7. Основы работы в среде Borland c
- •2.7.1. Запуск интегрированной среды, создание и сохранение файлов
- •2.7.2. Компилирование и запуск программы на выполнение
- •2.7.3. Закрытие Окна Редактирования
- •2.7.4. Выход из Borland c
- •2.7.5. Какие файлы создаются в процессе трансляции и компоновки
- •2.7.6. Загрузка в редактор и редактирование вашей программы
- •2.8 Работа с несколькими исходными файлами. Файлы проекта
- •2.8.1. Файлы проектов
- •2.8.2. Использование менеджера проекта
- •2.8. Система меню Borland c
- •2.8.1. Меню File(Файл)
- •2.8.2. Меню Edit (Редактирование)
- •3.Процесс проектирования
- •3.1. Сущность программирования: без сюрпризов, минимум сцепления и максимум согласованности
- •3.2. Подавляйте демонов сложности
- •3.2.1. Не решайте проблем, которых не сушествует
- •3.2.2. Решайте конкретную проблему, а не общий случай
- •3.3. Интерфейс пользователя не должен напоминать компьютерную программу (принцип прозрачности)
- •3.4. Не путайте легкость в изучении с легкостью в использовании
- •3.5. Производительность может измеряться числом нажатий клавиш
- •3.6.1. Начинайте с комментариев
- •3.7.Читайте код
- •3.7.1. В цехе современных программистов нет места примадоннам
- •3.8. Разлагайте сложные проблемы на задачи меньшего размера
- •3.9. Используйте язык полностью
- •3.9.1. Используйте для работы соответствуюший инструмент
- •3.10. Проблема должна быть хорошо продумана перед тем, как она сможет быть решена
- •3.11. Компьютерное программирование является индустрией обслуживания
- •3.12. Вовлекайте пользователей в процесс проектирования
- •3.13. Заказчик всегда прав
- •3.15. Прежде всего, не навреди
- •3.16. Отредактируйте свой код
- •3.17. Программа должна писаться не менее двух раз
- •3.18. Нельзя измерять свою производительность числом строк
- •3.19. Вы не можете программировать в изоляции
- •3.20. Прочь глупости
- •3.21. Пишите программу с учетом сопровождения — сопровождаюшим программистом являетесь вы сами
- •4. Язык программирования с
- •4.1. Символика языка Си
- •4.2. Форматы основных операторов
- •4.3 Структура простых программ на Си
- •4.4 Работа с числовыми данными
- •4.4.1. Внешнее и внутреннее представление числовых данных
- •4.4.2. Ввод числовой информации
- •4.4.3. Вывод числовых результатов
- •4.5. Обработка текстовой информации
- •4.5.1. Символьные данные и их внутреннее представление
- •4.5.2. Ввод и вывод текстовой информации
- •4.5.3. Обработка фрагментов строк
- •4.5.4. Сравнение и сортировка текстовых данных
- •4.5.5. Управление цветом в текстовом режиме
- •4.6. Функции
- •4.6.1 Основные сведения о функциях
- •4.6.2. Функции, возвращающие нецелые значения
- •4.7. Внешние переменные
- •4.8. Области видимости
- •4.9. Заголовочные файлы
- •4.10. Статические переменные
- •4.11. Регистровые переменные
- •4.12. Блочная структура
- •4.13. Инициализация
- •4.14. Рекурсия
- •4.15. Препроцессор языка Си
- •4.15.1. Включение файла
- •4.15.2. Макроподстановка
- •4.15.3. Условная компиляция
- •4.16. Указатели и массивы
- •4.16.1.Операция получения адреса &
- •4.16.2. Переменные указатели
- •4.16.3. Указатели должны иметь значение
- •4.16.4. Доступ к переменной по указателю
- •4.16.5 Указатель на void
- •4.16.6. Указатели-константы и указатели переменные
- •4.16.7 Передача простой переменной в функцию
- •4.16.8. Передача массивов
- •4.16.9.Указатели и адреса
- •4.16.10. Указатели и аргументы функций
- •4.16.11. Указатели и массивы
- •4.16.12. Адресная арифметика
- •4.16.13. Символьные указатели функции
- •4.16.14. Многомерные массивы
- •4.16.15. Указатели против многомерных массивов
- •4.16.16. Аргументы командной строки
- •4.16.17. Указатели на функции
- •4.17. Структуры
- •4.17.1. Основные сведения о структурах
- •4.17.2 Структуры и функции
- •4.17.3. Массивы структур
- •4.17.4. Указатели на структуры
- •4.17.5. Структуры со ссылками на себя
- •4.17.6. Средство typedef
- •4.18. Объединения
- •4.19. Битовые поля
- •4.20. Графические примитивы в языках программирования
- •4.20.1. Инициализация и завершение работы с библиотекой
- •4.20.2. Работа с отдельными точками
- •4.20.3. Рисование линейных объектов
- •4.20.3.1. Рисование прямолинейных отрезков
- •4.20.3.2. Рисование окружностей
- •4.20.3.3. Рисование дуг эллипса
- •4.20.4. Рисование сплошных объектов
- •4.20.4.1. Закрашивание объектов
- •4.20.5. Работа с изображениями
- •4.20.6. Работа со шрифтами
- •4.20.7. Понятие режима (способа) вывода
- •4.20.8. Понятие окна (порта вывода)
- •4.20.9. Понятие палитры
- •4.20.10. Понятие видеостраниц и работа с ними
- •4.20.11. 16-Цветные режимы адаптеров ega и vga
- •4.21. Преобразования на плоскости
- •4.21.1. Аффинные преобразования на плоскости
- •4.22. Доступ к файлам
- •4.22.1. Вводвывод строк
- •4.22.2. Дескрипторы файлов
- •4.22.3. Нижний уровень вводавывода (read и write)
- •4.22.4. Системные вызовы open, creat,close,unlink
- •4.22.5. Произвольный доступ (lseek)
- •4.22.6. Сравнение файлового вводавывода и вводавывода системного уровня
3.2. Подавляйте демонов сложности
Ричард Рашид (разработчик Масh — варианта ОС UNIX)выступил несколько лет назад с фундаментальным обращением на конференции разработчиков Microsoft. Его главный смысл состоял в том, что слишком большая сложность, как в пользовательском интерфейсе, так и в программе является единственной крупной задачей, стоящей перед проектировщиками и пользователями программного обеспечения. По иронии судьбы, его речь была произнесена спустя два дня после провалившейся попытки показать нескольким тысячам очень толковых программистов, как следует программировать разработанный Microsoft интерфейс OLE 2.0 — один из самых сложных интерфейсов прикладного программирования, из когда-либо мною виденных. (OLE означает «связь и внедрение объектов». Стандарт OLE 2.0 определяет интерфейс, который может использоваться двумя программами для взаимодействия между собой определенным образом. Это действительно объектная ориентация на уровне операционной системы).
Предыдущий оратор, который убеждал пользоваться библиотекой Microsoft Foundation Class (MFC), сказал, что поддержка OLE в MFC «включает 20000 строк кода, необходимых для каждого базового приложения OLE 2.0». Аудитория была ошеломлена не полезностью MFC, а тем обстоятельством, что для написания базового приложения OLE 2.0 требуется 20000 строк кода. Любой такой сложный интерфейс является ущербным. Следующие несколько правил используют OLE для иллюстрации характерных трудностей, но не подумайте, что проблема запутанности характерна лишь для Microsoft — она существует везде.
3.2.1. Не решайте проблем, которых не сушествует
3.2.2. Решайте конкретную проблему, а не общий случай
Поучительно воспользоваться OLE 2.0 в качестве примера того, что случается с многими, слишком сложными проектами. Сложность интерфейса OLE связана с двумя главными причинами. Во-первых, он безуспешно пытается быть независимым от языка программирования. Идея таблицы виртуальных функций С++ является центральной для OLE 2.0. Спецификация OLE даже пользуется нотацией классов С++ для документирования работы различных интерфейсов OLE. Для реализации OLE на другом языке программирования (не С++) вы должны имитировать на этом языке таблицу виртуальных функций С++, что фактически ограничивает ваш выбор языками С++, С или ассемблером (если вы не разработчик компиляторов, который может добавить к выбранному вами языку нужные свойства). Честно говоря, нужно быть сумасшедшим, чтобы программировать OLE не на С++; потребуется гораздо меньше времени на изучение С++, чем на написание имитатора С++. То есть, эта идея независимости от языка программирования является неудачной. Отказавшись отэтой идеи, интерфейс можно было бы существенно упростить.
Возвращаясь к истории из предыдущего раздела, нужно заметить, что библиотека MFC в действительности решает проблему сложности, связанную с OLE, при помощи простого и легко понятного интерфейса, реализующего все возможности, нужные для большинства приложений OLE 2.0. Тот факт, что никто не хотел программировать с OLE, пока для этого не появилась оболочка на основе MFC, впечатляет. Разработка хорошей оболочки вокруг плохого интерфейса не может быть решением лежащей в основе проблемы.
Если оболочка с использованием MFC столь проста, то почему же лежащий в ее основе пласт так сложен? Ответ на этот вопрос является основным предметом проектирования. Создатели интерфейса OLE никогда не задавали себе два основных вопроса:
Какие основные функции должно поддерживать настоящее приложение?
Как реализовать эти возможности простейшим способом?
Другими словами, они имели в виду не реальное приложение, когда они проектировали этот интерфейс, а какой-то худший в теоретическом смысле случай. Они реализовали самый общий интерфейс из возможных, не думая о том, что на самом деле предполагается делать при помощи этого интерфейса, и получили в результате систему, которая может делать все, но при этом оказалась слишком сложной для практического применения. (Вероятно, разработчики даже и не пробовали реализовать этот интерфейс в каком-либо приложении, иначе они бы обнаружили эти проблемы).
Процесс объектно-ориентированного проектирования является в какой-то мере попыткой решения этой проблемы. Относительно просто добавить новую возможность в объектно-ориентированную систему или посредством наследования, или добавив новые обработчики сообщений к существующим классам. Скрывая определения данных от пользователя класса, вы оставляете за собой право полностью менять внутреннюю организацию класса, включая определения данных, не беспокоя пользователей этого класса, при условии, что вы сохраняете существующий интерфейс.
В структурном проектировании вы не позволите себе подобную роскошь. Вначале вы обычно проектируете структуры данных, и ваша главная задача — это модификация структуры данных, потому что нужно проверить каждую подпрограмму, использующую эту структуру, чтобы убедиться в том, что она еще работает. В результате «структурные» программы зачастую содержат массу бесполезного кода. Это делается в надежде на то, что кто-либо в будущем захочет воспользоваться той или иной функцией. На деле многие проектанты структурных программ гордятся своей способностью предсказывать направление, в котором может развиваться программа. В целом, все это вызывает массу бесполезного труда и приводит к программам с большим, чем требуется, размером.
Вместо того, чтобы учитывать в проекте все возможные случаи, пишите свой код таким образом, чтобы его легко можно было расширить в случае реальной необходимости•добавить новые функции. В этих случаях объектноориентированные проекты, как правило, работают лучше.