Loading docs/lang/basic.md +1 −39 Original line number Diff line number Diff line Loading @@ -68,45 +68,7 @@ int main() { ??? note "什么是 std?" `std` 是 C++ 标准库所使用的 **命名空间** 。使用命名空间是为了避免重名。 例如:你定义了一个名为 `cin` 的变量,有了命名空间后,就可以通过 `cin` 和 `std::cin` 区分它们。 访问命名空间内的成员有三种方式: 1. 在成员名称前加上 `命名空间::` 。 2. 使用指令 `using 命名空间::成员名;` ,这样的话,可以直接通过成员名访问成员,但如果定义了和成员同名的变量或函数,就会产生冲突。 3. 使用指令 `using namespace 命名空间;` ,这样的话,可以直接通过成员名访问命名空间中的任何成员,但一旦定义了和命名空间中任何一个成员同名的变量或函数,就会产生冲突。 在工程开发中,是不推荐使用 `using namespace 命名空间` 的。在 OI 中,很多人为了方便,总是使用 `using namespace std;` ,但这样做会有导致编译错误的风险。 上面的代码还可以写成下面两种样子: ```cpp #include <iostream> using std::cin; using std::cout; using std::endl; int main() { int x, y; cin >> x >> y; cout << y << endl << x; return 0; } ``` ```cpp #include <iostream> using namespace std; int main() { int x, y; cin >> x >> y; cout << y << endl << x; return 0; } ``` 关于命名空间的详细知识,可以参考 [命名空间](./namespace.md) 页面。 ### scanf 与 printf Loading docs/lang/namespace.md 0 → 100644 +90 −0 Original line number Diff line number Diff line ## 概述 C++ 的 **命名空间** 机制可以用来解决复杂项目中名字冲突的问题。 举个例子:C++ 标准库的所有内容均定义在 `std` 命名空间中,如果你定义了一个叫 `cin` 的变量,则可以通过 `cin` 来访问你定义的 `cin` 变量,通过 `std::cin` 访问标准库的 `cin` 对象,而不用担心产生冲突。 ## 声明 下面的代码声明了一个名字叫 `A` 的命名空间: ```cpp namespace A { int cnt; void f(int x) { cnt = x; } } // namespace A ``` 声明之后,在这个命名空间外部,你可以通过 `A::f(x)` 来访问命名空间 `A` 内部的 `f` 函数。 命名空间的声明是可以嵌套的,因此下面这段代码也是允许的: ```cpp namespace A { namespace B { void f() { ... } } // namespace B void f() { B::f(); // 实际访问的是 A::B::f(),由于当前位于命名空间 A // 内,所以可以省略前面的 A:: } } // namespace A void f() //这里定义的是全局命名空间的 f 函数,与 A::f 和 A::B::f 都不会产生冲突 { A::f(); A::B::f(); } ``` ## `using` 指令 声明了命名空间之后,如果在命名空间外部访问命名空间内部的成员,需要在成员名前面加上 `命名空间::` 。 有没有什么比较方便的方法能让我们直接通过成员名访问命名空间内的成员呢?答案是肯定的。我们可以使用 `using` 指令。 `using` 指令有如下两种形式: 1. `using 命名空间::成员名;` :这条指令可以让我们省略某个成员名前的命名空间,直接通过成员名访问成员,相当于将这个成员导入了当前的作用域。 2. `using namespace 命名空间;` :这条指令可以直接通过成员名访问命名空间中的 **任何** 成员,相当于将这个命名空间的所有成员导入了当前的作用域。 因此,如果执行了 `using namespace std;` ,就会将 `std` 中的所有名字引入到全局命名空间当中。这样,我们就可以用 `cin` 代替 `std::cin` ,用 `cout` 代替 `std::cout` 。 !!! warning "`using` 指令可能会导致命名冲突!" 由于 `using namespace std;` 会将 `std` 中的 **所有名字** 引入,因此如果声明了与 `std` 重名的变量或函数,就可能会因为命名冲突而导致编译错误。 因此在工程中,并不推荐使用 `using namespace 命名空间;` 的指令。 有了 `using` 指令, [C++ 语法基础](./basic.md#cin-cout) 中的代码可以有这两种等价写法: ```cpp #include <iostream> using std::cin; using std::cout; using std::endl; int main() { int x, y; cin >> x >> y; cout << y << endl << x; return 0; } ``` ```cpp #include <iostream> using namespace std; int main() { int x, y; cin >> x >> y; cout << y << endl << x; return 0; } ``` ## 应用 在一些具有多个子任务的问题中,我们可以对每个子任务各开一个命名空间,在其中定义我们解决该子任务所需要的变量与函数,这样各个子任务间互不干扰,会在一定程度上方便调试,也会改善程序的可读性。 mkdocs.yml +1 −0 Original line number Diff line number Diff line Loading @@ -81,6 +81,7 @@ nav: - string: lang/csl/string.md - C++ 进阶: - 类: lang/class.md - 命名空间: lang/namespace.md - 引用: lang/reference.md - 常值: lang/const.md - 新版 C++ 特性: lang/new.md Loading Loading
docs/lang/basic.md +1 −39 Original line number Diff line number Diff line Loading @@ -68,45 +68,7 @@ int main() { ??? note "什么是 std?" `std` 是 C++ 标准库所使用的 **命名空间** 。使用命名空间是为了避免重名。 例如:你定义了一个名为 `cin` 的变量,有了命名空间后,就可以通过 `cin` 和 `std::cin` 区分它们。 访问命名空间内的成员有三种方式: 1. 在成员名称前加上 `命名空间::` 。 2. 使用指令 `using 命名空间::成员名;` ,这样的话,可以直接通过成员名访问成员,但如果定义了和成员同名的变量或函数,就会产生冲突。 3. 使用指令 `using namespace 命名空间;` ,这样的话,可以直接通过成员名访问命名空间中的任何成员,但一旦定义了和命名空间中任何一个成员同名的变量或函数,就会产生冲突。 在工程开发中,是不推荐使用 `using namespace 命名空间` 的。在 OI 中,很多人为了方便,总是使用 `using namespace std;` ,但这样做会有导致编译错误的风险。 上面的代码还可以写成下面两种样子: ```cpp #include <iostream> using std::cin; using std::cout; using std::endl; int main() { int x, y; cin >> x >> y; cout << y << endl << x; return 0; } ``` ```cpp #include <iostream> using namespace std; int main() { int x, y; cin >> x >> y; cout << y << endl << x; return 0; } ``` 关于命名空间的详细知识,可以参考 [命名空间](./namespace.md) 页面。 ### scanf 与 printf Loading
docs/lang/namespace.md 0 → 100644 +90 −0 Original line number Diff line number Diff line ## 概述 C++ 的 **命名空间** 机制可以用来解决复杂项目中名字冲突的问题。 举个例子:C++ 标准库的所有内容均定义在 `std` 命名空间中,如果你定义了一个叫 `cin` 的变量,则可以通过 `cin` 来访问你定义的 `cin` 变量,通过 `std::cin` 访问标准库的 `cin` 对象,而不用担心产生冲突。 ## 声明 下面的代码声明了一个名字叫 `A` 的命名空间: ```cpp namespace A { int cnt; void f(int x) { cnt = x; } } // namespace A ``` 声明之后,在这个命名空间外部,你可以通过 `A::f(x)` 来访问命名空间 `A` 内部的 `f` 函数。 命名空间的声明是可以嵌套的,因此下面这段代码也是允许的: ```cpp namespace A { namespace B { void f() { ... } } // namespace B void f() { B::f(); // 实际访问的是 A::B::f(),由于当前位于命名空间 A // 内,所以可以省略前面的 A:: } } // namespace A void f() //这里定义的是全局命名空间的 f 函数,与 A::f 和 A::B::f 都不会产生冲突 { A::f(); A::B::f(); } ``` ## `using` 指令 声明了命名空间之后,如果在命名空间外部访问命名空间内部的成员,需要在成员名前面加上 `命名空间::` 。 有没有什么比较方便的方法能让我们直接通过成员名访问命名空间内的成员呢?答案是肯定的。我们可以使用 `using` 指令。 `using` 指令有如下两种形式: 1. `using 命名空间::成员名;` :这条指令可以让我们省略某个成员名前的命名空间,直接通过成员名访问成员,相当于将这个成员导入了当前的作用域。 2. `using namespace 命名空间;` :这条指令可以直接通过成员名访问命名空间中的 **任何** 成员,相当于将这个命名空间的所有成员导入了当前的作用域。 因此,如果执行了 `using namespace std;` ,就会将 `std` 中的所有名字引入到全局命名空间当中。这样,我们就可以用 `cin` 代替 `std::cin` ,用 `cout` 代替 `std::cout` 。 !!! warning "`using` 指令可能会导致命名冲突!" 由于 `using namespace std;` 会将 `std` 中的 **所有名字** 引入,因此如果声明了与 `std` 重名的变量或函数,就可能会因为命名冲突而导致编译错误。 因此在工程中,并不推荐使用 `using namespace 命名空间;` 的指令。 有了 `using` 指令, [C++ 语法基础](./basic.md#cin-cout) 中的代码可以有这两种等价写法: ```cpp #include <iostream> using std::cin; using std::cout; using std::endl; int main() { int x, y; cin >> x >> y; cout << y << endl << x; return 0; } ``` ```cpp #include <iostream> using namespace std; int main() { int x, y; cin >> x >> y; cout << y << endl << x; return 0; } ``` ## 应用 在一些具有多个子任务的问题中,我们可以对每个子任务各开一个命名空间,在其中定义我们解决该子任务所需要的变量与函数,这样各个子任务间互不干扰,会在一定程度上方便调试,也会改善程序的可读性。
mkdocs.yml +1 −0 Original line number Diff line number Diff line Loading @@ -81,6 +81,7 @@ nav: - string: lang/csl/string.md - C++ 进阶: - 类: lang/class.md - 命名空间: lang/namespace.md - 引用: lang/reference.md - 常值: lang/const.md - 新版 C++ 特性: lang/new.md Loading