Какова связь между 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