Файл: Информация и формы ее представления Информационные процессы и технологии.docx

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 07.11.2023

Просмотров: 296

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

СОДЕРЖАНИЕ

Раздел 1 Основы информатики

1.3. ЭВМ как средство обработки информации

1.1 Информация и формы ее представления

Понятие количества информации

1.2 Информационные процессы и технологии

1.3 ЭВМ как средство обработки информации

Понятие архитектуры ЭВМ

Классификация ЭВМ

Структура и принципы функционирования ЭВМ

Основные характеристики вычислительной техники

Перспективы развития вычислительных средств

2.4 Операционная система MS-DOS

Системный блок

Монитор

Клавиатура

Мышь

Устройства ввода графических данных Для ввода графической информации используют сканеры, графические планшеты (дигитайзеры) и цифровые фотокамеры. Интересно отметить, что с помощью сканеров можно вводить и знаковую информацию. В этом случае исходный материал вводится в графическом виде, после чего обрабатывается специальными программными средствами (программами распознавания образов),Планшетные сканеры. Планшетные сканеры предназначены для ввода графической информации с прозрачного или непрозрачного листового материала (рис. 2.14). Принцип действия этих устройств состоит в том, что луч света, отраженный от поверхности материала (или прошедший сквозь прозрачный материал), фиксируется специальными элементами, называемыми приборами с зарядовой связью (ПЗС). Обычно элементы ПЗС конструктивно оформляют в виде линейки, располагаемой по ширине исходного материала. Перемещение линейки относительно листа бумаги выполняется механическим протягиванием линейки при неподвижной установке листа или протягиванием листа при неподвижной установке линейки. Рисунок 2.14 - Планшетный сканер ScanJet 3200C с аппаратным разрешением 600х1200 dpi фирмы Hewlett PackardОсновными потребительскими параметрами планшетных сканеров являются: разрешающая способность; производительность; динамический диапазон; максимальный размер сканируемого материала. Разрешающая способность планшетного сканера зависит от плотности размещения приборов ПЗС на линейке, а также от точности механического позиционирования линейки при сканировании. Типичный показатель для офисного применения: 600-1200 dpi (dpi – dots per inch – количество точек на дюйм). Для профессионального применения характерны показатели 1200-3000 dpi.Производительность сканера определяется продолжительностью сканирования листа бумаги стандартного формата и зависит как от совершенства механической части устройства, так и от типа интерфейса, использованного для сопряжения с компьютером.Динамический диапазон определяется логарифмом отношения яркости наиболее светлых участков изображения к яркости наиболее темных участков. Типовой показатель для сканеров офисного применения составляет 1,8-2,0, а для сканеров профессионального применения – от 2,5 (для непрозрачных материалов) до 3,5 (для прозрачных материалов).Ручные сканеры. Принцип действия ручных сканеров в основном соответствует планшетным. Разница заключается в том, что протягивание линейки ПЗС в данном случае выполняется вручную. Равномерность и точность сканирования при этом обеспечиваются неудовлетворительно, и разрешающая способность ручного сканера составляет 150-300 dpi.Барабанные сканеры. В сканерах этого типа исходный материал закрепляется на цилиндрической поверхности барабана, вращающегося с высокой скоростью. Устройства этого типа обеспечивают наивысшее разрешение (2400-5000 dpi) благодаря применению не ПЗС, а фотоэлектронных умножителей. Их используют для сканирования исходных изображений, имеющих высокое качество, но недостаточные линейные размеры (фотонегативов, слайдов и т. п.)Сканеры форм. Предназначены для ввода данных со стандартных форм, заполненных механически или <от руки». Необходимость в этом возникает при проведении переписей населения, обработке результатов выборов и анализе анкетных данных. От сканеров форм не требуется высокой точности сканирования, но быстродействие играет повышенную роль и является основным потребительским параметром.Штрих-сканеры. Эта разновидность ручных сканеров предназначена для ввода данных, закодированных в виде штрих-кода. Такие устройства имеют применение в розничной торговой сети.Графические планшеты (дигитайзеры). Эти устройства предназначены для ввода художественной графической информации. Существует несколько различных принципов действия графических планшетов, но в основе всех их лежит фиксация перемещения специального пера относительно планшета. Такие устройства удобны для художников и иллюстраторов, поскольку позволяют им создавать экранные изображения привычными приемами, наработанными для традиционных инструментов (карандаш, перо, кисть). К техническим характеристикам планшетам относятся: разрешающая способность (линий/мм), площадь рабочей области и количество уровней чувствительности к нажатию пера. На рис. 2.15 показан дигитайзер фирмы AIPTEK INK формата А6 с 512 уровнями чувствительности к нажатию пера. Рисунок 2.15 - Дигитайзер HYPER Pen 5000 фирмы AIPTEK INK Цифровые фото- и видеокамеры. Как и сканеры, эти устройства воспринимают графические данные с помощью приборов с зарядовой связью, объединенных в прямоугольную матрицу. Основным параметром цифровых фотоаппаратов является разрешающая способность, которая напрямую связана с количеством ячеек ПЗС в матрице. Наилучшие потребительские модели в настоящее время имеют до 1 млн. ячеек ПЗС и, соответственно, обеспечивают разрешение изображения до 800х1200 точек. У профессиональных моделей эти параметры выше. На рис. 2.16 показан недорогой фотоаппарат фирмы Mustek с оптическим разрешением 640х480 пикселей. Рисунок 2. 16 - Цифровая фотокамера VDC-200 фирмы MustekОсновные параметры видеокамер рассмотрим на примере камеры фирмы Mustek, представленной на рис. 2.17. Разрешение: 356х292 (HxV). Скорость передачи данных: 353х282, 16 бит цвета (сжатие), 20 кадров/с. Скорость передачи данных: 176x144, 16 бит цвета (сжатие), 30 кадров/с. Настройка фокусного расстояния: ручная. Экспозиция и баланс белого: автоматическая. Угол обзора ± 39°. Рисунок 2.17 - Цифровая видеокамера фирмы Mustek Устройства вывода данных В качестве устройств вывода данных, дополнительных к монитору, используют печатающие устройства (принтеры), позволяющие получать копии документов на бумаге или прозрачном носителе. По принципу действия различают матричные, лазерные, светодиодные и струйные принтеры.Матричные принтеры. Это простейшие печатающие устройства (см. рис. 2.18). Данные выводятся на бумагу в виде оттиска, образующегося при ударе цилиндрических стержней («иголок») через красящую ленту. Качество печати матричных принтеров напрямую зависит от количества иголок в печатающей головке. Наибольшее распространение имеют 9-игольчатые и 24-игольчатые матричные принтеры. Последние позволяют получать оттиски документов, не уступающие по качеству документам, исполненным на пишущей машинке. Рисунок 2.18 - Матричный 9-игольчатый принтер формата A3 Epson FX-1180 производительностью 396 cpsПроизводительность работы матричных принтеров оценивают по количеству печатаемых знаков в секунду (cps – characters per second). Обычными режимами работы матричных принтеров являются: draft – режим черновой печати, normal – режим обычной печати и режим NLQ (Near Letter Quality), который обеспечивает качество печати, близкое к качеству пишущей машинки.Лазерные принтеры. Лазерные принтеры обеспечивают высокое качество печати, не уступающее, а во многих случаях и превосходящее полиграфическое. Они отличаются также высокой скоростью печати, которая измеряется в страницах в минуту (ррт – page per minute). Как и в матричных принтерах, итоговое изображение формируется из отдельных точек. Рисунок 2.19 - Лазерный принтер HP LaserJet 4000 производительностью 16 ppmПринцип действия лазерных принтеров следующий: в соответствии с поступающими данными лазерная головка испускает световые импульсы, которые отражаются от зеркала и попадают на поверхность светочувствительного барабана; горизонтальная развертка изображения выполняется вращением зеркала; участки поверхности светочувствительного барабана, получившие световой импульс, приобретают статический заряд; барабан при вращении проходит через контейнер, наполненный красящим составом (тонером), и тонер закрепляется на участках, имеющих статический заряд; при дальнейшем вращении барабана происходит контакт его поверхности с бумажным листом, в результате чего происходит перенос тонера на бумагу; лист бумаги с нанесенным на него тонером протягивается через нагревательный элемент, в результате чего частицы тонера спекаются и закрепляются на бумаге. К основным параметрам лазерных принтеров относятся: разрешающая способность, dpi (dots per inch – точек на дюйм); производительность (страниц в минуту); формат используемой бумаги; объем собственной оперативной памяти. При выборе лазерного принтера необходимо также учитывать параметр стоимости оттиска, то есть стоимость расходных материалов для получения одного печатного листа стандартного формата А4. К расходным материалам относится тонер и барабан, который после печати определенного количества оттисков утрачивает свои свойства. В качестве единицы измерения используют цент на страницу (имеются в виду центы США). В настоящее время теоретический предел по этому показателю составляет порядка 1,0-1,5. На практике лазерные принтеры массового применения обеспечивают значения от 2,0 до 6,0.Основное преимущество лазерных принтеров заключается в возможности получения высококачественных отпечатков. Модели среднего класса обеспечивают разрешение печати до 600 dpi, а профессиональные модели – до 1200 dpi.Светодиодные принтеры. Принцип действия светодиодных принтеров похож на принцип действия лазерных принтеров. Разница заключается в том, что источником света является не лазерная головка, а линейка светодиодов. Поскольку эта линейка расположена по всей ширине печатаемой страницы, отпадает необходимость в механизме формирования горизонтальной развертки и вся конструкция получается проще, надежнее и дешевле. Типичная величина разрешения печати,. для светодиодных принтеров составляет порядка 600 dpi.Струйные принтеры. В струйных печатающих устройствах изображение на бумаге формируется из пятен, образующихся при попадании капель красителя на бумагу (рис. 2.20). Выброс микрокапель красителя происходит под давлением, которое развивается в печатающей головке за счет парообразования. В некоторых моделях капля выбрасывается щелчком в результате пьезоэлектрического эффекта – этот метод позволяет обеспечить более стабильную форму капли, близкую к сферической.Качество печати изображения во многом зависит от формы капли и ее размера, а также от характера впитывания жидкого красителя поверхностью бумаги. В этих условиях особую роль играют вязкостные свойства красителя и свойства бумаги. Рисунок 2.20 - Струйный принтер Stylus Color 640 с разрешением 1440 dpi и скоростью печати: 5 страниц в минуту в монохроме, 3,5 страницы в минуту в цвете К положительным свойствам струйных печатающих устройств следует отнести относительно небольшое количество движущихся механических частей и, соответственно, простоту и надежность механической части устройства и его относительно низкую стоимость. Основным недостатком, по сравнению с лазерными принтерами, является нестабильность получаемого разрешения, что ограничивает возможность их применения в черно-белой полутоновой печати.В то же время, сегодня струйные принтеры нашли очень широкое применение в цветной печати. Благодаря простоте конструкции они намного превосходят цветные лазерные принтеры по показателю качество/цена. При разрешении выше 600 dpi они позволяют получать цветные оттиски, превосходящие по качеству цветные отпечатки, получаемые фотохимическими методами.При выборе струйного принтера следует обязательно иметь виду параметр стоимости печати одного оттиска. При том, что цена струйных печатающих устройств заметно ниже, чем лазерных, стоимость печати одного оттиска на них может быть в несколько раз выше.Устройства хранения данных Необходимость во внешних устройствах хранения данных возникает в двух случаях: когда на вычислительной системе обрабатывается больше данных, чем можно разместить на базовом жестком диске; когда данные имеют повышенную ценность и необходимо выполнять регулярное резервное копирование на внешнее устройство (копирование данных на жестком диске не является резервным и только создает иллюзию безопасности). В настоящее время для внешнего хранения данных используют несколько типов устройств, использующих магнитные или магнитооптические носители.Стримеры. Стримеры – это накопители на магнитной ленте. Их отличает сравнительно низкая цена. К недостаткам стримеров относят малую производительность (она связана прежде всего с тем, что магнитная лента – это устройство последовательного доступа) и недостаточную надежность (кроме электромагнитных наводок, ленты стримеров испытывают повышенные механические нагрузки и могут физически выходить из строя).Емкость магнитных кассет (картриджей) для стримеров составляет до нескольких сот Мбайт. Дальнейшее повышение емкости за счет повышения плотности записи снижает надежность хранения, а повышение емкости за счет увеличения длины ленты сдерживается низким временем доступа к данным.ZIP-накопители.ZIP-накопители выпускаются компанией Iomega, специализирующейся на создании внешних устройств для хранения данных. Устройство работает с дисковыми носителями, по размеру незначительно превышающими стандартные гибкие диски и имеющими емкость 100/250 Мбайт. ZIP-накопители выпускаются во внутреннем и внешнем исполнении. В первом случае их подключают к контроллеру жестких дисков материнской платы, а во втором – к стандартному параллельному порту, что негативно сказывается на скорости обмена данными.Накопители HiFD. Основным недостатком ZIP-накопителей является отсутствие их совместимости со стандартными гибкими дисками 3,5 дюйма. Такой совместимостью обладают устройства HiFD компании Sony. Они позволяют использовать как специальные носители емкостью 200 Мбайт, так и обычные гибкие диски. В настоящее время распространение этих устройств сдерживается повышенной ценой.Накопители JAZ. Этот тип накопителей, как и ZIP-накопители, выпускается компанией Iomega. По своим характеристикам JAZ-носитель приближается к жестким дискам, но в отличие от них является сменным. В зависимости от модели накопителя на одном диске можно разместить 1 или 2 Гбайт данных.Магнитооптические устройства. Эти устройства получили широкое распространение в компьютерных системах высокого уровня благодаря своей универсальности. С их помощью решаются задачи резервного копирования, обмена данными и их накопления. Однако достаточно высокая стоимость приводов и носителей не позволяет отнести их к устройствам массового спроса.В этом секторе параллельно развиваются 5,25- и 3,5-дюймовые накопители, носители для которых отличаются в основном форм-фактором и емкостью. Последнее поколение носителей формата 5,25" достигает емкости 5,2 Гбайт. Стандартная емкость для носителей 3,5" – 640 Мбайт.В формате 3,5" недавно была разработана новая технология GIGAMO, обеспечивающая емкость носителей в 1,3 Гбайт, полностью совместимая сверху вниз с предыдущими стандартами. В перспективе ожидается появление накопителей и дисков форм-фактора 5,25", поддерживающих технологию NFR (Near Field Recording), которая обеспечит емкость дисков до 20 Гбайт, а позднее и до 40 Гбайт.Устройства обмена данными Модем. Устройство, предназначенное для обмена информацией между удаленными компьютерами по каналам связи, принято называть модемом (МОдулятор + ДЕМодулятор) (см. рис. 2.21). При этом под каналом связи понимают физические линии (проводные, оптоволоконные, кабельные, радиочастотные), способ их использования (коммутируемые и выделенные) и способ передачи данных (цифровые или аналоговые сигналы). В зависимости от типа канала связи устройства приема-передачи подразделяют на радиомодемы, кабельные модемы и прочие. Наиболее широкое применение нашли модемы, ориентированные на подключение к коммутируемым телефонным каналам связи.Цифровые данные, поступающие в модем из компьютера, преобразуются в нем путем модуляции (по амплитуде, частоте, фазе) в соответствии с избранным стандартом (протоколом) и направляются в телефонную линию. Модем-приемник, понимающий данный протокол, осуществляет обратное преобразование (демодуляцию) и пересылает восстановленные цифровые данные в свой компьютер. Таким образом обеспечивается удаленная связь между компьютерами и обмен данными между ними.К основным потребительским параметрам модемов относятся: производительность (бит/с); поддерживаемые протоколы связи и коррекции ошибок; шинный интерфейс, если модем внутренний (ISA или РСI). От производительности модема зависит объем данных, передаваемых в единицу времени. От поддерживаемых протоколов зависит эффективность взаимодействия данного модема с сопредельными модемами (вероятность того, что они вступят во взаимодействие друг с другом при оптимальных настройках). От шинного интерфейса в настоящее время пока зависит только простота установки и настройки модема (в дальнейшем при общем совершенствовании каналов связи шинный интерфейс начнет оказывать влияние и на производительность).По способу подключения модемы делятся на два вида: внешние и внутренние. Внешний модем подключается к одному из COM-портов. Внутренний вставляется внутрь системного блока в виде платы расширения. На рис. 2.23 представлены внешний и внутренний факс/модемы Courier V.34 фирмы US Robotics. Рисунок 2.21 - Внешний и внутренний факс/модемы Courier V.34 фирмы US Robotics2.3 Виды программного обеспечения ЭВМНазначением ЭВМ является выполнение программ. Программа содержит команды, определяющие порядок действий компьютера. Совокупность программ для компьютера образует программное обеспечение (ПО). По функциональному признаку различают следующие виды ПО: системное; прикладное; инструментальное. Рисунок 2.22 - Структура программного обеспеченияПод системным (базовым) понимается программное обеспечение, включающее в себя операционные системы, сетевое ПО, сервисные программы, а также средства разработки программ (трансляторы, редакторы связей, отладчики и пр.).Основные функции операционных систем (ОС) заключаются в управлении ресурсами (физическими и логическими) и процессами вычислительных систем. Физическими ресурсами являются: оперативная память, процессор, монитор, печатающее устройство, магнитные и оптические диски. К логическим ресурсам можно отнести программы, файлы, события и т. д. Под процессом понимается некоторая последовательность действий, предписанная соответствующей программой и используемыми ею данными.В настоящее время существует большое количество ОС, разработанных для ЭВМ различных типов. На ЭВМ Единой Системы (ЕС ЭВМ), например, использовались такие операционные системы, как СВМ и ОС ЕС, на малых ЭВМ (СМ-4, СМ-1420 и др.) - ОС РВ и RSX-11. На персональных ЭВМ долгое время эксплуатировалась ОС-MS-DOS. В настоящее время получили распространение системы Windows , Unix, Linix.Сетевое ПО предназначено для управления общими ресурсами в распределенных вычислительных системах: сетевыми накопителями на магнитных дисках, принтерами, сканерами, передаваемыми сообщениями и т. д. К сетевому ПО относят ОС, поддерживающие работу ЭВМ в сетевых конфигурациях (так называемые сетевые ОС), а также отдельные сетевые программы (пакеты), используемые совместно с обычными, не сетевыми ОС.Например, большое распространение получили следующие сетевые ОС: NetWare 4.1 (фирма Novell), Windows NT Server 3.5 (фирма Microsoft) и LAN Server 4.0 Advanced (фирма IBM). Однако в последнее время лидирующие позиции начинает занимать ОС Windows 2000 Server фирмы Microsoft.  Для расширения возможностей операционных систем и предоставления набора дополнительных услуг используются сервисные программы. Их можно разделить на следующие группы: интерфейсные системы; оболочки операционных систем; утилиты. Интерфейсные системы являются естественным продолжением операционной системы и модифицируют как пользовательский, так и программный интерфейсы, а также реализуют дополнительные возможности по управлению ресурсами ЭВМ. В связи с тем, что развитая интерфейсная система может изменить весь пользовательский интерфейс, часто их также называют операционными системами. Это относится, например, к Windows.Оболочки операционных систем, в отличие от интерфейсных систем, модифицируют только пользовательский интерфейс, предоставляя пользователю качественно новый интерфейс по сравнению с реализуемым операционной системой. Такие системы существенно упрощают выполнение часто запрашиваемых функций, например, таких операций с файлами, как копирование, переименование и уничтожение, а также предлагают пользователю ряд дополнительных услуг. В целом, программы-оболочки заметно повышают уровень пользовательского интерфейса, наиболее полно удовлетворяя потребностям пользователя.На ПЭВМ широко используются такие программы-оболочки, как Norton Commander, FAR Manager и Windows Commander.Утилиты предоставляют пользователям средства обслуживания компьютера и его ПО. Они обеспечивают реализацию следующих действий: обслуживание магнитных дисков; обслуживание файлов и каталогов; предоставление информации о ресурсах компьютера; шифрование информации; защита от компьютерных вирусов; архивация файлов и др. Существуют отдельные утилиты, используемые для решения одного из перечисленных действий, и многофункциональные комплекты утилит. В настоящее время для ПЭВМ среди многофункциональных утилит одним из наиболее совершенных является комплект утилит Norton Utilities. Существуют его версии для использования в среде DOS и Windows.Средства разработки программ используются для разработки нового программного обеспечения как системного, так и прикладного.Прикладным называется ПО, предназначенное для решения определенной целевой задачи из проблемной области. Часто такие программы называют приложениями.Спектр проблемных областей в настоящее время весьма широк и включает в себя по крайней мере следующие: промышленное производство, инженерную практику, научные исследования, медицину, управление (менеджмент), делопроизводство, издательскую деятельность, образование и т. д. Из всего разнообразия прикладного ПО выделяют группу наиболее распространенных программ (типовые пакеты и программы), которые можно использовать во многих областях человеческой деятельности.К типовому прикладному ПО относят следующие программы: текстовые процессоры; табличные процессоры; системы иллюстративной и деловой графики (графические процессоры); системы управления базами данных; экспертные системы; программы математических расчетов, моделирования и анализа экспериментальных данных. Предлагаемые на рынке ПО приложения, в общем случае, могут быть выполнены как отдельные программы либо как интегрированные системы. Интегрированными системами обычно являются экспертные системы, программы математических расчетов, моделирования и анализа экспериментальных данных, а также офисные системы. Примером мощной и широко распространенной интегрированной системы является офисная система Microsoft Office.Поскольку разработка ПО любого назначения, как правило, является довольно сложным и трудоемким процессом, дальнейший материал настоящего раздела посвятим общим вопросам разработки программ и инструментальному ПО.Инструментальное ПО Инструментальное программное обеспечение представляет комплексы программ для создания других программ. Программы инструментального программного обеспечения управляются системными программами, поэтому они относятся к более высокому уровню. К инструментальному ПО относятся: компиляторы, редакторы связей, отладчики, интегрированные системы разработки ПО, например, интегрированная система Delphi, Visual Studio и т.п..2.4 Операционная система MS-DOS Операционная система MS-DOS – это однопользовательская, однозадачная, не сетевая 16-разрядная операционная система (ОС), ориентированная на использование на ПЭВМ с микропроцессором Intel 8088(80286).Краткая история появления данной операционной системы такова. В октябре 1980 г. менеджеры фирмы IBM занялись поисками ОС для своего 16-разрядного персонального компьютера (ПК), находящегося в стадии разработки. В тот период на ПЭВМ наиболее широко применялась ОС CP/M (Control Program for MicroComputers) фирмы Digital Research. Не достигнув приемлемых соглашений с Digital Research, фирма IBM обратилась к фирме Microsoft (президент – Билл Гейтс). В тот момент у Microsoft не было соответствующей OС, но ей была известна небольшая фирма Seattle Computer Products, которая имела такую OС. За 50 000$ Билл Гейтс приобрел права на эту OС. В дальнейшем эта OС послужила основой для MS-DOS. В ноябре 1980 г. Microsoft и IBM подписали договор на разработку OС для IBM PC. В феврале 1981 г. появилась первая версия PC/MS-DOS, которая работала на IBM PC, в августе того же года – PC DOS 1.0 (эта версия была утверждена для применения на IBM PC).Операционная система MS-DOS позволяет полностью использовать возможности процессоров Intel 8088 и Intel 80286, работающих в реальном режиме. Основными характеристиками данной ОС являются: максимальный объем адресуемой физической памяти – 640 Кбайт; максимальный объем памяти, доступный из прикладных программ 640 Кбайт. Последние версии MS-DOS (начиная с 5.0) могут использовать адресное пространство между 640 Кбайт и 1 Мбайт для размещения своих составных частей и некоторых драйверов, освобождая тем самым память в адресном пространстве 0-640 Кбайт для использования прикладными программами; представление всех ресурсов персонального компьютера для одной, активной в настоящий момент, программы; развитая файловая система и процессор командного языка; слабая поддержка интерактивных средств взаимодействия с пользователем; занимаемый объем на диске, в зависимости от версии, от 1 Мбайта до 6 Мбайт. (минимум, при котором можно работать – 100 Кбайт). Основные составные части MS-DOS MS-DOS состоит из следующих компонент: блок начальной загрузки (размещается в 1-м секторе 0-дорожки 0-стороны системной дискеты); модуль расширения BIOS (IO.SYS для версии 5.0 и выше); модуль обработки прерываний (MSDOS.SYS для версии 5.0 и выше), командный процессор (COMMAND.COM); внешние команды (программы) MS-DOS; драйверы устройств; файл Config.SYS; файл Autoexec.bat. Ядро MS-DOS включает блок начальной загрузки и файлы IO.SYS, MSDOS.SYS.Блок начальной загрузки размещается  в 1-м секторе 0-дорожки 0-стороны системной дискеты и/или в 1-м секторе HDD-диска, в разделе, отведенном под DOS. Выполняет следующие функции: просматривает корневой каталог системного диска и проверяет, являются ли первые два файла в каталоге – файлами IO.SYS и MSDOS.SYS. Если ДА – загружает их в ОЗУ и передает управление MS-DOS, если НЕТ – выдает сообщение на экране и ожидает нажатия какой-либо клавиши пользователем: Non-System disk or disk errorReplace and press any key when ready (Не системный диск или ошибка дискаЗамените и нажмите какую-либо клавишу, когда будет готово)Именно поэтому , при создании системной дискеты необходимо переносить на неё файлы IO.SYS и MSDOS.SYS с помощью специальной программы SYS.COM.Модуль расширения BIOS IO.SYSЭто резидентный модуль (всегда находится в ОЗУ после загрузки, пока включен ПК). Взаимодействует с BIOS. Расширяет возможности BIOS или изменяет ее свойства (там, где необходимо) с помощью дополнительных драйверов.Модуль обработки прерываний MSDOS.SYSЭто резидентный модуль. Обеспечивает интерфейс высокого уровня для прикладных программ, содержит программные средства для управления файлами, устройствами ввода-вывода, обработки исключительных ситуаций (ошибок) и др. Прикладная программа вызывает функции этого модуля через механизм программных прерываний, передавая (принимая) информацию к (от) MS-DOS через регистры CPU или (и) области памяти ОЗУ. MSDOS.SYS транслирует (переводит) запрос прикладной программы в один или несколько вызовов IO.SYS + BIOS.Командный процессор COMMAND.COMОтдельный модуль MS-DOS. Этот модуль может быть заменен на другой, более удобный. Предназначен для приема команд с клавиатуры или из *.bat - файлов и их выполнения; выполнения команд файла Autoexec.bat при загрузке MS-DOS; загрузки в ОЗУ и запуск на выполнение прикладных программ в среде MS-DOS.Командный процессор состоит из 3-х частей : резидентной (размещается в ОЗУ сразу после MSDOS.SYS, включает процедуры обслуживания некоторых прерываний, процедуры обработки стандартных ошибок MS-DOS, процедуру загрузки транзитной части командного процессора); инициализирующей (в ОЗУ следует сразу за резидентной частью; во время загрузки OС ей передается управление; она выполняет файл Autoexec.bat и некоторые другие действия; эта часть командного процессора стирается из ОЗУ первой же загруженной программой); транзитной (загружается в старшие адреса ОЗУ; обрабатывает все внутренние команды, команды с клавиатуры и из *.bat-файлов; выдает системную подсказку MS-DOS; загружает в ОЗУ программы и передает им управление). Внешние команды (программы)Дополнительные программы, входящие в MS-DOS, выполняющие определенные функции.Драйверы устройствСпециальные резидентные программы, которые управляют внешними устройствами. Драйверы загружаются в ОЗУ в том порядке, как они указаны в файле CONFIG.SYS.Файл CONFIG.SYSСпециальный текстовый файл, где содержится информация о подгружаемых дополнительных драйверах и некоторая другая информация, касающаяся непосредственно MS-DOS и выполняемых в ее среде прикладных программ. MS-DOS выполняет этот файл автоматически, сразу после загрузки COMMAND.COM.Файл AUTOEXEC.BATСпециальный текстовый файл, в котором содержится дополнительная настроечная информация. MS-DOS выполняет этот файл автоматически, сразу после выполнения файла CONFIG.SYSНачальная загрузка MS-DOS 1. При включении ПК вначале выполняются программы BIOS.2. После тестирования оборудования и выполнения других действий процедура POST (из модуля BIOS) осуществляет поиск и загрузку блока начальной загрузки по следующему алгоритму: вначале производится поиск на устройстве A:. Если блок не найден, то поиск выполняется на устройстве C:. Если снова поиск не завершился успешно, то вызывается встроенный в ПЗУ BASIC или производятся  другие действия, записанные в ПЗУ.3. Блок начальной загрузки производит поиск в корневом каталоге  системной дискеты (диска) файлов IO.SYS и MSDOS.SYS (эти файлы должны быть первыми и именно в таком порядке).4. Блок начальной загрузки производит загрузку файла IO.SYS и передает ему управление.5. Файл IO.SYS выполняет следующие действия: загружает и настраивает MSDOS.SYS; определяет состояние подключенных устройств; инициализирует подключенные устройства; загружает необходимые драйверы устройств; передает управление файлу MSDOS.SYS. 6. Файл MSDOS.SYS выполняет следующие действия: инициализирует (настраивает) свои внутренние рабочие таблицы; загружает драйверы, указанные в файле CONFIG.SYS; загружает командный процессор (файл COMMAND.COM). 7. Командный процессор выполняет команды, указанные в файле Autoexec.bat.8. Командный процессор выдает на экран монитора системную подсказку  MS-DOS и ожидает ввода команд пользователя.Файловая система MS-DOS Файл  (по-английски file – папка, скоросшиватель) – это поименованная область памяти на каком-либо физическом носителе, предназначенная для хранения информации.Совокупность средств MS-DOS, обеспечивающих доступ к информации на внешних носителях, называется системой управления файлами, или файловой системой.Одно из понятий файловой системы MS-DOS – логический диск. В некотором приближении можно считать, что с точки зрения MS-DOS каждый логический диск – это отдельный магнитный диск. Каждый логический диск имеет своеуникальное имя.В качестве имени логического диска используются буквы английского алфавита от A до Z (включительно). Таким образом, количество логических дисков, может быть не более 26.Буквы A и B – отведены строго под имеющиеся в IBM PC дисководы.Начиная с буквы C именуются логические диски (разделы) жесткого диска (рис. 2.23).В случае, если данный IBM PC имеет только один FDD, буква B пропускается (см. рис. 2.24).Как правило, только логические диски A и C могут быть системными.

