Сист. прогр. Ч2 (Методические указания к выполнению лабораторных работ по СПО), страница 12
Описание файла
Файл "Сист. прогр. Ч2" внутри архива находится в следующих папках: Методические указания к выполнению лабораторных работ по СПО, сист прогр лабы. Документ из архива "Методические указания к выполнению лабораторных работ по СПО", который расположен в категории "". Всё это находится в предмете "операционные системы" из 7 семестр, которые можно найти в файловом архиве РТУ МИРЭА. Не смотря на прямую связь этого архива с РТУ МИРЭА, его также можно найти и в других разделах. Архив можно найти в разделе "книги и методические указания", в предмете "операционные системы" в общих файлах.
Онлайн просмотр документа "Сист. прогр. Ч2"
Текст 12 страницы из документа "Сист. прогр. Ч2"
5. Более высокая степень машинной независимости. Языки высокого уровня, такие, как С, менее чувствительны к особенностям аппаратуры по сравнению с машинными языками. Это дает возможность использовать одну и ту же программу на разных машинах. И, что более важно, это заставляет программиста творить, а не заниматься «жонглированием» двоичными разрядами.
6. Возможность повышения эффективности. Эффективность программирования в кодах, возможно, наиболее серьезное возражение против языков высокого уровня. Конечно же, с точки зрения микроуровня хороший программист на машинном языке может создать более эффективную программу, чем компилятор. Однако в системе, содержащей миллион команд, фактор эффективности кодирования не так очевиден. Опытный программист, перекодируя С программу в коды машины, может увеличить скорость решения или эффективность распределения памяти в два-три раза. Но с точки зрения макро-подхода к проблеме эффективности совершенно не очевидно, что истинная экономия сводится только к случайной экономии отдельных байтов или слов. Часто оказывается более важным то, что при использовании языка высокого уровня алгоритм решения задачи становится проще и нагляднее. К сказанному следует также добавить, что в действительности программист, создавая. программу на машинном языке, редко имеет время для ее всесторонней оптимизации.
7. Создание работоспособной версии системы.
Обычно очень трудно предсказать неэффективность той или иной части программного обеспечения. И, как правило, в кодах команд машины пишутся именно те сегменты, для которых скорость и эффективность выполнения является наиболее критичными. В больших системах обычно около 80 процентов времени выполнения тратится менее чем на 20 процентов команд программы (например, подпрограммы обработки ошибок и ряд других программ используются редко). К сожалению, нет алгоритма, с помощью которого можно было бы заранее определять наиболее критические участки программы. Поэтому важно как можно раньше получить какую-то законченную версию системы, выявить эти критические участки, а затем оптимизировать их.
Вот семь областей, в которых преимущества языков высокого уровня представляются наиболее очевидными. Для извлечения максимальной пользы из этих преимуществ, необходимы:
1) язык высокого уровня, пригодный для системного программирования;
2) компилятор с этого языка ;
3) вычислительная машина и операционная система, которые помогли бы реализовать такую систему программирования на языке высокого уровня .
СВОЙСТВА ЯЗЫКА ВЫСОКОГО УРОВНЯ
В этом разделе рассматриваются наиболее важные свойства языков высокого уровня, таких, как С или Паскаль. Некоторые из этих свойств встречались в ФОРТРАНе, КОБОЛе и АЛГОЛе (например, структуры данных в языке КОБОЛ, алгольная блочная структура и рекурсии, указатели в ГПЛ), хотя ни один из указанных языков не обладает ими всеми. Нам кажется, что эти свойства в будущих языках станут обычными и компиляторы завтрашнего дня должны обеспечивать их реализацию. Основная трудность при создании компиляторов заключается вовсе не в грамматическом разборе арифметических операторов, на что так часто обращается особое внимание в литературе. Скорее наиболее сложными вопросами являются распределение памяти, рекурсии и тесное взаимодействие с операционной системой.
С представляет попытку эффективного объединения наиболее привлекательных свойств более ранних языков, В последующих разделах рассматриваются такие важные с точки зрения системного программирования свойства языка С, как:
1. Развитые типы данных и их организация :
а) строки символов,
б) строки битов,
в) структуры данных,
г) объединения данных.
2. Распределение памяти и область действия имен :
а) способы распределения памяти,
б) блочная структура.
3. Гибкость доступа к данным :
а) указатели,
б) унарные операторы.
4. Функциональная модульность ;
а) функции ,
б) рекурсии.
5. Асинхронные операции :
а) управление по условию,
б) сигналы,
в) мультизадачный режим.
6. Расширяемость :
а) макрокоманды времени компиляции,
б) структуры данных,
в) подпрограммы.
7. Разное .
ТИПЫ И СТРУКТУРЫ ДАННЫХ
В большинстве языков программирования предусмотрена возможность непосредственной обработки лишь ограниченного набора типов данных. В ФОРТРАНе, например, целые числа (числа с фиксированной точкой) и вещественные числа (числа с плавающей точкой) являются основными типами данных; комплексные числа и логические переменные допустимы только в некоторых реализациях. Хотя в ФОРТРАНе и допустима обработка символьных данных, однако делается это очень неудобно и громоздко, поскольку такие данные приходится рассматривать как целые либо как вещественные числа.
Как было показано при рассмотрении ассемблеров и загрузчиков, обработка символьных и битовых данных является основой большинства операций системного программирования. Более того, используемые базы данных являются на самом деле гораздо более сложными конструкциями, чем простые массивы. В частности, каждый элемент такой базы может в свою очередь состоять из нескольких полей, содержащих, возможно, даже различные типы данных. Такие типы данных, как битовая строка, символьная строка, а также структуры данных, предусмотренные в языке С, отвечают требованиям системного программирования.
СИМВОЛЬНАЯ СТРОКА
В С имеется богатая библиотека функций для работы с символьными строками, в частности туда входят:
1. Функция определения длины строки. Параметром функции является символьная строка, результатом - длина этой строки.
2. Функция конкатенации
3. Функции выделения подстрок, используемая для включения и исключения строк.
Ясно, что, допуская строку переменной длины , мы можем проиграть в эффективности из-за дополнительной обработки, связанной с распределением памяти и преобразованием таких строк. Это одна из проблем, с которой часто встречается разработчик компилятора.
СТРОКА БИТОВ
Над целыми числами и строками битов, допускаются следующие логические операции:
1. Побитовое И ( AND).
2. . Побитовое ИЛИ ( OR).
3. Исключающее ИЛИ ( XOR).
3. Унарная логическая операция НЕ ( NOT).
СТРУКТУРЫ и ОБЪЕДИНЕНИЯ
Структуры позволяют объединять данные разных типов под одним именем. Объединения позволяют данным разных типов использовать одну и ту же область памяти
. РАСПРЕДЕЛЕНИЕ ПАМЯТИ И ОБЛАСТЬ ДЕЙСТВИЯ ИМЕН
Во многих случаях при решении задачи на машине встает проблема минимизации как размеров самой программы, так и области памяти, необходимой для данных. Для существенного сокращения размера области памяти, необходимой для размещения данных, имеются два пути:
1. Резервировать память, только когда это необходимо. Например, при работе ассемблера одни данные необходимы только при первом просмотре, а другие - только при втором.
2. Резервировать ровно столько памяти, сколько необходимо, во многих случаях размер массивов и таблиц заранее неизвестен (т. е. их размер зависит от входных данных), и было бы весьма полезно задерживать резервирование памяти под такие данные, если, конечно, это допускается компилятором.
Типы памяти и блочная структура представляют собой средства языка С, обеспечивающие такое управление памятью.
ТИПЫ ПАМЯТИ
С предоставляет в распоряжение программиста следующие типы памяти: статическую, автоматическую и глобальную.
Статическая память постоянна и выделяется во время компиляции. Статическое распределение памяти является единственно возможным во многих языках программирования, например в ФОРТРАНе.
Автоматическая память распределяется при входе в блок, чаще всего на уровне функции. Например, если в функции SUBR объявлена переменная А , то А будет выделена память при первом обращении к функции. Когда функция закончится, память, отведенная под переменную А, будет освобождена для возможного использования другими функциями. Поэтому вполне вероятно, что при разных обращениях к функции SUBR переменной А будут выделяться разные участки памяти. Память для переменной А распределяется автоматически во время выполнения программы.
Управляемая память дает возможность программисту управлять распределением памяти при выполнении программы. Он может резервировать блок памяти, когда это необходимо, и может освобождать его в процессе выполнения программы. При рассмотрении указателей будут даны примеры использования управляемой памяти.
ГИБКОСТЬ ДОСТУПА К ДАННЫМ
Гибкость как в доступе, так и в передаче данных является одной из существенных предпосылок эффективного системного программирования. Гибкость доступа подразумевает способность манипулировать с самоопределенными структурами данных, а также со сложными организациями, подобными списковым структурам. Гибкость в передаче определяется способностью изменять и устанавливать место, куда должны быть переданы данные, в зависимости от входных данных и результатов предыдущих вычислений. Тип данных, названный указателем, в соединении с динамической памятью обеспечивают достаточно гибкий доступ к данным.
УКАЗАТЕЛИ
Указатели средство идентификации переменных, функций и областей памяти. При объявлении указателя на функцию используется псевдоописание функции, в которое при необходимости можно подставить вызов нужной функции. При выделении блока памяти, программист может завести для него один указатель, а при выделении памяти для другого блока - другой указатель. Теперь эти два блока различаются своими указателями. Напомним, что память, явно выделяемая программистом для размещения переменных, называется управляемой памятью.
Унарные и арифметические операции.
В языке С используются следующие арифметические операторы: + (сложение),
-(вычитание), * (умножение), / (деление), %( остаток от целочисленного деления), а также операции ++ и --, которые соответственно добавляют 1 или вычитают 1 как из переменных, так и из указателей. Над указателями одного типа могут производится операции сложения, вычитания и сравнения.
ФУНКЦИОНАЛЬНАЯ МОДУЛЬНОСТЬ
Одним из наиболее важных аспектов проектирования системы является возможность автономного написания, реализации и отладки отдельных модулей такой системы.
Механизм загрузки, рассмотренный ранее, позволяет объединить в общую программу отдельные программные модули, называемые также подпрограммами или функциями. Хотя понятие подпрограммы носит довольно общий характер, во многих языках программирования, таких, например, как АЛГОЛ и КОБОЛ, оно не используется.
Функции
В С используются функции, которые всегда внешние. Функция может быть как самостоятельным программным модулем, который компилируется отдельно и связывается с другими программными модулями с помощью загрузчика, так и компилироваться совместно с другими функциями в составе файла.
РЕКУРСИЯ
Рекурсия, реализация которой упрощается благодаря применению автоматической памяти, является важным средством программирования, позволяющим решать широкий круг задач. Как будет показано при обсуждении вопросов проектирования компиляторов, многие программы мы должны писать как рекурсивные. Мы уже убедились в том, что при реализации макропроцессора рекурсия была удобным способом реализации макровызова, содержащегося внутри макроопределения.
Более того, многие алгоритмы гораздо удобнее описывать и программировать с использованием рекурсии. Например, стандартное математическое определение факториала выглядит следующим образом:
1, если n=0 или n=1,
п*(п—1)!, если n=^(0 или 1).
АСИНХРОННОЕ ВЫПОЛНЕНИЕ ОПЕРАЦИЙ
Большинство языков программирования основывается на последовательном и синхронном выполнении операции, т. е. в любой момент времени выполняется одна команда, операторы обрабатываются последовательно друг за другом, пока не встретится оператор GO TO, изменяющий эту естественную последовательность. Однако в системном программировании встречаются ситуации, которые вызывают необходимость выполнения непоследовательной или несинхронной операции, как, например:
1. Обработка внутренних и внешних прерываний, т. е. прекращение нормальной последовательности выполнения программы, вызванное возникновением некоторого условия, связанного с выполнением программы, или внешнего условия, как, например, окончания или обнаружения ошибки при операции ввода- вывода.
2. Прерывания, вызванные, например, неправильными результатами, обнаруженными функцией, о чем должно быть сообщено другой функции.