Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Документ Microsoft Office Word (2).docx
Скачиваний:
44
Добавлен:
09.02.2015
Размер:
842.69 Кб
Скачать

Пример №1

Это пример программы, которая не делает ничего. Она начинает выполняться и немедленно завершается. Она состоит из единственной вещи: функции main(), которая обозначает точку начала выполнения программы на Си++.

int main()

{

return 0;

}

Стандарт Си++ требует, чтобы функция main() возвращала тип int. Программа, которая имеет другой тип возвращаемого значения функции main(), не соответствует стандарту Си++.  Стандарт не говорит о том, что на самом деле означает возвращаемое значение функции main(). Традиционно оно интерпретируется как код возврата программы. Стандарт гарантирует, что возвращение 0 из функции main() показывает, что программа была завершена успешно.  Завершение программы на Си++ с ошибкой традиционно обозначается путём возврата ненулевого значения.

Пример №2

Эта программа также ничего не делает, но более лаконична.

int main(){return 0;}

В Си++, если выполнение программы доходит до конца функции main(), то это эквивалентно return 0;. Это неверно для любой другой функции кроме main(). Строго говоря, эта программа не является программой на Си++, желающие могут обратиться к H.Sutter "Exceptional C++".

Пример №3

Это пример программы Hello World, которая выводит это знаменитое сообщение, используя стандартную библиотеку, и завершается.

#include // это необходимо для std::cout и достаточно для std::endl

int main()

{

std::cout <<"Hello, world!" << std::endl;

}

Пример №4

Современный Си++ позволяет решать простым способом и более сложные задачи. Этот пример демонстрирует кроме всего прочего использование контейнеров стандартной библиотеки шаблонов (STL).

#include <iostream> // для использования std::cout

#include <vector> // для std::vector<>

#include <map> // для std::map<> и std::pair<>

#include <algorithm> // для std::for_each()

#include <string> // для std::string

using namespace std; // используем пространство имён "std"

void display_item_count(pair< string const, vector > const& person) {

// person - это пара двух объектов: person.first - это его имя,

// person.second - это список его предметов (вектор строк)

cout << person.first << " is carrying " << person.second.size() << " items\n";

}

int main()

{

// объявляем карту со строковыми ключами и данными в виде векторов строк

map< string, vector<string> > items;

// Добавим в эту карту пару человек и дадим им несколько предметов

items["Anya"].push_back("scarf");

items["Dimitri"].push_back("tickets");

items["Anya"].push_back("puppy");

// Переберём все объекты в контейнере

for_each(items.begin(), items.end(), display_item_count);

}

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

#include <vector>

int main()

{

using std::vector;

vector<int> my_vector;

}

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

Сравнение C++ с языками Java и C#