Файловая структура логического диска

Раздел 3 Основные принципы программирования

3.1. Этапы подготовки и решения задач на ЭВМ

3.2. Алгоритмы и способы их описания

3.3. Компиляция и интерпретация программ

3.4. Стили программирования

3.1 Этапы подготовки и решения задач на ЭВМ

3.2 Алгоритмы и способы их описания

3.3. Компиляция и интерпретация программ

3.4. Стили программирования

Раздал 6 Структуры данных

Раздел 7 Файлы данных

Раздел 8 Подпрограммы

Раздел 9 Объектно-ориентированное программирование

9.1. Описание класса

9.2. Описание объектов

9.4. Наследование

9.5. Иерархия классов

9.6. Виртуальные методы. Полиморфизм.

9.7. Контейнерные классы

Методы класса При вызове методов необходимо связать метод с объектом этого класса [2]. Поэтому имена объектов ( p ) связаны с именем функции (метода) операцией точка (.):p.InitPoint(10,10);p.relmove(5,10); Замечание: Это напоминает доступ к полям структуры.Вызов методов InitPoint() и relmove() приводило к изменению значений полей x и y. В следующем примере задание значений полей в методе Vvod() будет осуществляться с клавиатуры: class TPoint { private: int x,y;public: void InitPoint ( int newx, int newy) { x = newx;y = newy ;} void Vvod(){std::cout<<"Vvedi X Y:";std::cin>> x >> y;}. . . };Вставим вызов этого метода в главную программу: int main(){ TPoint p;// описание объектаp.Vvod();std::cout<<"x="<< p.getx()<<",\ty="<< p.gety()<<"\n"; return 0;} Результаты работы программы приведены на рисунке 9.2. Рисунок 9.2 – Результат использования метода Vvod()Конструкторы'>КонструкторыB отличии от предыдущего примера удобнее инициализировать поля объекта автоматически в момент его создания, а не явно, вызовом соответствующего метода. Такой способ реализуется с помощью особого метода класса, называемого конструктором.Конструктор - это метод, выполняющийся автоматически в момент создания объекта.Конструктор отличается от других методов: Имя конструктора совпадает с именем класса; У конструктора не существует возвращаемого значения. Заменим метод InitPoint() на конструктор:class TPoint { private: int x,y;public:TPoint(int newx, int newy) // конструктор {x=newx;y=newy; } void relmove ( int dx, int dy ) {x+= dx; y += dy ; } int getx ( void ) { return x ; }int gety ( void ) { return y ; } };int main(int argc, char *argv[]){ TPoint p(10,10); //инициализация объекта р std::cout<<"x="<< p.getx()<<",\ty="<< p.gety()<<"\n"; . . .}В качестве второго примера создадим класс Counter, объекты которого могут хранить количественную меру какой-либо изменяющейся величины. При наступлении некоторого события счетчик увеличивается на единицу. Обращение к счетчику происходит, как правило, для того, чтобы узнать текущее значение той величины, для изменения которой он предназначен.#include "stdafx.h"#include "iostream"class Counter{ private: int count;public: Counter ( ):count(0){ } //конструктор void inc_count ( )//метод увеличения счетчика на 1{count++; }int get_count( )//метод возвращает значение счетчика{ return count; }};int _tmain(int argc, _TCHAR* argv[]){ Counter c1, c2;//создание объектов c1 и c2std::cout<std::cout<c1.inc_count(); c1.inc_count(); //увеличение с1 на 2c2.inc_count(); //увеличение с2 на 1std::cout<std::cout<return 0;}Результаты программы приведены на рисунке 9.3. Рисунок 9.3. – Результаты работы программыОдной из наиболее часто возлагаемых на конструктор задач является инициализация полей объекта. Инициализация полей обычно реализуется с помощью списка инициализации, который располагается между заголовком и телом функции-конструктора. После заголовка ставится двоеточие. Инициализирующие значения помещены в круглые скобки после имени поля.Counter ( ):count(0) {/* тело функции*/ } Если инициализируются несколько полей, то значения разделяются запятыми.ДеструкторыКроме специального метода конструктор, который вызывается при создании объекта, существует другой особый метод, автоматически вызываемый при уничтожении объекта, называемый деструктором [2].Деструктор имеет имя, совпадающее с именем конструктора, перед которым стоит тильда .class Prim{ private: int dat;public:Prim(): dat(0){ }Prim(){ }}; Наиболее распространённое применение деструкторов – освобождение памяти, выделенной конструктором при создании объекта.Определение методов может быть реализовано как внутри самого класса, так и вне класса. Во втором случае внутри класса содержится лишь прототип функции, а сама функция определяется позже. Тогда перед именем функции указывается имя класса и символ ::Вернемся к примеру класса TPoint. Рассмотрим в этом примере реализацию метода relmove()вне класса и добавим деструктор для класса TPoint.class TPoint { private: int x,y;public:TPoint(int newx, int newy) {x=newx;y=newy; } void relmove ( int dx, int dy ); int getx ( void ){ return x ; } int gety ( void ) { return y ; } Tpoint( ){ }};void TPoint::relmove(int dx, int dy){x+= dx; y += dy ; } ЗАМЕЧАНИЯ:1)Класс может иметь несколько конструкторов с разными параметрами для разных видов инициализации.2)Конструктор, вызываемый без параметров, называется конструктором по умолчанию.3)Деструктор вызывается автоматически, когда объект выходит из области видимости:• для локальных объектов — при выходе из блока, в котором они объявлены;• для глобальных — как часть процедуры выхода из main( );• для объектов, заданных через указатели деструктор вызывается неявно при использовании операции delete. Деструктор:• не имеет аргументов и возвращаемого значения;• не может быть объявлен, как const или static;• не наследуется;• может быть виртуальным.Вернемся ко второму примеру, где был создан класс Counter. При решении разных задач может возникнуть необходимость инициализации счетчика разными значениями, а не только нулем. Для этого создадим еще один конструктор:class Counter{ private: int count;public:Counter ( ):count(0)//конструктор, инициализирующий нулем { }Counter (int c): count(c)//конструктор задает любое нач. значение{ } void inc_count ( ) {count++; } int get_count( ){ return count; }

Наследование

Потоковый вывод


Для начинающих программистов организация потокового вывода числовой информации на стандартное устройство вывода экран (stdout) представляется более простой:

#include

int main()

{ int i;

float f;

double d;

..........

cout << i+1 << f << f*d;

Здесь на первых порах не надо заботиться о форматах выводимых результатов. Для каждого типа данных существуют соответствующие системные соглашения. Переход в начало следующей строки здесь осуществляется путем включения в список вывода признака конца строки endl, например:

cout << i+1 << endl << f << f*d;

В таком случае значения переменных f и f*d будут выведены на новую строку.

Форматный вывод


Форматный вывод числовых результатов на стандартное устройство вывода (stdout), которым по умолчанию является экран дисплея, осуществляется с помощью функции printf. Например:

#include

int main()

{ int i;

float f;

double d;

..........

printf("%d %f %lf", i+1, f, f*d);

Ее аргументы напоминают по форме обращение к функции scanf с той лишь разницей, что список вывода составляют не адреса переменных, а арифметические выражения, значения которых предварительно будут подсчитаны, а потом выведены в соответствии с использованными форматными указателями. Выражения и имена переменных в списке перечисляются через запятую. В качестве простейших выражений могут быть константы, переменные, символы, строки.

Работа операторов вывода

Операторы вывода преобразуют значения переменных и вычисленные значения выражений, указанных в списке, из внутреннего представления во внешнее и выводят эти значения на экран.

Для вывода чисел и значений переменных на экран используют функцию printf.

Общий вид записи оператора

printf(“ список форматов”, cnиcoк имен переменных и выражений);

Например:

printf ( "Результат: %d + %d = %d \n", a, b, c );

Содержание скобок при вызове функции printf очень похоже на функцию scanf. Сначала идет символьная строка — форматы вывода, — в которой можно использовать специальные символы

%d - вывод целого числа

%f - вывод вещественного числа

%с - вывод одного символа

%s - вывод символьной строки

\n - переход в начало новой строки

все остальные символы (кроме некоторых других специальных команд) просто выводятся на экран.

В символьной строке мы сказали компьютеру, какие данные (целые, вещественные или символьные) надо вывести на экран, но не сказали откуда (из каких ячеек памяти) их брать. Поэтому через запятую после форматов вывода надо поставить список чисел или имен переменных, значения которых надо вывести, при этом можно сразу проводить вычисления.

printf ( "Результат: %d + %d = %d \n", a, 5, a+5 );

Так же, как и для функции scanf, надо следить за совпадением типов и количества переменных и форматов вывода.

Пример вывода:

Операторы

printf(“Выходные данные:\n”);

printf(“'K=%d y=%f”, 8+5, 7./10);

выводят на экран результаты в следующем виде:

Выходные данные:

К=13 у=0.7

Управление выводом данных

При стандартной форме вывода вещественные числа отображаются на экране с порядком. Мантисса выводится в нормализованном виде, т.е. с одной значащей цифрой в целой части и десятью цифрами в дробной части. На порядок отводится четыре позиции: первая позиция - под букву Е, вторая позиция - под знак порядка, третья и четвертая позиции - под цифры порядка.

Если программиста не устраивает стандартная форма вывода, то он может использовать форматированный вывод, предусмотренный в системе Турбо Си. При форматированном выводе чисел используются два формата.

  1. Ширина поля, определяющая число позиций на экране, отводимых для вывода всего числа, включая целую, дробную час­ти, знак и десятичную точку.

  2. Точность представления вещественного числа, опреде­ляющая число позиций в дробной части.

Вещественное число с указанием форматов всегда выводится в десятичной форме. Для целого числа используется только фор­мат ширины поля.

В операторах вывода форматы записываются после знака % и отделяются друг от друга точкой. На­пример, при записи оператора

printf(“K=%3d у=%5.2f”,8+3,7./10);

результаты отображаются на экране в следующем виде:

К= 11 у = 0.70

В приведенном примере форматы 3 и 5 задают ширину поля, формат 2 - точность выводимого числа, т.е. значение выражения 7./10 выведено на экран с двумя значащими цифрами после запятой.

4.6 Структура основной программы

Простейшая программа на Си

Такая программа состоит всего из 12 символов, но заслуживает внимательного рассмотрения. Вот она:

void main()

{

}

Основная программа в Си всегда называется именем main (будьте внимательны - Си различает большие и маленькие буквы, а все стандартные операторы Си записываются маленькими буквами). Пустые скобки означают, что main не имеет аргументов, а слово void (пустой) говорит о том, что она также и не возвращает никакого значения, то есть, является процедурой.

Фигурные скобки обозначают начало и конец процедуры main - поскольку внутри них ничего нет, наша программа ничего не делает, она просто соответствует правилам языка Си, ее можно скомпилировать и получить exe-файл.

Составим теперь программу, которая делает что-нибудь полезное, например, выводит на экран слово «Привет».

#include

void main()

{

printf("Привет");

}

Что новенького?

Перечислим новые элементы, использованные в этой программе:

Чтобы использовать стандартные функции, необходимо сказать транслятору, что есть функция с таким именем и перечислить тип ее аргументов - тогда он сможет определить, верно ли мы ее используем. Это значит, что надо подключить описание этой функции.

Описания стандартных функций Си находятся в так называемых заголовочных файлах с расширением *.h (в каталоге C:\BORLANDC\INCLUDE)

Для подключения заголовочных файлов используется директива (команда) препроцессора "#include", после которой в угловых скобках ставится имя файла заголовка. (Препроцессор - это специальная программа, которая обрабатывает текст вашей программы раньше транслятора. Все команды препроцессора начиняются знаком "#"). Внутри угловых скобок не должно быть пробелов. Для подключения еще каждого нового заголовочного файла надо использовать новую команду "#include".

Для вывода информации на экран используется функция printf. В простейшем случае она принимает единственный аргумент - строку в кавычках, которую надо вывести на экран.

Каждый оператор языка Си заканчивается точкой с запятой.

В программу могут быть включены комментарии - тексты,
поясняющие программу. Комментарии – обязательная принадлежность каждой программы. Описание нетривиального алгоритма, как правило, снабжается пояснениями, которые помогут разобраться в тексте программы персоналу сопровождения программных продуктов. Наконец, отключение части программы путем перевода ее в разряд комментариев – наиболее употребительный прием отладки программ. В языке Си предусматривается две разновидности комментариев – многострочные и однострочные.

Однострочный комментарий начинается вслед за парой символов "//" и продолжается до конца программной строки. Обычно с его помощью записывается комментарий к текущей строке или исключается фрагмент текущей строки из области обслуживания. Комментарии, заключенные в /* */ и записываются в любом месте программы и могут располагаться на нескольких строках.

Пример линейной программы

Составить программу вычисления площади треугольника по

формуле:

где - полупериметр; а,b,с -стороны треугольника.

Исходные данные: а = 1; b= 2; с = 0,5.

#include

#include

#include

main()

{ clrscr();

float a, b, c, p, S;
printf(“Введите исходные данные ”);

scanf(“%f%f%f”,&a, &b,&с);

p = (a + b + c) / 2;

S = sqrt(p * (p - a) * (p -b) * (p - c));

/*Вывод на экран*/

printf(“Площадь треугольника S =%5.2f”, S);

}

При выполнении оператора scanf программа останавливается и переходит в режим ожидания набора исходных данных с кла­виатуры. В этот момент надо набрать на клавиатуре:

1 2 0.5 [Enter]

После нажатия клавиши [Enter] программа продолжает вы­полнение и выведет результат на экран в следующем виде:

Площадь треугольника S = 3.87
4.7 Разветвляющиеся вычислительные процессы

Вычислительный процесс называется разветвляющимся, если он реализуется по одному из нескольких направлений - ветвей. В программе должны быть учтены все возможные ветви вычисле­ний. Выбор той или иной ветви осуществляется по условию, включенному в состав условного оператора. Для программной реализации условия используется логическое выражение. В сложных структурах с большим числом ветвей применяют опера­тор выбора.

4.7.1. Логические выражения

Логические выражения строятся из операндов, отноше­ний, логических операций и круглых скобок.

Результатом вычисления логического выражения является одно из двух логических значений: TRUE(истина)(1) или FALSE(ложь)(0).

В качестве операндов используются константы, переменные и функции логического типа.

Отношения

Отношение - это простейший вид логического выражения, состоящего из двух выражений арифметического, символьного или строкового типов, соединенных знаком операции отношения.

Операция отношения - это операция сравнения двух опе­рандов:

< - меньше

<= - меньше либо равно

>- больше

>= - больше либо равно

= = - равно

!= не равно.

Примеры записи отношений на языке Си

Отношение

Результат

5>3

TRUE

cos(x)>1

FALSE

х*х+у*у<1

TRUE для всех точек, лежащих внутри круга с единичным радиусом и центром в начале координат

A!=’Y’

TRUE, если значение символьной переменной А не равно символу ’Y’

Следует помнить, что к операндам вещественного типа не применима операция = = из-за неточного представления чисел в памяти компьютера. Поэтому для вещественных переменных а и bотношение вида а= =b надо заменить отношением abs(a-b)Е - малая величина, определяющая допустимую погрешность.

Логические операции

Математическая запись

Запись на языке Си аскаль

Название операции

¬

!

Отрицание



&&

Операция «И» (логиче­ское умножение)



||

Операция «ИЛИ» (ло­гическое сложение)


Действия логических операций удобно задать таблицами ис­тинности, в которых приняты следующие обозначения: a, b - ло­гические операнды; Т - TRUE, F - FALSE.


а

! a

Т F

F Т



а

b

a && b

Т

Т

Т

Т

F

F

F

Т

F

F

F

F

а

b

a || b

Т

Т

Т

Т

F

Т

F

Т

Т

F

F

F


Порядок выполнения операций в логических выражениях

В бесскобочных логических выражениях операции выполня­ют слева направо в соответствии с их приоритетом:

  1. !

  2. &&

  3. ||

  4. Отношения.

Поскольку отношения имеют самый низкий приоритет, то их необходимо заключать в круглые скобки.

Пример. Вычислить логическое выражение:

(-3≥5) ¬(7<9) (0≤3)

Запись на языке Си имеет вид:



(-3>= 5) || ! (7 <9) && (0 <= 3)

1 6 4 2 5 3

Внизу под операциями проставлен порядок выполнения действий.

1) -3>= 5=>F;2) 7 <9 => Т; 3) 0 <= 3 => Т;

4) !(T) -> F; 5) F && T=>F; 6) F || F => F.

