2 рк скре. Программа в Visual Studio. Локализация и кириллица в консоли Первая программа на Windows. Компилятор g
Скачать 290.46 Kb.
|
Вопросы 1-го РКОсновы C++ Первая программа в Visual Studio. Локализация и кириллица в консоли Первая программа на Windows. Компилятор g++ Структура программы. Переменные Генератор чисел и работа со строками Типы данных. Статическая типизация и преобразования типов Циклы For, While, Do while Константы. Арифметические операции Исключения и отлов ошибок Условные выражения. Побитовые операции Массивы данных. Одномерные и многомерные 1. C++ — компилируемый, статически типизированный язык программирования общего назначения. C++ широко используется для разработки программного обеспечения, являясь одним из самых популярных языков программирования. Область его применения включает создание операционных систем, разнообразных прикладных программ, драйверов устройств, приложений для встраиваемых систем, высокопроизводительных серверов, а также развлекательных приложений (игр). Существует множество реализаций языка C++, как бесплатных, так и коммерческих и для различных платформ. Например, на платформе x86 это GCC, Visual C++, Intel C++ Compiler, Embarcadero (Borland) C++ Builder и другие. Синтаксис C++ унаследован от языка C. Одним из принципов разработки было сохранение совместимости с C. Тем не менее, C++ не является в строгом смысле надмножеством C; множество программ, которые могут одинаково успешно транслироваться как компиляторами C, так и компиляторами C++, довольно велико, но не включает все возможные программы на C. Язык возник в начале 1980-х годов, когда сотрудник фирмы Bell Labs Бьерн Страуструп ( родился 30 декабря 1950) придумал ряд усовершенствований к языку C под собственные нужды. Когда в конце 1970-х Страуструп начал работать над задачами теории очередей, он обнаружил, что попытки применения существующих в то время языков программирования оказываются неэффективными, а применение высокоэффективных машинных языков слишком сложно из-за их ограниченной выразительности. Так, язык Симула имеет такие возможности, которые были бы очень полезны для разработки большого программного обеспечения, но работает слишком медленно, а язык BCPL достаточно быстр, но слишком близок к языкам низкого уровня и не подходит для разработки большого программного обеспечения. Вспомнив опыт своей диссертации, Страуструп решил дополнить язык C (преемник BCPL) возможностями, имеющимися в языке Симула. Язык C, будучи базовым языком системы UNIX, на которой работали компьютеры Bell, является быстрым, многофункциональным и переносимым. Страуструп добавил к нему возможность работы с классами и объектами. В результате практические задачи моделирования оказались доступными для решения как с точки зрения времени разработки (благодаря использованию Симула-подобных классов), так и с точки зрения времени вычислений (благодаря быстродействию C). Ранние версии языка, первоначально именовавшегося «C with classes» («Си с классами»), стали доступны с 1980 года Цикл while в C++Этот код выполняется следующим образом: Программа проверяет, верно ли утверждение. Выполняются инструкции в теле цикла. Программа возвращается к пункту 1. То есть пока утверждение верно (i < 100), цикл будет повторять одни и те же действия. Цикл, который пять раз выводит сообщение «Hello, World!»: int i = 0; while(i < 5) { std::cout << "Hello, World! \n"; i++; } Посмотрим на вывод: Обратите внимание на переменную i — она играет роль счётчика, к которому в каждом шаге цикла прибавляется единица. Это нужно, чтобы инструкции выполнялись только определённое количество раз. Один шаг цикла называется итерацией, а счётчик — итератором. Поэтому чаще всего для счётчика создаётся переменная i. Важно! Следите за тем, чтобы выход из цикла был возможен, иначе он будет выполняться бесконечно. Если внутри цикла складываются числа или что-то выводится, то нагрузка будет минимальной. Если же это какие-то ресурсозатратные вычисления, то выполнение такого цикла может заставить компьютер зависнуть. Когда нам нужно вмешаться в работу цикла, мы используем операторы break и continue. Оператор breakОператор break прерывает выполнение цикла: int sum = 0; int maxSum = 50; int i = 0; while(i < 100) { sum += i; i++; if(sum >= maxSum) { break; } } std::cout << "i = " << i << "\nsum = " << sum << "\n"; Этот цикл должен посчитать сумму всех чисел от одного до ста. Но мы указали максимальное значение для переменной sum, поэтому цикл прервётся, как только sum станет больше maxSum. Компилятор умеет отличать оператор break в конструкции switch от оператора break, который прерывает циклы. Поэтому можно спокойно писать вот такой код: int action = 0; bool end = false; //Этот цикл будет бесконечным, если его не прервать изнутри while(true) { std::cout << "Exit? \n1 - Yes\n0 - No\nAction: "; std::cin >> action; switch(action) { case 1: std::cout << "Good bye!\n"; end = true; break; case 0: std::cout << "Try again!\n"; } if(end) { break; } } Вот как это будет работать: Важно! Оператор break внутри конструкции switch не может прервать цикл. Оператор continueИногда нам нужно пропустить одну итерацию и перейти к следующей. Для этого используем оператор continue. int i = 0; while(i < 100) { i++; // if(i % 3 == 0) { continue; } std::cout << " " << i; } std::cout << "\n"; Этот цикл выведет все числа от одного до ста, кроме тех, которые делятся на три без остатка. Цикл do-while в C++Цикл do-while похож на while, но он сначала выполняет одну итерацию и только потом проверяет верность утверждения: while(false) { //Ничего не выводится std::cout << "Hello! \n"; } do { //Надпись будет выведена один раз std::cout << "Bye! \n"; } while(false); Вот результат: Цикл for в C++Если для работы цикла нужен счётчик, то его запись можно сократить с помощью цикла for, записав логику в скобки: Вот пример такого цикла: int sum = 0; for(int i = 0; i < 200; i++) { sum += i; } std::cout << "sum = " << sum << "\n"; В результате мы получим сумму всех чисел от 1 до 200: Вложенные циклыЦиклы, как и другие конструкции, можно размещать внутри других циклов. Вот, например, как вывести сетку с помощью for: for(int i = 0; i < 10; i++) { //Обратите внимание, что во вложенном цикле должен использоваться другой итератор. В данном случае j вместо i for(int j = 0; j < 10; j++) { std::cout << " + "; } std::cout << "\n"; } Получаем результат: Важно! Операторы break и continue влияют на тот цикл, в котором они находятся, а не на родительский. ЗаключениеЦиклы — одни из самых часто используемых конструкций в программировании. Они нужны при чтении данных из файлов, сортировке, отрисовке графики и так далее. Одно из самых полезных применений циклов связано с массивами, о работе с которыми будет отдельная статья. Компиля́тор: Программа или техническое средство, выполняющее компиляцию.[1][2] Машинная программа, используемая для компиляции.[2][3] Программа, переводящая текст программы на языке высокого уровня в эквивалентную программу на машинном языке.[4] Программа, предназначенная для трансляции высокоуровневого языка в абсолютный код или, иногда, в язык ассемблера. Входной информацией для компилятора (исходный код) является описание алгоритма или программа на проблемно-ориентированном языке, а на выходе компилятора — эквивалентное описание алгоритма на машинно-ориентированном языке (объектный код).[5] Программа выполняющая (после трансляции) компоновку программы. Компиляция: трансляция программы на язык, близкий к машинному,[2][3] и последующая её компоновка. трансляция программы, составленной на исходном языке, в объектный модуль (осуществляется компилятором.[2]) и последующая её компоновка в готовый к использованию программный модуль. трансляция программы, составленной на исходном языке, и последующая её компоновка в программу на некоем машинонезависимом низкоуровневом интерпретируемом коде (как например в случае языка Java). Компилировать — производить трансляцию машинной программы с проблемно-ориентированного языка на машинно-ориентированный язык [3] и последующую компоновку программы в готовый к использованию программный модуль. 1. Виды компиляторов Векторизующий. Компилирует исходный код в машинный код для компьютеров, оснащённых векторным процессором. Гибкий. Сконструирован по модульному принципу, управляется таблицами и запрограммирован на языке высокого уровня или реализован с помощью компилятора компиляторов. Диалоговый. См.: диалоговый транслятор. Инкрементальный. Повторно транслирует/компонует фрагменты программы и дополнения к ней без перекомпиляции всей программы. Интерпретирующий (пошаговый). Последовательно выполняет независимую компиляцию каждого отдельного оператора (команды) исходной программы. Компилятор компиляторов. Компилятор, воспринимающий формальное описание языка программирования и генерирующий компилятор для этого языка. Отладочный. Устраняет отдельные виды синтаксических ошибок. Резидентный. Постоянно находится в оперативной памяти и доступен для повторного использования многими задачами. Самокомпилируемый. Написан на том же языке, с которого осуществляется компиляция. Универсальный. Основан на формальном описании синтаксиса и семантики входного языка. Важными составными частями такого компилятора являются: ядро, синтаксический и семантический загрузчики. 2. Виды компиляции Пакетная. Компиляция нескольких исходных модулей в одном пункте задания. Построчная. То же, что и интерпретация. Условная. Компиляция, при которой транслируемый текст зависит от условий, заданных в исходной программе директивами компилятора. Так, в зависимости от значения некоторой константы, можно включать или выключать трансляцию части текста программы. 3. Основы Большинство компиляторов компилирует (в том числе транслирует) программу с некоторого высокоуровневого языка программирования в машинный код, который может быть непосредственно выполнен центральным процессором. Как правило, этот код также ориентирован на исполнение в среде конкретной операционной системы, поскольку использует предоставляемые ею возможности (системные вызовы, библиотеки функций, API). Архитектура или платформа (набор программно-аппаратных средств), для которой производится компиляция, называется целевой машиной или, также, целевой платформой. Некоторые компиляторы (например, Java) переводят программу не в машинный код, а в программу на некотором специально созданном низкоуровневом интрепретируемом языке. Такой язык — байт-код (в случае с Java Java-байт-код) — также можно считать языком машинных команд, поскольку в качестве его интерпретатора используется виртуальная машина. Байт-код не является машинным кодом какого-либо компьютера, т. е. машинным кодом в прямом смысле слова, и может переноситься на различные компьютерные архитектуры без перекомпиляции. Байт-код интерпретируется (исполняется) виртуальной машиной. Например, для языка Java это JVM (язык виртуальной машины Java), или так называемый байт-код Java (вслед за ним все промежуточные низкоуровневые интрепретируемые языки стали называть байт-кодами). Для языков программирования на платформе .NET Framework (C#, Managed C++, Visual Basic .NET и другие) — это MSIL (Microsoft Intermediate Language). Программа на байт-коде подлежит интерпретации виртуальной машиной, либо ещё одной компиляции уже в машинный код непосредственно перед исполнением. Последнее называется «Just-In-Time компиляция» (JIT), по названию подобного компилятора для Java. MSIL-код компилируется в код целевой машины также JIT-компилятором, а библиотеки .NET Framework компилируются заранее. Для каждой целевой машины (IBM, Apple, Sun и т. д.) и каждой операционной системы или семейства операционных систем, работающих на целевой машине, требуется написание своего компилятора. Существуют также так называемые кросс-компиляторы, позволяющие на одной машине и в среде одной ОС генерировать код, предназначенный для выполнения на другой целевой машине и/или в среде другой ОС. Кроме того, компиляторы могут быть оптимизированы под разные типы процессоров из одного семейства (путём поддержки специфичных для этих процессоров машинных команд). Например, код, скомпилированный под процессоры семейства Pentium, может использовать специфичные для этих процессоров наборы инструкций — MMX, SSE, SSE2. Также существуют компиляторы, переводящие программу с языка высокого уровня на язык ассемблера. (Правда такие компиляторы, вообще-то следовало бы называть трансляторами...) Существуют программы, которые решают обратную задачу — перевод программы с низкоуровневого языка на высокоуровневый. Этот процесс называют декомпиляцией, а такие программы — декомпиляторами. (Яркий пример таких программ - дизассемблеры) Но поскольку компиляция — это процесс с потерями, точно восстановить исходный код, скажем, на C++, в общем случае невозможно. Более эффективно декомпилируются программы в байт-кодах — например, существует довольно надёжный декомпилятор для Flash. Разновидностью декомпилирования является дизассемблирование машинного кода в код на языке ассемблера, который всегда выполняется успешно. Связано это с тем, что между кодами машинных команд и командами ассемблера имеется практически взаимно-однозначное соответствие. 4. Структура компилятора Любой компилятор состоит из транслятора и компоновщика. Часто в качестве компоновщика компилятор использует внешний компоновщик, реализованный в виде самостоятельной программы, а сам выполняет лишь трансляцию исходного текста (по этой причине многие ошибочно считают компилятором разновидность транслятора). Компилятор может быть реализован и как своеобразная программа-менеджер, для трансляции программы вызвающая сооствествующий транслятор (трансляторы - если разные части программы написаны на разных языках программирования) и затем - для компоновки программы, - вызывающая компоновщик. Ярким примером такого компилятора является имеющаяся во всех UNIX-системах (и Linux-системах в том числе) утилита make (имеются реализации утилиты make и в других системах, в частности в Windows-системах). Процесс компиляции состоит из следующих фаз: Лексический анализ. На этой фазе последовательность символов исходного файла преобразуется в последовательность лексем. Синтаксический (грамматический) анализ. Последовательность лексем преобразуется в древо разбора. Семантический анализ. Древо разбора обрабатывается с целью установления его семантики (смысла) — например, привязка идентификаторов к их определениям, типам данных, проверка совместимости типов данных, определение результирующих типов данных выражений и т. д. Результат обычно называется «промежуточным представлением/кодом», и может быть дополненным древом разбора, новым древом, абстрактным набором команд или чем-то ещё, удобным для дальнейшей обработки. Оптимизация. Удаляются избыточные команды и упрощается (где это возможно) код с сохранением его смысла, т. е. реализуемого им алгоритма (в том числе предвычисляются (т. е. вычисляются на фазе трансляции) выражения, результаты которых практически являются константами). Оптимизация может быть на разных уровнях и этапах — например, над промежуточным кодом или над конечным машинным кодом. Генерация кода. Из промежуточного представления порождается код на целевом языке (в том числе выполняется компоновка программы). В конкретных реализациях компиляторов эти фазы могут быть разделены или, наоборот, совмещены в том или ином виде. 5. Трансляция и компоновка Важной исторической особенностью компилятора, отражённой в его названии (англ. compile — собирать вместе, составлять), являлось то, что он мог производить как трансляцию так и компоновку (то есть состоял из двух частей — транслятора и компоновщика). Это связано с тем, что раздельные трансляция и компоновка как отдельная фазы компиляции выделились значительно позже появления компиляторов. В связи с этим, вместо термина «компилятор» иногда используют термин «транслятор» как его синоним, что, правда, терминологически неправильно: либо в старой литературе, либо когда хотят подчеркнуть его способность переводить программу в машинный код (и наоборот, используют термин «компилятор» для подчёркивания способности собирать из многих файлов один). 6. Интересные факты На заре развития компьютеров первые компиляторы (трансляторы) называли «программирующими программами»[6] (так как в тот момент программой считался только машинный код, а «программирующая программа» была способна из человеческого текста сделать машинный код, то есть запрограммировать ЭВМ). Собственно, это отражает тот факт, что компилятор по своей сути являются одним из средств автоматизации процесса программирования компьютеров. Дело в том, что любая написанная нами программа на неком входном языке (например, на С++ или языке ассемблера) по сути есть скрипт-сценарий для компилятора - непосредственно выполняемая - интерпретируемая - компилятором программа в которой описывается: какую программу компилятор должен построить , что и как создаваемая нами таким образом программа должна делать (в том числе какие данные и как обрабатывать). И уже выполняя - интерпретируя - эту нашу программу на входном языке, компилятор и строит эквивалентную ей программу на машинном языке. Договор оферты Оплата Правила пользования Платформой Политика конфиденциальности Конец формы |