Язык С++ с появлением первых трансляторов нашёл сразу же очень широкое распространение, на нём было создано огромное количество программ и приложений. По мере накопления опыта создания больших программных систем обнажились недостатки, которые привели к поиску альтернативных решений. Таким альтернативным решением стал язык Java, который в некоторых областях стал конкурировать по популярности с C++, а фирма Майкрософт предложила язык C# как новый язык, развивающий принципы C++ и использующий преимущества языка Java. В дальнейшем появился язык Nemerle, объединяющий достоинства C# с возможностью функционального программирования. В последнее время появилась попытка объединения эффективности C++, безопасности и скорости разработки, как в Java и C# - был предложен язык D, который пока не получил широкого признания.  Язык Java обладает следующими особенностями, которых нет в языке C++ :  Java является типобезопасным языком. Типобезопасность гарантирует отсутствие в программах труднообнаружимых ошибок связанных с неверной интерпретацией памяти компьютера. Это делает процесс разработки более надежным и предсказуемым, а стало быть более быстрым. Так же это позволяет привлекать к разработке программистов имеющих меньшую квалификацию и иметь большие группы разработчиков.  Java-код компилируются изначально не в машинный код, а в некий промежуточный код, который в дальнейшем интерпретируется или компилируется, тогда как многие C++ компиляторы ориентированны на компиляцию в машинный код заданной платформы.  В языке Java есть чётко определённые стандарты на ввод-вывод, графику, геометрию, диалог, доступ к базам данных и прочим типовым приложениям.  Благодаря этим особенностям, приложения на Java обладают гораздо лучшей переносимостью, чем на С++, и часто, будучи написаны для определённого компьютера и операционной системы, работают под другими системами без изменений. Программисты, пишущие на языке Java, не зависят от пакетов, навязанных разработчиками компиляторов на данную конкретную среду, что резко упрощает портирование программ.  В языке Java реализована полноценная сборка мусора, которой нет в C++. Нет в С++ и средств проверки правильности указателей. С другой стороны, C++ обладает набором средств (конструкторы и деструкторы, стандартные шаблоны, ссылки), позволяющих почти полностью исключить выделение и освобождение памяти вручную и опасные операции с указателями. Однако такое исключение требует определённой культуры программирования, в то время как в языке Java оно реализуется автоматически.  Язык Java является чисто объектно-ориентированным, тогда как C++ поддерживает как объектно-ориентированное, так и процедурное программирование.  В C++ отсутствует полноценная информации о типах во время исполнения RTTI. Эту возможность можно было бы реализовать в C++, имея полную информацию о типах во время компиляции CTTI.  В C++ возможность введения пользовательского синтаксиса с помощью #define может привести к тому, что модули в крупных пакетах программ становятся сильно связаны друг с другом, что резко понижает надёжность пакетов и возможность организации разделённых модулей. С другой стороны, С++ предоставляет достаточно средств (константы, шаблоны, встроенные функции) для того, чтобы практически полностью исключить использование #define.  Эти отличия приводят к ожесточённым спорам между сторонниками двух языков о том, какой язык лучше. Сторонники Java считают эти особенности преимуществами; сторонники C++ считают, что во многих случаях эти особенности являются недостатками, в частности  Ценой переносимости является требование наличия на компьютере виртуальной Java-машины, что приводит к замедлению вычислений и практической невозможности использования новых возможностей аппаратной архитектуры.  Сборка мусора приводит к потере эффективности.  Стандарты на графику, доступ к базам данных и т.д. являются недостатком, если программист хочет определить свой собственный стандарт.  Указатели во многих случаях являются мощным или даже необходимым средством, а их бесконтрольное использование опасно лишь в неумелых руках.  Поддержка процедурного программирования является полезной.  Далеко не все программисты являются сторонниками одного из языков. По мнению большинства программистов, Java и C++ не являются конкурентами, потому что обладают различными областями применимости. Другие считают, что выбор языка для многих задач является вопросом личного вкуса.

Достоинства языка C++

Масштабируемость. На языке C++ разрабатывают программы для самых различных платформ и систем.  Возможность работы на низком уровне с памятью, адресами, портами. Что, при неосторожном использовании, может легко превратиться в недостаток.  Возможность создания обобщенных алгоритмов для разных типов данных, их специализация, и вычисления на этапе компиляции, используя шаблоны.

Недостатки языка C++