Ответ: FALSE.

Примеры записи логических выражений

Записать на языке Си логические выражения, реализующие следующие условия:

a) переменная х принадлежит интервалу [а, b].

Ответ: (х>= a) && (x <= b)

б) переменная х не принадлежит интервалу [а, b].

Ответ: Данное условие можно записать в одном из двух ва­риантов:

1) (х <а) || (x> b);

2)воспользоваться операцией отрицания:

! ((x>= a) && (х <= b))

4.7.2. Условные операторы

На языке Си различают два вида условных опе­раторов: короткий и полный.

Короткий условный оператор

Общий вид записи

if (логическое выражение) P;

где Р - любой оператор.

Работа оператора

Сначала вычисляется логическое выражение (ЛВ), и если оно имеет значение TRUE, то выполняется оператор Р, стоящий за логическим выражением. В противном случае оператор Р игнори­руется.

Графическая интерпретация оператора

В схемах алгоритма короткому условному оператору соответству­ет структура ЕСЛИ—ТО.

Замечание. По определению, конструкция короткого услов­ного оператора включает единственный оператор Р. Если в задаче по заданному условию требуется выполнить несколько операто­ров, то их необходимо заключить в скобки { }, образуя тем самым единый составной оператор. То­гда запись условного оператора с использованием скобок имеет следующий вид:

