Какова связь между iostream и namespace std?

В настоящее время я использую книгу "Teach Yourself С++" за 21 день, второе издание, чтобы узнать о кодировании на С++, а также Microsoft Visual С++ 2010 Express. В конце главы 1 есть небольшое упражнение о написании и компиляции следующего кода:

#include <iostream>

int main ()
{
    cout << "Hello World!\n";
    return 0;
}

Довольно просто, не так ли? Однако, к моему удивлению, код не будет компилироваться из-за этой ошибки:

ошибка C2065: 'cout': необъявленный идентификатор

Я начал чистить Web и вскоре нашел несколько решений здесь. Оказывается, мне пришлось добавить using namespace std; моему коду!

Однако в книге не было упоминания о пространствах имен, поэтому я решил, что книга устарела. (Он использует директиву #include <iostream.h> pre-processor!). После нескольких веб-исследований я нашел много информации об пространствах имен namespace std, а также некоторый исторический фон на <iostream.h> и <iostream>, и весь этот поток новых информация довольно запутанная для меня. (Не говоря уже обо всех ненужных результатах Google о медицинских ЗППП...)

Итак, вот некоторые вопросы, которые я получил до сих пор:

  • Если я включаю библиотеку iostream, зачем нужен namespace для поиска cout? Есть ли еще cout где-нибудь, что может вызвать конфликт имен? Если бы кто-то мог предоставить диаграмму для этого, это было бы здорово.

И как бонус, некоторый исторический фон:

  • Что именно было iostream.h до того, как оно было изменено на iostream?

  • Разве namespace сыграл роль в этом изменении?

Ответы

Ответ 1

Все стандартные определения библиотек находятся в пространстве имен std. То есть они не определены в глобальном масштабе, поэтому для их использования вам необходимо квалифицировать их одним из следующих способов:

  • std::cout
  • using namespace std
  • using std::cout

Например, допустим следующее:

// declarations
int global_variable;

namespace n {
int variable2;
}

global_variable может быть доступен как есть:

int x;
x = global_variable;

Но переменная2 не является частью глобального пространства, а является частью namespace n.

int x;
x = variable2; // error variable2 identifier not found.

Итак, вы должны использовать полное имя:

int x;
x = n::variable2;

В качестве ярлыка вы можете написать:

using namespace n;
int x;
x = variable2; // variable2 is searched in current namespace
               // and in all namespaces brought in with using namespace
               // Found ONLY in namespace n -> OK

или

using n::variable2; // this makes any unqualified reference to `variable2`
                    // to be resolved to `n::variable2`
int x;
x = variable2;

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

Ответ 2

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

Директива #include заставляет препроцессор включать содержимое другого файла в программу. Файл iostream содержит код, который позволяет программе С++ отображать вывод на экран и вводить ввод с клавиатуры. Файлы iostream включены в программу в точке, где появляется директива #include. iostream называется заголовочным файлом и отображается в верхней или верхней части программы.

using namespace std;

С++ использует пространства имен для организации имен или программных объектов. Он заявляет, что программа будет оценивать объекты, которые являются частью namespace, называемой "std". Каждое имя, созданное файлом iostream, является частью этого namespace.

Ответ 3

1.Если я включаю библиотеку iostream, почему namespace нужно найти cout? Есть ли еще cout где-нибудь, что может вызвать столкновение имен?

Это необходимо, потому что для стандарта С++ требуется, чтобы cout находился внутри пространства имен std. Может возникнуть конфликт cout, но не в стандартной библиотеке (например, ваш собственный код или какая-либо сторонняя библиотека.)

1.Что именно было iostream.h до того, как оно было изменено на iostream?

Это может быть что угодно, потому что это не часть стандарта, но это было название заголовка предварительной стандартизации, который лег в основу для iostream. Обычно он объявляет все имена в глобальном пространстве имен, поэтому вполне вероятно, что пример, на который вы смотрите, был написан до стандартизации.

2.Did namespace играет роль в этом изменении?

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

namespace foo
{
  void bar();  // declares foo::bar
}

Ответ 4

В С++ вы можете логически группировать идентификаторы в пространства имен. cout поток находится в пространстве имен std. Вы можете использовать его тремя способами.

  • Напишите using namespace std сверху и используйте cout, как и вы.
  • Запишите using std::cout сверху и используйте cout, как и вы.
  • Используйте std::cout вместо cout

Ответ 5

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

Представьте, что вам нужен карандаш, который помещается в ящик, который присутствует в вашей спальне. Так что вам нужно войти в свою комнату, чтобы получить доступ к карандашу. Здесь комната iostream. После того, как вы вошли в свою комнату, вам нужно открыть ящик и получить доступ к карандашу. Здесь ящик - это пространство имен, а карандаш - это cin/cout.

Ссылка: - https://en.wikiversity.org/wiki/C%2B%2B/Introduction