Наличие множества возможностей, нарушающих принципы типобезопасности приводит к тому, что в С++-программы может легко закрасться трудноуловимая ошибка. Вместо контроля со стороны компилятора разработчики вынуждены придерживаться весьма нетривиальных правил кодирования. По сути эти правила ограничивают С++ рамками некоего более безопасного подъязыка. Большинство проблем типобезопасности С++ унаследовано от С, но важную роль в этом вопросе играет и отказ автора языка от идеи использовать автоматическое управление памятью (например, сборку мусора). Так визитной карточкой С++ стали уязвимости типа "переполнение буфера".  Плохая поддержка модульности. Подключение интерфейса внешнего модуля через препроцессорную вставку заголовочного файла (#include) серьёзно замедляет компиляцию, при подключении большого количества модулей. Для устранения этого недостатка, многие компиляторы реализуют механизм прекомпиляции заголовочных файлов Precompiled Headers.  Недостаток информации о типах данных во время компиляции (CTTI).  Язык C++ является сложным для изучения и для компиляции.  Некоторые преобразования типов неинтуитивны. В частности, операция над беззнаковым и знаковым числами выдаёт беззнаковый результат.  Препроцессор С++ (унаследованный от С) очень примитивен. Это приводит с одной стороны к тому, что с его помощью нельзя (или тяжело) осуществлять некоторые задачи метапрограммирования, а с другой, в следствии своей примитивности, он часто приводит к ошибкам и требует много действий по обходу потенциальных проблем. Некоторые языки программирования (например, Scheme и Nemerle) имеют намного более мощные и более безопасные системы метапрограммирования (также называемые макросами, но мало напоминающие макросы С/С++).  С конца 20-го века в сообществе С++ получило распространение так называемое метапрограммирование на базе шаблонов. По сути, оно использует особенности шаблонов C++ в целях реализации на их базе интерпретатора примитивного функционального языка программирования выполняющегося во время компиляции. Сама по себе данная возможность весьма привлекательна, но, в следствии вышесказанного, такой код весьма трудно воспринимать и отлаживать. Языки Lisp/Scheme, Nemerle и некоторые другие имеют более мощные и одновременно более простые для восприятия подсистемы метапрограммирования. Кроме того, в языке D реализована сравнимая по мощности, но значительно более простая в применении подсистема шаблонного метапрограммирования.  Хотя декларируется, что С++ мультипарадигменный язык, реально в языке отсутствует поддержка функционального программирования. Отчасти, данный пробел устраняется различными библиотеками (Loki, Boost) использующими средства метапрограммирования для расширения языка функциональными конструкциями (например, поддержкой лямбд/анонимных методов), но качество подобных решений значительно уступает качеству встроенных в функциональные языки решений. Такие возможности функциональных языков как сопоставление с образцом вообще крайне сложно эмулировать средствами метапрограммирования.

Критика языка C++

C++ унаследовал многие проблемы языка C:  Операция присваивания обозначается как = , а операция сравнения как == . Их легко спутать, и такая конструкция будет синтаксически правильной, но приведёт к труднонаходимому багу. Особенно часто это происходит в операторах if и while, например, программист может написать if (i=0) вместо if (i==0)(Вместе с тем, основная масса компиляторов выдаёт в таких случаях предупреждение.) Избежать ошибку такого типа можно, если писать все операции сравнения в таком виде: if (0==i). К тому же многие языки (Бейсик, Паскаль) используют символ "=" именно в операциях сравнения.  Операции присваивания (=), инкрементации (++), декрементации (--) и другие возвращают значение. В сочетании с обилием операций это позволяет, но не обязывает, программиста создавать трудночитаемые выражения. С другой стороны, один из основных принципов языков C и C++ — позволять программисту писать в любом стиле, а не навязывать «хороший» стиль. К тому же это иногда позволяет компилятору создавать более оптимальный код.  Макросы (#define) являются мощным, но опасным средством. В языке C++, в отличие от C, необходимость в опасных макросах появляется значительно реже благодаря шаблонам и встроенным функциям. Но в унаследованных стандартных С-библиотеках много потенциально опасных макросов.  Некоторые считают недостатком языка C++ отсутствие системы сборки мусора. С другой стороны, в C++ есть достаточно средств (классы с конструкторами и деструкторами, стандартные шаблоны, передача параметров по ссылке), позволяющих почти исключить использование опасных указателей. Тем не менее, отсутствие встроенной сборки мусора позволяет пользователю самому выбрать стратегию управления ресурсами.

39. Константа, переменная — это основополагающие понятия в любом языке программирования. Дадим определения этим понятиям.

Константа — это величина, которая при выполнении программы остаётся неизменной.

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