if (логическое выражение)
{

Составной оператор

}
П ример. Переменной у присвоить минимальное значение из трех различных чисел, т.е. у = min(a, b, с).

Программа

#include

#include

#include

main()

{ clrscr();

float a, b, c,y;

printf(“ Вве д ите числа а, b, с”);

scanf(“%f%f%f”, &a,& b,& с);

у=а;

if (b
if (c
printf(“y =%6.2f”, y);

}

Полный условный оператор

Общий вид записи

if (логическое выражение) P1; else P2;

где Р1, Р2 - любые операторы или даже группы операторов.

Работа оператора

Вычисляется логическое выражение, и если оно имеет значе­ние TRUE(1), то выполняется оператор Р1, стоящий после логического выражения. В противном случае (FALSE (0))оператор P1 пропускается, а выполняется оператор Р2, стоящий после служебного слова else.

Графическая интерпретацияоператора

В схемах алгоритма полному условному оператору соответствует структура ЕСЛИ-ТО-ИНАЧЕ.


Замечание. Операторы Р1 и Р2 входят в конструкцию полного условного оператора как единственные. Если возникает не­обходимость выполнить в ветвях несколько операторов, то их за­ключают в операторные скобки { }. Вид записи условного оператора в этом случае следующий.

if (логическое выражение)

{

оператор 1;

………………

оператор n;

}

else

{

оператор 1;

………………

оператор m;

}

Пример 1. Вычислить значение переменной у по одной из двух ветвей:



Схема алгоритма Программа

#include

#include

#include

main()

{

float a, b, c,y;

printf(“ В ве д ите число x”);

scanf(“%f”,&x);

if( x>0) у = log(х)

else у = ехр(х);

printf('y =%6.2f”, у);

}

Пример 2. Вычислить корни полного квадратного уравнения

ах2 + bх + с = 0.

В программе предусмотреть проверку дискриминанта на знак. Если дискриминант окажется отрицательным, то вывести сообщение «Корни мнимые».

#include

#include

#include

main()

{

float a, b, с, d, xl, x2; // описание переменных

printf(“Введите коэффициенты уравнения ”);

scanf(“%f%f%f”,&a, &b, &с); // ввод исходных данных

d = pow(b,2)-4*a*c; //вычисление дискриминанта

if ( d<0 ) // сравнение дискриминанта с нулем

printf (“Корни мнимые”); /*вывод «корни мнимые», если d окажется < 0 */

else // иначе

{

x1=(-b+sqrt(d))/(2*a); // вычисление первого корня

x2=(-b-sqrt(d))/(2*a); // вычисление второго корня

printf(“x1=%f x2=%f”,x1,x2); // вывод корней на экран

}

}

Вложенные структуры условных операторов

Структура называется вложенной, если после служебного слова else или при истинности логического выражения вновь используются условные операторы. Число вложений может быть произвольным. При этом справедливо сле­дующее правило: служебное слово else всегда относится к ближайшему выше слову if. Для удобства чтения вложен­ных структур при программировании рекомендуется избегать по возможности записи вложенного условного оператора.

Пример. Вычислить значение у по одной из трех ветвей:



При решении данной задачи возможны два варианта про­граммирования: 1) без вложенной структуры; 2) с вложенной структурой. Ниже рассмотрены оба варианта решения задачи.

Вариант 1 (с использованием вложенной структуры)

Схема алгоритма Программа

#include

#include

#include

main()

{ clrscr();

float х, у;

printf(“Введите число х”); scanf(“%f”,&x);

if (х>=1)

у = sqrt(x)/2;

else

if(x>0)

y=pow(x,1./3)/2;

else

y=pow(x,l./4)/4;

printf(“y=%6.2f”,y);

}


Вариант 2 (без использования вложенной структуры)

Схема алгоритма Программа



#include

#include

#include

main()

{

float х, у;

printf(“Введите число х”);

scanf(“%f”,&x);

if (х>=1) у = sqrt(x)/2;

if(x>0) y =pow(x,l/3)/2;

if(x<=0) y=pow(x,l./4)/4;

printf(“y=%6.2f”,y);

}

4.7.3. Оператор выбора

При многократном вложении условных операторов программа становится громоздкой и ее трудно понять. Считается, что число вложений не должно превышать двух-трех. При большем числе вложений рекомендуется использовать оператор выбора switch-case.

Общий вид записи оператора

switch <селектор>

{

сase константа выбора 1: оператор 1; break;

…………………………………………………

сase константа выбора n: оператор n; break;

default:

}

Селектор - это выражение целого или символьного типа.

Константы выбора - всевозможные значения селектора.

default – предусматривает обработку непредусмотренного значения селектора.

Работа оператора

По вычисленному значению селектора выбирается для испол­нения case-оператор той строки, у которого содержится кон­станта выбора, равная значению селектора. После выполнения выбранно­го case-оператора управление передается на конец оператора case. Следующим в программе выполняется оператор, стоящий за опе­ратором выбора switch.

Пример 1. Написать оператор выбора для вычисления величи­ны y по формулам:



Оператор выбора имеет следующую запись:

switch (n)

{

case 1: у =х; break;

case 2: case 3: у = 2 * sqrt(abs(x)); break;

case 4: у = ехр(х); break;

default: printf(“значение для n указано не верно\n”);

}

Графическая интерпретация оператора

В схемах алгоритма оператору switch соответствует структура ВЫБОР.

Для приведенного выше примера 1 эта структура выглядит следующим образом:


Замечание. Если в строке выбора необходимо записать не­сколько операторов, то их заключают в операторные скобки {...}.

Пример 2. Вычислить значение у.



Если значение х не принадлежит рассматриваемым проме­жуткам, то вывести на экран соответствующее сообщение.

В задаче переменная х является вещественной и не может ис­пользоваться в качестве селектора оператора case. Введем новую переменную целого типа n, которой присваивается целая часть значения х. Тогда программа решения данной за­дачи с использованием оператора выбора может быть составлена следующим образом.

#include

#include

#include

main()

{ clrscr(); /* очистка экрана */

float х, у;

int n;

printf(“Введите число х ”);

scanf(“%f”,&x);

if (х<1) || (x>=5)

printf(“x не принадлежит рассматриваемой области\n”);

else

{ n = x;

switch (n)

{

case l: y =sin(x); break;

case 2: у = exp(-x); break;

case 3: y =log(x); break;

case 4: у = tan(x); break;

default: printf(“ такого решения не предусмотрено\n”); break;
}

if (n= =1)||(n= =2)||(n= =3)||(n= =4) printf(“y=%6.2f”, y);

}

}

4.8 Циклические вычислительные процессы

Циклические вычислительные процессы характеризуются наличием многократно повторяющихся участков вычислений (циклов). Переменная, изменяющаяся в цикле, называется управляющей переменной. Для программирования циклических задач используются операторы цикла с условием или с параметром.

4.8.1. Операторы цикла с условием

В языке Си имеется два вида операторов цикла с условием:

  1. оператор цикла while (пока);

  2. оператор цикла do... while (повторять до тех пор, пока).

Оператор цикла while является наиболее универсальным, так как с его помощью можно запрограммировать практически любой циклический процесс.

Оператор цикла while

Общий вид записи

while (логическое выражение) { <тело цикла>; }

<тело цикла> - единичный оператор или группа операторов, выполняемых в цикле.

Замечание.Если тело цикла состоит из нескольких операторов, то их обязательно заключают в операторные скобки {...}.

Работа оператора

Тело цикла выполняется, пока логическое выражение, определяющее условие выхода из цикла, имеет значение TRUE. В противном случае оператор цикла while завершает свою работу.

В состав логического выражения входит управляющая переменная, которая должна изменяться в теле цикла. Перед началом работы оператора определяется начальная установка управляющей переменной.

Графическая интерпретация оператора

В схемах алгоритма оператору цикла while соответствует структура ЦИКЛ-ПОКА.


Оператор цикла do...while

Общий вид записи

do

{

<тело цикла>;

} while (логическое выражение);

Работа оператора
Выполняется тело цикла, после чего вычисляется логическое выражение, определяющее условие выхода из цикла. Если логическое выражение примет значение FALSE, то цикл do...while завершает свою работу.

Управляющая переменная, как и в случае оператора цикла while должна включаться в состав логического выражения и изменяться в теле цикла. Перед началом работы оператора также производится начальная установка управляющей переменной.

Графическая интерпретация оператора
В схемах алгоритма оператору цикла do... while соответствует структура ЦИКЛ-ДО.

Пример 1.Алгоритм расчета значений функции с одной переменной.

Вычислить таблицу значений функции:



для всех х, изменяющихся в интервале [-0.5,2.5] с шагом Δх = 0.1,

а, b - заданные вещественные числа.
В данной задаче переменная х является управляющей пере­менной цикла.

Схема алгоритма Программа

#include

#include

#include


main()

{

clrscr(); /* очистка экрана */

float а, b, х, у;

printf”'Bвeдитe исходные данные”);

scanf(“%f%f”,&a,&b);

printf(“ x y(x)\n”);

х=-0.5;

while(х <= 2.5)

{

y= log(abs(x))/(a*a +b*b);

printf(“%8.1f %8.1f”,x,y);

x=x + 0.1;

}

}

Пример 2.Решить предыдущую задачу табулирования функции с использованием оператора цикла do…while.

Схема алгоритма Программа

#include

#include

#include

void main()

{

clrscr(); /*очистка экрана */

float а, b, х, y;

printf(“Bвeдитe исходные данные “);

scanf(“%f%f”,&a,&b);

printf(“ x y(x)\n”);

х=-0.5;

do

{

y=log(abs(x))/(a*a-b*b);

printf(“%8.1f %8.1f\n”,x,y);

x= x+ 0.1;

} while( x<= 2.5);

}
Основные отличия оператора цикла whileот оператора цикла do...while

1. В операторе while тело цикла может не выполниться ни разу, если логическое выражение в начальный момент окажется ложным.

В операторе do...while логическое выражение записывается после тела цикла, поэтому тело цикла обязательно выполнится хотя бы один раз.

4.8.2. Операторы цикла с параметром

Общий вид записи

for( i = ml; i<= m2; i=i+шаг)

{ <тело цикла>;}
i - параметр, управляющий работой цикла;

ml, m2 - выражения, определяющие соответственно начальное и конечное значения параметра цикла.

Замечание.Тело цикла состоит по стандарту из одного оператора. В случае выполнения в цикле нескольких операторов надо воспользоваться обязательно операторными скобками {...}.

Работа оператора цикла for...

Тело цикла выполняется для каждого значения параметра i, начиная от ml до конечного значения m2. После каждого шага выполнения цикла значение параметра i автоматически увеличивается на шаг(шаг – это любое число).

Графическая интерпретация оператора цикла for...

В схемах алгоритма оператору цикла for..., как и в случае цикла while, соответствует структура ЦИКЛ-ПОКА.

Однако, из-за особенностей работы оператора и его широко­го применения при программировании задач обработки массивов данных, для оператора for... имеется специальная структура следующего вида:

Замечание 1. Оператор цикла for...допускает применение любого шага для изменения своего параметра.

Правила использования операторов цикла с параметром

  1. Параметр цикла i, а также его значения ml и m2 могут быть любого типа.

  2. Параметр i, а также значения ml и m2 не должны пере­определяться (менять значения) в теле цикла. При завершении работы оператора па­раметр i становится неопределенным и переменную i можно использовать в других целях.

  3. Тело цикла может не выполниться ни разу, если m1>m2 для цикла for... с положительным шагом, или m1

Замечание 2.Оператор цикла while, как указывалось выше, наиболее универсальный из трех операторов цикла, используе­мых в языке Си. Однако конструкция оператора цикла for является наиболее простой. Поэтому рекомендуется там, где возможно, использовать оператор for.

4.9 Базовые алгоритмы

Для реализации циклических вычислительных процессов в большинстве случаев используются следующие базовые алгоритмы:

  • табулирование функций;

  • организация счетчика;

  • накопление суммы или произведения;

  • поиск минимального или максимального члена последо­вательности.

Ниже приводятся примеры программирования задач на осно­ве базовых алгоритмов.

Задача 1.Алгоритм организации счетчика

Дана последовательность:

cos 1, cos 3, cos 5, ..., cos 99.

Определить количество положительных членов последова­тельности.

Решение

Представим последовательность в общем виде:

а = cos(2n -1), где п = .

Для организации счетчика в памяти компьютера выделяется ячейка, содержимое которой должно увеличиваться на 1 каждый раз, когда встречается положительный член последовательности. В программе ячейке (счетчику) соответствует переменная целого типа, например переменная L. Работа счетчика реализуется с по­мощью оператора присваивания L=L+1;. В начальный момент содержимое ячейки должно быть равно нулю. С этой целью пред­варительно осуществляется очистка ячейки оператором присваи­вания L=0;.

#include

#include

#include

void main()

{

clrscr(); // очистка экрана

float a;

integer n,L; // описание переменных

L=0; // очистка счетчика

for ( n = 1; n<= 50; n++) // запуск цикла

{

a = cos(2*n - 1);

if(a>0) L = L + 1 // тело цикла

}

printf(“L=%d”, L); // вывод значения счетчика

}
Задача 2.Алгоритм накопления суммы

Дана последовательность:

sin 2x, sin 4x, sin 6x, ..., sin l6x

x - заданное вещественное число.

Вычислить сумму членов последовательности, которые по модулю больше 0.3.

Решение

Общий член последовательности имеет вид:

а = sin(2nx), где n = .

Для вычисления суммы в памяти компьютера выделяется ячейка S, к содержимому которой прибавляется член последовательности а каждый раз, когда выполняется условие > 0.3. Накопление суммы реализуется оператором присваивания S=S+a;. В начальный момент ячейка для суммирования должна быть очищена оператором S=0;.

#include

#include

#include

void main()

{

clrscr();

float a, x, S;

integer n;

printf(“Введите значение х= ”);

scanf(“%f”,&x);

S=0;

for( n = 1; n<= 8; n++)

{ a = sin(2*n*x);

if ( abs(a)>0.3) S = S + a;

}

printf(“S=%6.2f”, S);

}

Задача 3.Алгоритм накопления произведения

Дана последовательность:

cos 0.1, cos 0.2, cos 0.3, ..., cos 10.

Вычислить значение: Р где РО - произведение отри­цательных членов последовательности.

Решение

Общий член последовательности имеет вид:

y = cos x, где 0.1 10; Δх = 0.1.

Для реализации алгоритма накопления произведения выделяется ячейка памяти РО, в которой осуществляется последова­тельное перемножение отрицательных членов последовательно­сти с помощью оператора присваивания РО=РО*у; . В началь­ный момент в ячейку должна быть занесена единица оператором РО=1;.

#include

#include

#include

void main(0

{

clrscr();

float х, у, Р, РО;

РО = 1;

for (x=0.1; x<=10; x=x+0.1)

{

у = cos(x);

if ( y<0) РО = РО*у;

}

Р = abs(PO);

printf(“P=%6.2f”,P);

}

Задача 4.Алгоритм поиска минимального члена после­довательности

Дана последовательность:

ak=ektg(2k + l); к= .

Найти минимальный член последовательности.

Решение

Для реализации алгоритма выделяется ячейка памяти min, в которую сначала заносится первый член последовательности. Затем, начиная со второго, производится сравнение очередного вычисленного члена последовательности с содержимым ячейки min. Если текущий член последовательности меньше содержимого ячейки min, то oн переписывается в эту ячейку. В противном случае содержимое ячейки min сохраняет прежнее значение. При завершении сравнения всех членов последовательности в ячейке min остается минимальное значение.

Замечание 1. Алгоритм поиска максимального члена последовательности

отличается от поиска минимального члена лишь тем, что в ячейке (ей можно дать, например, имя max) запоминается больший из сравниваемых членов последовательности.

Замечание 2. В начальный момент в ячейку min можно занести не первый член последовательности, а достаточно большое число, которое превышало бы область определения сравниваемых чисел (например, min=+1E6;). Тогда при сравнении с содержимым ячейки min первый член последовательности обязательно окажется меньше и перепишется в ячейку min. При поиске максимального члена последовательности в ячейку max в начальный момент заносится, наоборот, достаточно малое число, которое должно быть меньше всех сравниваемых членов последовательности (например, mах= -1Е6;). В этом случае первый из сравниваемых членов последовательности окажется больше содержимого ячейки max и переписывается в эту ячейку.

#include

#include

#include

void main()

{

clrscr();

float a, min;

int k;

min = +1E6;

for( k=l; k<=10; k++)

{

a = exp(k)*tan(2*k + 1);

if (a
}

printf(“min=%6.2f”, min);

}
Задача 5. Табулирование функции (или кратные циклы)

Тело цикла может содержать любой оператор, в том числе и другой оператор цикла. Структура цикла, содержащая вло­женный цикл, называется кратным циклом. Число вложений может быть произвольным. Если цикл содержит один вложенный цикл, то он называется двойным циклом, если содержит два вложенных цикла, то является тройным циклом, и т.д. Цикл, ко­торый содержит вложенный цикл, называется внешним. Вло­женный цикл называется внутренним.

Переменная внутреннего цикла всегда меняется быстрее, чем внешнего. Это означает, что для каждого значения внешней пе­ременной цикла меняются все значения внутренней переменной.

Внешний и внутренний циклы могут использовать любой вид операторов цикла (while, do-while, for).

Пример.Алгоритм табулирования функции с двумя пе­ременными

Вычислить значение функции:

z(x, у) = sin x + cos y

при всех х, изменяющихся на интервале [-1, 1] с шагом Δх = 0.2,

и у, изменяющихся на интервале [0, 1] с шагом Δу = 0.1.

Данный алгоритм реализуется с использованием двойного цикла, в котором х примем за внешнюю переменную цикла, у - за внутреннюю переменную цикла.

#include

#include

#include

void main()

{

clrscr(); // очистка экрана

float х, у, z; // описание переменных

printf(“x y z(x,y)\n”); // вывод заголовка

x=-l; // начальное значение параметра цикла

while (х<=1) // запуск внешнего цикла, если х≤ 1

{

for( y=0; y<=1; y=y+0.1) //запуск внутреннего цикла

{

z=sin(x) + cos(y); // вычисление функции

printf(“%6.1f %6.1f z=%6.1f”,x, y, z); // вывод

}

x=x + 0.2; // изменение параметра х на шаг

}

}

В результате выполнения программы вид таблицы на экране будет следующим:

x


y


z(x,y)

-1.0

0.0

z=-1.0

-1.0

0.1

z=-1.1







-1.0

1.0

z=-0.0

-0.8

0.0

z=-0.8

-0.8

1.0

z=-0.8
0>9>
1   ...   14   15   16   17   18   19   20   21   ...   26


Задача 6. Вычисление сумм последовательностей

Последовательности с заданным числом элементов

Пример 1. Найти сумму первых 20 элементов последовательности

S=1/2 – 2/4 + 3/8 – 4/16+…

Чтобы решить эту задачу, надо определить закономерность в изменении элементов. В данном случае можно заметить:

  • Каждый элемент представляет собой дробь.

  • Числитель дроби при переходе к следующему элементу возрастает на единицу.

  • Знаменатель дроби с каждым шагов увеличивается в 2 раза.

  • Знаки перед дробями чередуются (плюс, минус и т.д.).

Любой элемент последовательности можно представить в виде

S=z*c/d

У переменной z меняется знак (эту операцию можно записать в виде z=-z), значение переменной c увеличивается на единицу (c++), а переменная d умножается на 2 (d=d*2).

Алгоритм решения задачи можно записать в виде следующих шагов:

  • Записать в переменную S значение 0. В этой ячейке будет накапливаться сумма;

  • Записать в переменные z, c и d начальные значения (для первого элемента): z=1, c=1,d=2;

  • Сделать 20 раз следующие две операции:

  • добавить к сумме значение очередного элемента;

  • изменить значения переменных z, c и d для следующего элемента.

#include

#include


Начальные значения
void main()

{ clrscr();

float S, z, c, d;

int i;

S = 0; z = 1; c = 1; d = 2;


добавить элемент к сумме
for ( i = 1; i <= 20; i ++ )

{

S = S + z*c/d;


изменить переменные
z = - z;

c ++;

d = d * 2;

}

printf(“Сумма S = %f”, S);

}

Суммы с ограничивающим условием

Рассмотрим более сложную задачу, когда количество элементов заранее неизвестно.

Пример 2. Найти сумму всех элементов последовательности

S=1/2 – 2/4 + 3/8 – 4/16+…

которые по модулю меньше, чем 0.001.

Эта задача имеет решение только тогда, когда элементы последовательности убывают по модулю и стремятся к нулю. Поскольку мы не знаем, сколько элементов войдет в сумму, надо использовать цикл while (или do - while). Один из вариантов решения показан ниже.

#include

#include


начальные значения
void main()

{ clrscr();


Запустить цикл, если а≥0.001
float S, z, c, d, a;

S = 0; z = 1; c = 1; d = 2;

a = 1;

while ( a >= 0.001 )


добавить элемент к сумме
{

a =abs( c / d);

S = S + z*a;


изменить переменные
z = - z;

c ++;

d = d * 2;

}

printf(“Сумма S = %f”, S);

}
Цикл закончится тогда, когда переменная a (она обозначает модуль очередного элемента последовательности) станет меньше 0.001. Чтобы программа вошла в цикл на первом шаге, в эту переменную надо записать любое значение, большее, чем 0.001.

Очевидно, что если переменная a не будет уменьшаться, то условие в заголовке цикла всегда будет истинно и программа «зациклится».

Контрольные вопросы

  1. Типы данных, применяемые в языке С++.

  2. Запись основных стандартных функций.

  3. Оператор присваивания в языке С++.

  4. Схема простого циклического процесса.

  5. Операторы цикла в языке С++, особенности их использования.

  6. Понятие параметра цикла, тела цикла, управляющих операторов цикла.

  7. Вложенные циклы.

  8. Операторы ввода-вывода.

  9. Управление формой вывода в операторе printf.

  10. Алгоритм вычисления суммы элементов последовательности.

  11. Алгоритм поиска максимального (минимального) элемента последовательности.

  12. Алгоритм определения количества элементов последовательности.

  13. Понятие параметра цикла, тела цикла, управляющих операторов цикла.

  14. Управление формой вывода в операторе printf.

Раздел 5 Типы и структуры данных

    1. Основные структуры данных

Любая программа в процессе работы обрабатывает некоторые данные. По способу представления в памяти компьютера данные можно разделить на две группы: статические и динамические. Статические данные имеют фиксированную структуру, поэтому размер выделенной для них памяти постоянен. Динамические данные изменяют свою структуру в процессе работы программы, при этом объём памяти изменяется. Основные структуры данных представлены в следующей таблице.

Таблица 1 Различные типы данных

Статические

Простые

Перечислимые


Целые

Вещественные

Логические

Символьные

Структурированные

Массивы

Записи

Объединения

Динамические

Списки

Стек

Очередь

Деревья

АВЛ-деревья

Б-деревья
1   ...   15   16   17   18   19   20   21   22   ...   26


Основной характеристикой данных в программировании является тип данных. Любая константа, переменная, выражение, функция всегда относятся к определенному типу. Тип характеризует множество значений, которые может принимать переменная. К простым типам языка программирования относятся целые, вещественные, логические, символьные. Целые типы в языках программирования различаются количеством байт, отведённых в памяти (диапазоном значений) и наличием знака. Вещественные типы характеризуются точностью представления числа. Перечислимые типы образуются в процессе перечисления всех возможных значений. Логический тип является частным случаем перечислимого типа с двумя возможными значениями ИСТИНА и ЛОЖЬ.

Простые типы языка С мы рассмотрели в разделе 4.

5.2 Указатели и массивы

5.2.1. Указатели

Указатель - это переменная, содержащая адрес области памяти. Указатели широко применяются в языке Си. В некоторых случаях без них просто не обойтись, а в некоторых потому, что программы с использование указателей становится короче и эффективнее.

Начнем с того, что поговорим о структуре памяти любого компьютера. Как известно, память компьютера представляет последовательность 8-битовых байтов. Каждый байт пронумерован, причем нумерация начинается с нуля. Номер байта называется адресом. Иногда говорят, что адрес указывает на определенный байт. Таким образом, указатель является просто адресом байта памяти.

Язык Си позволяет определять переменные, которые могут хранить адреса памяти. Такие переменные и называются указателями. Значение указателя сообщает о том, где размещен объект, но ничего не говорит о значении самого объекта.



Присваивая указателю то или иное допустимое значение, можно обеспечить доступ к желаемым данным через этот указатель.

Для описания переменной типа указатель используется символ *.

Формат описания:

Тип *имя;

Указатель всегда указывает на переменную того типа, для которого он был объявлен.

Напимер:

int *x;

char *y;

Пример следует понимать, что x – это указатель на ячейку, в которой хранится целое значение, а y – указатель на однобайтовую ячейку, предназначенную для хранения символа.

Двумя наиболее важными операциями, связанными с указателями, являются операция обращения по адресу * и определение адреса &.


Операция обращения по адресу предназначена для записи или считывания значения, размещенного по адресу, содержащемуся в переменной-указателе.

Например:

int *x;

. . .

*x=5;

Операция определения адреса & возвращает адрес памяти своего операнда. Операндом должна быть переменная.

Напимер:

int *x;

int a=5;

x=&a;

Кроме того, над указателями можно выполнять арифметические операции сложения и вычитания.

Если у – указатель на целое, то унарная операция y++ увеличивает значение адреса, хранящегося в переменной-указателе на число равное размеру ячейки целого типа, т.е. на 2 байта; теперь оно является адресом следующей ячейки целого типа. Соответственно, оператор y-- означает, что адрес уменьшается на 2 байта.

Указатели и целые числа можно складывать. Конструкция у + n (у - указатель, n - целое число) задает адрес n-гo объекта, на который указывает у. Это справедливо для любых объектов (int, char, float и др.); транслятор будет масштабировать приращение адреса в соответствии с типом, указанным в определении объекта.

Любой адрес можно проверить на равенство (= =) или неравенство (!=), больше (>) или меньше (<) с любым другим адресом.

Рассмотрим следующий фрагмент программы:

#include

main()

{

int *x, *w;

int y;

*x=16;

y=-15;

w=&y;

. . .

}

Этот текст можно понимать так:

Выделить память под три переменные x, w, y, где x и w –переменные типа указатель. Оператор *x=16; означает, что в ячейку, адрес которой записан в х, помещается значение 16. Затем переменной у присваивается значение -15. После чего в указатель w записывается адрес переменной y. Синтаксически текст записан правильно. Проблема заключается в том, что указатель х не инициализирован. Описание int *x; приводит к тому, что компилятор резервирует память, необходимую для хранения адреса целой ячейки, но адрес в этой ячейки может быть любой, в том числе и адрес, где хранится полезная информация, например, операционная система. Запись в такую ячейку может привести к сбою в работе компьютера. Поэтому при работе с указателями их надо правильно инициализировать. Существует 4 способа правильного задания начального значения для указателя:

1) Описать указатель глобально, т.е. вне любой функции. При этом указатель будет инициализирован безопасным нулевым адресом. Кроме того любому указателю можно присвоить безопасный нулевой адрес, например:

int *x;

char *y=0;

x=NULL;

Гарантируется, что этот адрес не совпадет ни с одним адресом, уже использованным в системе.

2) Присвоить указателю адрес переменной. Например: w=&y;

3) Присвоить указателю значение другого указателя, к этому моменту правильно инициализированного. Например: x=w;

4) Использовать функции выделения динамической памяти malloc() и calloc(). При использовании этих функция необходимо подключать библиотеку . Рассмотрим пример использования функции malloc():

x=(int*)malloc(sizeof(int));

Приведенный пример означает, что функция выделит область памяти, размер которой определит функция sizeof(). Если вы знаете размер ячейки заданного типа, то можно написать проще: x=(int*)malloc(2);

По окончанию работы программы, память, выделенную функцией malloc() рекомендуется освободить функцией free(x);

И так, вернемся к приведенному ранее фрагменту программы:

#include

main()

{

int *x, *w;

int y;

x=(int*)malloc(sizeof(int));

*x=16;

y=-15;

w=&y;

. . .

}

Теперь никаких конфликтных ситуаций при работе с указателями не возникнет.

5.2.2. Понятие массива

Массив представляет собой упорядоченное множества однотипных элементов. В языке Си массив описывается переменной сложной структуры. При описании массива необходимо указать:

  • способ объединения элементов в структуру (одномерный, двухмерный и т.д. массивы);

  • число элементов;

• тип элементов.

Общий вид описания массива

<тип элементов> имя [число элементов];

Доступ к каждому элементу массива осуществляется с помощью индексов. Индексы задают порядковый номер элемента, к которому осуществляется доступ. В языке Си первый элемент массива имеет индекс ноль. Число индексов определяет структуру массива: если используется один индекс, то такой массив называется одномерным, если два индекса - двухмерным, и т.д. В общем случае размерность массива может быть произвольной.

5.2.3. Одномерные массивы

В математике одномерному массиву соответствует n-мерный вектор, например:

; i = 1, n,

где х, - компонента (координата) вектора;

i- номер компоненты;

п - число компонент.

Описание одномерного массива

На языке Си описание одномерного массива задается следующим образом:

<тип элементов> <имя массива>[размер];

Компилятор отводит под массив память размером (sizeof(тип)*размер) байтов.

Непосредственно при описании можно задать начальные значения массива:

int dat[4]={5,8,-2,11};

float kom[]={3.5,6,-1.1};
Указатели могут обеспечить простой способ ссылок на массив. Имя массива фактически является константой-указателем, ссылающимся на начальный адрес данных (адрес первого элемента массива). Начальный адрес массива определяет компилятор в момент описания массива, и такой адрес не может быть переопределен. Первый элемент массива имеет индекс ноль.

Например:

int Ar[5];

printf (“адрес Ar=%x\n”,Ar);

printf (“адрес Ar=%x\n”,&Ar[0]);

В приведенном фрагменте обе функции printf выводят начальный адрес массива Ar, т.к. выражения Ar и &Ar[0] эквивалентны.

Индексные переменные

Выбор отдельного элемента из массива осуществляется с помощью индексной переменной, которая задается следующим образом:

x[i] - индексная переменная (элемент массива).

Здесь x - имя массива;

i - индекс (номер элемента массива).

В качестве индекса используются:

  • целые константы, например х[2] х2;

  • целые переменные, например х[к] хk;

  • индексные выражения, например х[2*n+1] x2n+1.

Замечание.В языке Си индексы начинаются с нуля. Индексными выражениями являются арифметические выражения целого типа.

Индексная переменная, как и простая; может стоять в левой части оператора присваивания, например:

х[3]=2.5;

Ввод-вывод одномерных массивов

Ввод-вывод массивов осуществляется поэлементно с помо­щью операторов scanf и printf соответственно и оператора цикла for..., в котором в качестве параметра используется индекс.

Пример 1. Организовать ввод с клавиатуры массива:

A = (1.2, 5,-6.8, 14).

Необходимо задать описание массива и индекса.

void main()

{ float A [4] ;

int i;

В программе ввод массива рекомендуется организовать в виде диалога, поместив перед оператором ввода оператор вывода (printf), в котором дается поясняющее сообщение, например:

printf(“Введите массив А\n”);

for( i = 0; i<4; i++)

scanf(“%f”,&A[i]);

В момент работы оператора scanf на клавиатуре через один или несколько пробелов набираются элементы массива (ввод в строке экрана) и нажимается клавиша [Enter]:

1.2 5 -6.8 14 [Enter]

Замечание.Элементы массива можно вводить в «столбик», если после ввода каждого элемента нажимать клавишу [Enter].

Пример 2. Организовать вывод массива А на экран таким образом, чтобы все элементы располагались на одной строке экрана.

В программе надо записать следующие операторы:

for ( i = 0; i<4; i++)

printf(%5.2f “,A[i]);

printf(“\n”);

Вид выводимого массива на экране:

1.2 5.0 -6.8 14.0

Оператор printf(“\n”); без списка служит для перевода курсора к началу следующей строки.

Обработка одномерных массивов

При решении задач обработки массивов используют базовые алгоритмы реализации циклических вычислительных процессов: организация счетчика, накопление сумм и произведений, поиск минимального и максимального элементов массива.

Задача 1. Организация счетчика

Дан целочисленный массив: В = {bi};i= . Определить количество элементов массива, которые делятся на 3 без остатка.

#include

#include

void main()

{

clrscr();

int В [20] ; /* описание массива B*/

int i, L;

printf(“Введите массив В\n”);

for( i =0; i<20; i++)

scanf(“%d”, &B[i]); /* ввод данных в массив с клавиатуры*/

L=0;

for( i =0; i<20; i++)

if (B[i] % 3= = 0) /*проверка элемента на кратность 3*/

L ++;

printf(“Кол-во=%d\n”, L);

}
Задача 2.Накопление суммы и произведения

Дано целое число п и массив вещественных чисел: . Вычислить среднее арифметическое и среднее геометрическое чисел массива, используя формулы:

; .

#include

#include

void main()

{

clrscr();

float X [100];

int n, i;

float S=0, P=1;

printf(“Введите размер массива n= “);

scanf(“%d”,&n);

prinf(“Введите массив X\n”);

for( i = 0; i
scanf(“%f”,&X[i]);

for( i=0; i
{

S = S + X[i]; /* вычисление суммы элементов массива Х */

P =P*X[i]; /* вычисление произведения элементов Х */

}

S = S/n; /* вычисление среднего значения Х */

P=exp(l/n*log(P)); /* вычисление среднего геометрического Х */

printf(“S=%6.2f\n”, S);

printf(“P=%10.2f\n”,P);

}

Задача 3. Поиск минимального и максимального элементов массива

Дан вещественный массив: T = {ti}; i= . Поменять местами минимальный и максимальный элементы массива и вывести массив после обмена.

Решение

В этой задаче для осуществления обмена надо знать не только значения минимального и максимального элементов массива, но и их местоположение. Поэтому во время поиска минимального и максимального элементов необходимо фиксировать их индексы.

Введем обозначения:

min - минимальный элемент;

imin - индекс минимального элемента;

max - максимальный элемент;

imax - индекс максимального элемента.



#include

#include

#include

void main()

{

clrscr();

float Т [10] ; /* описание массива Т */

int i, imin, imax;

float min, max;

printf(“Введите массив Т\n”);

for( i = 0;i<10;i++)

scanf(“%f”,&T[i]);

min =+1E6;

max =-1E6;

for( i = 0; i<10; i++)

{

if (T[i]

{

min = T[i];

imin=i; /* сохранение номера текущего min */

}

If( T[i]>max)

{

max = T[i];

imax = i; /* сохранение номера текущего max */

}

}

T[imin]=max;

T[imax]= min;

for( i= 0; i<10; i++)

printf(“%6.2f “,T[i]);

printf(“\n”);

}

5.2.4. Двухмерные массивы

Двухмерные массивы в математике представляются матрицей:



или сокращенно можно записать: А = , где т - число

строк; n - число столбцов; i,j- индексы (номера) текущих строки и столбца, на пересечении которых находится элемент aij.

Описание двухмерного массива

Описание матрицы задается структурным типом вида:

<тип элементов><имя> [m][ n] ;

где m – количество строк;

n –количество столбцов матрицы.

|По описанию матрицы во внутренней памяти компьютера выделяется область из т п последовательных ячеек, в которые при работе программы записываются значения элементов матрицы. Например, по описанию:

float A [3][5];

В памяти компьютера для элементов матрицы выделяется область, состоящая из 3 5=15 последовательных ячеек вещественного типа. Из описания видно, что матрица состоит из трех строк и пяти столбцов.

Обращение к отдельным элементам матрицы осуществляется с помощью переменной с двумя индексами, причем индексы, как и для одномерного массива начинаются с нуля. Например:

А[i][j] aij;

А[2][3] a23;

А[2*n][k+1] a2n,k+1.

Ввод-вывод двухмерного массива

Для поэлементного ввода и вывода матрицы используется двойной цикл for.... Если задать индекс i как параметр внешнего цикла, а индекс j как параметр внутреннего цикла, то ввод-вывод матрицы осуществляется построчно.

Пример 1.Организовать ввод целочисленной матрицы М по строкам.



Описание матрицы вместе с текущими индексами имеет вид:

void main()

{

int М [2][3] ;

int i, j;

Ввод в программе реализуется в форме диалога, т.е. сопровождается поясняющим сообщением:

printf(“Введите матрицу М\n”);

for( i = 0; i<2; i++)

for( j = 0; j< 3; j++)

scanf(“%f”,&m[i][ j]);

На клавиатуре желательно для наглядности восприятия набирать элементы матрицы по строкам, отделяя числа друг от друга одним или несколькими пробелами:

1 2 3 [Enter]

4 5 6 [Enter]

Пример 2.Организовать вывод матрицы М на экран.

Вывод матрицы необходимо реализовать в удобном для чтения виде, т.е. чтобы на одной строке экрана располагалась одна строка матрицы. С этой целью в тело внешнего цикла, помимо внутреннего, включается оператор printf, который переводит курсор к началу следующей строки экрана после вывода текущей строки матрицы.

for ( i = 0; i<2; i++)

{

for ( j = 0; j< 3; j++)

printf(“%3d “,m[i][j]);

printf(“\n”);

}

Вывод матрицы на экран будет следующим:

1 2 3

4 5 6

Обработка матриц

Базовыми алгоритмами обработки матриц являются те же алгоритмы, которые используются при обработке одномерных массивов. Однако реализацию этих алгоритмов можно условно рас­сматривать для двух типов задач.

  1. Алгоритмы реализуются при просмотре всех элементов матрицы (просмотр может быть с условием). Начальная установка алгоритма выполняется перед двойным циклом. В этом случае запись операторов цикла для параметров i и j осуществляется последовательно друг за другом и имеет вид:

<начальная установка>

for (i = 0; i
for (j = 0; j< n; j++)

<тело цикла>;

  1. Алгоритмы реализуются внутри каждой строки или каждого столбца матрицы. В этом случае начальная установка алгоритма выполняется между операторами цикла, записанными для параметров i и j. Например, если алгоритм реализуется для каждой строки, то запись в программе имеет следующий вид:

for ( i = 0; i< m ; i++)

{

<начальная установка>

for ( j = 0; j< n; j++)

<тело цикла>;

}

Нижерассмотрены примеры программирования задач каждого типа.

Реализация алгоритмов задач первого типа

Задача 1.Дана матрица вещественных чисел А = {аij}4х6.
Вычислить значение Z = Р1/|Р2|, где Р1 и Р2 – произведения положительных и отрицательных элементов матрицы соответственно.

#include

#include

#include

void main()

{

clrscr();

float A [4][6] ; /* описание матрицы А
int i,j;

float P1,P2,Z;

printf(“Введите матрицу А\n”);

for ( i = 0; i<4; i++)

for ( j = 0;j<6; j++)

scanf(“%f”,A[i][j]);

Pl=l; /* установка начальных значений

P2=1; произведений

for ( i = 0; i<4; i++)

for ( j =0; j< 6 ;j++)

{

if (A[i][j]>0) P1= P1*A[i][j]; /* произведение + */

if ( A[i][j]<0) Р2 = P2*A[i][j]; /* произведение - */

}

Z=Pl/abs(P2);

printf(“Z=%10.2f ”,Z);

}

Задача 2.В квадратной целочисленной матрице В= {bij}5х5 вычислить модуль разности между числом нулевых элементов, стоящих ниже главной диагонали, и числом нулевых элементов, стоящих выше главной диагонали.

Введем обозначения:

L1 – счетчик нулевых элементов ниже главной диагонали;

L2 – счетчик нулевых элементов выше главной диагонали;

L = |L1 -L2|.

#include

#include

#include

void main()

{

clrscr();

int B [5][5] ; /* описание матрицы B */

int i, j, LI, L2, L;

printf(“Введите матрицу В\n”);

for ( i = 0; i< 5; i++)

for (j = 0;j<5; j++)

scanf(“%d”,B[i][j]);

L1 = 0; /* инициализация счетчиков L1 и L2 */

L2 = 0;

for ( i = 0; i< 5; i++)

for (j = 0; j< 5; j++)

if (B[i][j]==0 ) /* поиск элементов, равных нулю */

{

if ( i>j) Ll=L1+1; /* выше главной диагонали */

if ( i
}

L = abs(Ll - L2);

printf(“L=%d”, L);

}
Реализация алгоритмов задач второго типа

Задача 1.В матрице X ={хij}3х6вещественных чисел первый элемент каждой строки поменять местами с минимальным элементом этой строки. Вывести матрицу Xпосле обмена.

#include

#include

#include

void main()

{

clrscr();

float X[3][6 ]; // описание матрицы X

int i,j,jmin;

float min;

printf(“введите матрицу X\n”);

for(i=0; i<3; i++) /* ввод значений матрицы */

for (j= 0; j<6; j++)

scanf(“%f ”,X[i][j]);

for(i=0; i<3; i++)

{

min=+lE6;

for (j=0; j<6; j++)

if (X[i][j]

{

min=X[i][j];

jmin=j;

}

X[i][jmin]=X[i][0]; // перестановка первого элемента //матрицы с наименьшим

X[i,0]=min;

}

for(i=0; i<3; i++)

{

for (j=0; j<6; j++) printf(“%8.2f”,X[i][j]);

printf(“\n”);

}

getch();

}

Задача 2.Дана матрица вещественных чисел С = {сij}8х4. Вычислить среднее арифметическое каждого столбца. Результат оформить в виде одномерного массива S = {sj};j= .

#include

#include

main()

{ float С[8][4];

float S[4];

int i, j;

printf(“Введите матрицу С:\n”);

for(i=0; i<8; i++)

for (j= 0; j<4; j++)

scanf(“%f ”,C[i][j]);

for (j= 0; j<4; j++)

{

S[j]=0;

for(i=0; i<8; i++)

S[j]= S[j] + C[i][j];

S[j]=S[j]/8;

}

for (j= 0; j<4; j++) printf(“%8.2f”,S[j]);

printf(“\n”);

getch();

}

В приведенной выше программе для вычисления каждого элемента S[j] организован двойной цикл, в котором индекс j является внешним параметром цикла, а индекс i - внутренним.

Приведем вариант программы без использования одномерного массива S.

#include

#include

main()

{ float С[8][4];

float S;

int i, j;

printf(“Введите матрицу С:\n”);

for(i=0; i<8; i++)

for (j= 0; j<4; j++)

scanf(“%f ”,C[i][j]);

for (j= 0; j<4; j++)

{

S=0;

for(i=0; i<8; i++) S:= S + C[i][j];

S = S/8;

printf(“Среднее арифметическое %d -го

столбца =%8.2f\n”,j, S);

}

}

5.3 Текстовые данные

В языке СИ текстовая информация может быть представлена двумя типами данных: символьным и стро­ковым.

5.3.1. Символьный тип данных

Значением данных символьного типа является любой символ
из набора всех символов компьютера. Каждому символу соответствует порядковый номер (код) в диапазоне 0..255. Для кодировки символов первой половины диапазона (0..127) используется код ASCII (американский стандартный код для обмена информацией).
Вторая половина символов с кодами 128..255 может быть различной.

При написании программ символьные данные могут быть
представлены либо константами, либо переменными.

Символьная константа представляет собой одиночный
символ, заключенный в апострофы, например:

Y’ ‘!’ ‘_’ ‘Д’

Символьная переменная объявляется с помощью ключевого слова char, например:

char cr;

Во внутренней памяти компьютера каждый символ занимаем 1 байт.

Ввод-вывод символьных данных

Для ввода символьных данных используются функции: scanf() – форматированный ввод, getchar() – специальная функция для ввода символа. Для форматного ввода и вывода символьных констант используется спецификатор (формат) %с. Необходимо помнить, что нажатие любой небуквенной клавиши при вводе ([пробел], [Enter] и др.) будет значимым и восприниматься как символ.

Пример 1. Организовать ввод символьных переменных:

a='i';b='j';c='k'

main()

{ char a,b,c;

printf(“Введите исходные данные”);

scanf(“%c%c%c”,&a,&b,&sc);

. . .

}

При вводе символы набираются без апострофов:

ijk [Enter]

Символ клавиши [Enter] выходит за пределы списка ввода, поэтому он игнорируется.

При использовании для ввода символьной информации с помощью функции getchar() надо помнить, что функция переводит программу в ожидание нажатого символа, но при нажатии символа на клавиатуре он не выводится на экран. Например, при выполнении следующего фрагмента программы

printf(“Введите исходные данные”);

a=getch();b=getch();c=getch();

переменные будут введены, но на экране их значения не отразятся.

Для вывода символьных данных используются функции printf() и putchar().

Пример 2. Организовать вывод указанных выше переменных на экран в одну строку. Запись операторов вывода будет следую­щей:

printf(“%c%c%c\n”,a,b,c);

Нa экране будет отображено:

ijk

Если использовать для вывода функцию putchar():

putchar(a); putchar(b); putchar(c);

на экране будет отображен тот же результат.

Обработка символьных данных

Поскольку символы в языке СИ упорядочены, к ним можно применять операции отношения (>, >=, <, <=, =, <>). Это дает возможность записывать логические выражения с символьными данными в условных операторах. Например, оператор

If (ch=='!' ) ch ='.';

заменяет в символьной переменной ch восклицательный знак точкой.

Символьные данные могут использоваться и в операторах цикла for. Так, при выполнении операторов:

for (ch= 'a';ch>='d';ch++)printf(“%с ”,ch);

в строку экрана выводится последовательность:

a b с d

Если значение символьной переменной вывести, используя спецификатор для целых чисел %d, на экране отобразится код символа. Например:

for (ch= 'a';ch>='d';ch++)printf(“%d ”,ch);

на экран будет выведено:

97 98 99 100

Над символьными данными можно выполнять арифметические операции сложению и вычитания. Так, например, операция ch++; из предыдущего примера увеличивает код символа, хранящегося в переменной ch на 1. Или, выполняя операцию ch='a'-'A'; будет получена разница кода большой и маленькой буквы латинского алфавита. Так, например, если в символьной переменной ch1 хранится маленькая буква алфавита, то, выполнив действия:

char ch,ch1,ch2;

ch='a'-'A';

ch1='k';

ch2=ch1-сh;

printf(“%c-%d %c-%d\n”,ch1,ch1,ch2,ch2);

в переменную ch2 запишется та же буква, только большая, а на экран

k-107 K-75

5.3.2. Строковый тип данных

Значением данных строкового типа (строка) является любая последовательность символов из набора символов компьютера. Причем компьютеру все равно, какие данные записаны – для него это набор байтов.

Строковая константа - это строка, заключенная в кавычки, например:

“Язык программирования”

Строковая переменная или строка представляет собой массив символов, поэтому и объявляется она именно так:

сhar st[30];

В квадратных скобках указывается максимальное число символов в строке st.

Под значение строковой переменной в памяти компьютера отводится (МАХ) байт, пронумерованных от 0 до МАХ-1, где МАХ - заданный максимальный размер строки.

Однако строка отличается от массива тем, что она заканчивается символом с кодом 0 - признаком окончания строки. По местоположению этого специального символа определяется фактическая длина строки.

Начальное значение строки можно задать при объявлении в двойных кавычках после знака равенства:

char s[80] = "Язык программирования Си";

Символы в кавычках будут записаны в начало массива s, а затем - признак окончания строки '\0'.

При описании строки можно также написать так:

char s[] = "Язык программирования Си";

В этом случае компилятор подсчитает символы в кавычках, выделит памяти на 1 байт больше и занесет в эту область саму строку и завершающий ноль.

Ввод-вывод строковых данных

При вводе строк, как и символов, используется функция scanf(). При этом для форматного ввода и вывода строк используется спецификатор %s. Однако нажатие клавиши [Enter] или клавиши [пробел] не является значимым символом. При вводе строки с помощью функции scanf() нажатие одной из этих клавиш формирует символ конца строки. Таким образом надо помнить, что функция scanf() позволяет записать в строку только одно слово.

Пример.Организовать ввод ФИО студента.

char fam[20];

printf("Введите фамилию и инициалы студента");

scanf("%s",fam);

На клавиатуре строка набирается без кавычек, например:

Андреева СВ. [Enter]

Одновременно с вводом строки в байт с индексом восемь запишется символ с кодом 0. Инициалы студента с эту строку записаны не будут.

Для ввода текста содержащего пробелы можно использовать специальную функцию gets(). При вводе строки с помощью этой функции только нажатие клавиши [Enter] сформирует символ конца строки.

Так, например, в предыдущей задаче:

char fam[20];

printf(“Введите фамилию и инициалы студента”);

gets(fam);

использование функции gets() позволит записать в строку fam не только фамилию, но и инициалы.

Вывод строк осуществляется с помощью функции printf() и специальной функции puts(). Например, оператор

printf(“| %20s|”,fam);

выведет на экран в правую часть поля из 20 позиций строку fam:

| Андреева С.В.|

Специальная функция puts() позволяет вывести содержимое строки и переводит курсор на следующую строку. Например:

putchar(‘|’); puts(fam);putchar(‘|’);

приведет к получению следующего результата:

|Андреева С.В.

|

Последний символ будет выводиться в следующей строке экрана.

Обработка строковых данных

К любому символу строки можно обратиться как к элементу одномерного массива, например, запись st[i] определяет i символ в строке st. Поэтому при решении некоторых задач обработку строковых данных можно проводить посимвольно, организуя циклы для просмотра строки.

Например: Дано предложение. Определите количество слов в нем.

Решение:

Слова в предложении разделяются пробелами. Подсчитав количество пробелов, можно определить количество слов, учитываю, что между словами введен только один пробел.

#include

#include

#include

main()

{ char slova[120];

int i, n, k=1;

printf(“Введите предложение\n”);

gets(slova);

n= strlen(slova); // функция strlen() возвращает длину строки

for(i=0;i
if(slovo[i]==‘ ’)k++;

printf("k=%d\n",k);

}

Стандартные функции и процедуры

Большинство действий над строками реализуется с помощью стандартных функций. Библиотека языка Си содержит большое количество таких функций, прототипы которых определяются в заголовочном файле string.h. Рассмотрим некоторые из них.

Сравнение строк:

strcmp(str1,str2) – сравнивает две строки str1 и str2 и возвращает 0, если они одинаковы; результат отрицателен, если str1str2.

strncmp(str1, str2, kol) – сравниваются части строк str1 и str2 из kol символов. Результат равен 0, если они одинаковы.

Сравнение двух строк выполняется последовательно слева неправо с учетом кодировки символов. Например, сравнивая стоки st1 и st2

char st1[10]=”Пример”;

char st2[10]=”ПPимер”;

int a;

if (strcmp(st1,st2)>0)

a=1;

else

a=2;

переменной а будет присвоено значение 1, так как код символа 'р' больше кода символа 'Р'.

Сцепление строк

strcat(str1,str2) - сцепление строк в порядке их перечисления.

strncat(str1,str2,kol) – приписывает kol символов строки str2 к строке str1.

Функция служит для объединения двух строк в одну. Например, в результате выполнения операторов:

char fam[] = “Андреева С.В.”;

char pr[7]= “ “; //7 пробелов

strcat(fam ,pr);

printf(“|%20s|”, fam);

на экран выведется строка:

|Андреева С.В. |

Заметим, что строка вывода занимает поле в 20 позиций, а переменная fam располагается в левой части поля.

Определение длины строки

strlen(str) – определяет длину строки str.

Пример.Определить длину строки

charfam[] = “Андреева С.В”;

printf(“%d”,strlen(fam));

функция strlen() вернёт значение равное 13 (символов).

Копирование строк

strcpy(str1,str2) – копирует строку str2 в строку str1.

Strncpy(str1, str2, kol) – копирует kol символов строки str2 в строку str1.

Пример.Скопировать фамилию сотрудника в переменную fam и вывести на экран.

int main()

{ char fam[15];

char *str = " Андреева СВ.";

strcpy(fam, str);

printf("|%s|\n", fam);

return 0; }

В результате выполнения данных операторов на экран будет выведена строка: |Андреева СВ.|

Поиск символа в стоке

P=strchr(st, ch) - функция поиска адреса символа ch в заданной строке st. Результатом выполнения поиска является адрес P найденного символа в строке st, иначе возвращается нулевой адрес. Чтобы вычислить порядковый номер символа ch в строке, можно из адреса P вычесть адрес начала строки.

Пример.В заданной фамилии определить порядковый номер символа ‘n’.

main()

{ char fam[] = "Ivanov";

char faml[20];

char a='n'; char *p;

p=strchr(fam,a);

if(p)

printf("|%s|%d", fam,p-fam);

else

printf("нет такого символа в фамилии!\n");

}

Пример программирования текстовой задачи

Исходный текст является предложением, заканчивающимся точкой. Слова в предложении отделяются друг от друга одним пробелом. Определить самое длинное слово в предложении.

#include

#include

#include

main()

{ char slovo[12],x[120];

int i,m=0,n,k=0;

gets(x);

for(i=1;i
if(x[i]!=' ')k++;

else{ if (k>m){ m=k;n=i;}

k=0;}

k=0;

for(i=n-m;i
slovo[k++]=x[i];

slovo[k]=0;
printf("%s \n%s\n",slovo,x);

printf("%d %d\n",strlen(slovo),strlen(x));

}

Контрольные вопросы

  1. Какие ограничения накладываются на индексы элементов массивов?

  2. Способы описания массивов на языке С++. Понятия размерности массивов, описание размерности массивов.

  3. Задание типов элементов массива. Могут ли элементы массива иметь разный тип?

  4. Как располагаются элементы массива в памяти?

  5. Чем отличаются алгоритмы поиска максимального и минимального элемента массива.

  6. Что является общим во всех алгоритмах формирования и обработки массивов?

  7. Чем отличаются алгоритмы расчета суммы и подсчета числа элементов массива.

  8. Как располагаются элементы двухмерного массива в памяти?

  9. Чем отличаются алгоритмы поиска максимального и минимального элемента массива, расчета суммы и подсчета числа положительных (отрицательных) элементов массива для массива в целом и для каждой его строки (столбца)?

  10. Особенности организации ввода – вывода двухмерных массивов на языке С++.

  11. Описание символьных данных и строк на языке С++.

  12. Встроенные функции языка С++, используемые для обработки строк.

  13. Кодирование символьной информации в ПЗВМ.


1   ...   16   17   18   19   20   21   22   23   ...   26

Раздал 6 Структуры данных

6.1 Понятие структуры

6.2 Обработка структур



6.1 Понятие структуры


Очень часто при обработке информации приходится работать с блоками данных, в которых присутствуют данные разных типов. Например, информация о книге в каталоге библиотеки включает в себя автора, название книги, год издания, количество страниц и т.п.

Для хранения этой информации в памяти не подходит обычный массив, так как в массиве все элементы должны быть одного типа. Конечно, можно использовать несколько массивов разных типов, но это не совсем удобно.

В современных языках программирования существует особый тип данных, который может включать в себя несколько элементов более простых (причем разных!) типов.

Структура - это тип данных, который может включать в себя несколько полей – элементов разных типов (в том числе и другие структуры).

В общем случае при работе со структурами следует выделить четыре момента:

- объявление и определение типа структуры,

- объявление структурной переменной,

- инициализация структурной переменной,

- использование структурной переменной.

Данные типа структура, как и массивы, относятся к сложным структурам данных. Структура состоит из фиксированного числа элементов, называемых полями. Однако, в отличие от массива, поля могут быть различного типа. Например, структурой можно считать строку экзаменационной ведомости:

Андреева С.В. 4 5 5

Данная структура состоит из четырех полей: одно поле - строка (ФИО студента) и три числовых поля (оценки студента по предметам).

Поскольку структура - это новый тип данных, его надо предварительно объявить в начале программы. Определение типа структуры делается так:

struct Имя

{

<тип> <имя 1-го поля>;

<тип> <имя 2-го поля>;

…………

<тип> <имя последнего поля>;

};

Например, задание типа записи строки экзаменационной ведомости выглядит следующим образом:

struct student

{

char fam[20];

int mathematics, informatics, history;