【C++】:C++关键字,命名空间,输入&输出,缺省参数

简介: 【C++】:C++关键字,命名空间,输入&输出,缺省参数

一,C++关键字(C++98)

C++总计63个关键字,C语言32个关键字。

ps:下面我们只是看一下C++有多少关键字,不对关键字进行具体的讲解。在以后的学习中会会了解的更深。

二,命名空间

2.1 命名冲突

在C语言的语法中,有时候会遇到这样的情况:

#include <stdio.h>
#include <stdlib.h>
int rand = 0;
int main()
{
  printf("%d\n", rand);
  return 0;
}

我们的本意是创建一个全局的 rand 变量,再进行输出。那为什么会报错呢?

原因:这是因为 rand 是一个库函数,当我们包含头文件 <stdlib.h> 时,在预处理阶段会展开头文件,里面的 rand 函数与我们定义的 rand 变量发生了冲突。编译器会自动识别 rand 是一个库函数,而不是对整形打印。

2.2 关键字namespace

使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染

首先我们知道在全局域(全局变量)和局部域(局部变量),可以分别定义名字相同的变量,但是使用时是局部优先。

那如何访问全局变量呢?就要用到域作用限定符::

当域作用限定符前没有其他符号时,就默认访问全局变量。

命名空间的本质也是一个域,叫做命名空间域。

它与全局域和局部域的区别是:命名空间域不影响生命周期。

使用方法是:后面跟命名空间的名字,然后接一对{}即可,里面的内容为命名空间的成员

使用变量,函数时,编译器的默认查找规则是:先在当前局部域查找,再在全局域中查找,但是不会在命名空间域里查找。

当要指定打印命名空间域中的变量时,在域作用限定符前要加上域的名字。

2.2.1 命名空间中可以定义变量/函数/类型

注意:一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中。

在 test.cpp 中:

namespace bit
{
 
 int rand = 10;
 int Add(int left, int right)
 {
 return left + right;
 }
 struct Node
 {
 struct Node* next;
 int val;
 };
}

2.2.2 命名空间可以嵌套

在大型项目中一般最多嵌套两三层,平时不会嵌套。

在 test.cpp 中:

namespace N1
{
 int a;
 int b;
 int Add(int left, int right)
 {
     return left + right;
 }
 namespace N2
 {
     int c;
     int d;
     int Sub(int left, int right)
     {
         return left - right;
     }
 }
}

2.2.3 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。

比如在 test .h 中:

namespace N1
{
 int Mul(int left, int right)
 {
     return left * right;
 }
}

一个工程中的 test.h 和上面 test.cpp 中两个N1会被合并成一个。

但是合并后不能有同名的变量,函数等,否则也会报错。要用嵌套解决。

2.3 命名空间的使用

2.3.1 指定访问域中成员:加命名空间名称及作用域限定符

2.3.2 使用using将命名空间中某个成员引入

可以指定域中的某个成员进行展开,使用它时可以不加作用域限定符。但是使用其他成员时要加。

比如 b 经常使用,a 偶尔使用时:

2.3.3 使用using namespace 命名空间名称 引入

当我们要多次使用域中某个成员时,每次都要 域名+限定符 十分麻烦就可以使用 using namespace + 名称 将域进行展开

2.4 当两个命名空间定义相同成员,同时展开时会报错。

所以命名空间不能随便展开!

namespace bit
{
  int a = 0;
  int b = 1;
  int c = 2;
}
namespace hello
{
  int a = 0;
  int b = 1;
  int c = 2;
}
//展开命名空间
using namespace bit;
using namespace hello;
int main()
{
  printf("%d\n", a);
  printf("%d\n", a);
  printf("%d\n", a);
  printf("%d\n", a);
  printf("%d\n", a);
  printf("%d\n", a);
  return 0;
}

2.5 总结

所以说,使用 using namespace 展开命名空间的本质可以理解为改变了编译器默认的查找规则,不仅会先在局部域,全局域中查找,最后还会到命名空间域中查找。

但是要注意的是命名空间域的展开不是像头文件在预处理时展开的那样直接拷贝进来,而是相当于增加了一个声明。

三,输入&输出

3.1 C++也有一套新的输入输出流。

cout 和 cin 包含在头文件< iostream >中,在使用时为啥要展开命名空间 std 呢?

原因:是为了防止标准库中定义的内容和你定义的内容发生冲突。std 是官方库的命名空间,把标准库里的内容保护起来

说明:

  1. 使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含< iostream >头文件以及按命名空间使用方法使用std。
  2. cout和cin是全局的流对象,endl是特殊的C++符号,表示换行输出,他们都包含在包含< iostream >头文件中
  3. <<是流插入运算符,>>是流提取运算符
  4. 使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动控制格式
    C++的输入输出可以自动识别变量类型

注意:

关于cout和cin还有很多更复杂的用法,比如控制浮点数输出精度,控制整形输出进制格式等等。因为C++兼容C语言的用法,这些又用得不是很多,所以在涉及这方面时建议使用printf 来控制格式,这样更方便。

3.2 std命名空间的使用惯例

std是C++标准库的命名空间,如何展开std使用更合理呢?

  1. 在日常练习中,建议直接using namespace std即可,这样就很方便
  2. using namespace std展开,标准库就全部暴露出来了,如果我们定义跟库重名的类型/对象/函数,就存在冲突问题。该问题在日常练习中很少出现,但是项目开发中代码较多、规模大,就很容易出现。所以建议在项目开发中使用,像std::cout这样使用时指定命名空间 + using std::cout展开常用的库对象/类型等方式。

四,缺省参数

4.1 缺省参数概念

缺省参数是声明或定义函数时函数的参数指定一个缺省值在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参

举例:

4.2 缺省参数的分类

4.2.1 全缺省参数

函数的所有参数均由自己指定。

4.2.2 半缺省参数

函数的参数部分传实参,其余的自己指定。

半缺省参数必须从右往左缺省,如图 b ,c 是缺省的,实参50床给 a。

注意:

  1. 半缺省参数必须从右往左依次来给出,不能间隔着给。
  2. 缺省参数不能在函数声明和定义中同时出现,若有声明和定义分离的情况,只能在声明中缺省。

举例:

  1. 间隔缺省会报错
#include <iostream>
using namespace std;
void Func(int a , int b = 20, int c )
{
  cout << "a = " << a << endl;
  cout << "b = " << b << endl;
  cout << "c = " << c << endl << endl;
}
int main()
{
  Func(50, ,30);
  return 0;
}

目录
相关文章
|
1月前
|
安全 程序员 编译器
【C++】如何巧妙运用C++命名空间:初学者必备指南
【C++】如何巧妙运用C++命名空间:初学者必备指南
|
1月前
|
自然语言处理 编译器 Linux
【C++】巧用缺省参数与函数重载:提升编程效率的秘密武器
【C++】巧用缺省参数与函数重载:提升编程效率的秘密武器
|
3月前
|
程序员 C++ 开发者
C++命名空间揭秘:一招解决全局冲突,让你的代码模块化战斗值飙升!
【8月更文挑战第22天】在C++中,命名空间是解决命名冲突的关键机制,它帮助开发者组织代码并提升可维护性。本文通过一个图形库开发案例,展示了如何利用命名空间避免圆形和矩形类间的命名冲突。通过定义和实现这些类,并在主函数中使用命名空间创建对象及调用方法,我们不仅解决了冲突问题,还提高了代码的模块化程度和组织结构。这为实际项目开发提供了宝贵的参考经验。
61 2
|
2月前
|
程序员 C++ 容器
C++编程基础:命名空间、输入输出与默认参数
命名空间、输入输出和函数默认参数是C++编程中的基础概念。合理地使用这些特性能够使代码更加清晰、模块化和易于管理。理解并掌握这些基础知识,对于每一个C++程序员来说都是非常重要的。通过上述介绍和示例,希望能够帮助你更好地理解和运用这些C++的基础特性。
40 0
|
3月前
|
编译器 C语言 C++
C++入门 | 命名空间、输入输出、缺省参数
C++入门 | 命名空间、输入输出、缺省参数
44 4
|
2月前
|
C语言 C++
C++(六)Namespace 命名空间
命名空间(Namespace)是为了解决大型项目中命名冲突而引入的机制。在多库集成时,不同类库可能包含同名函数或变量,导致冲突。C++通过语法形式定义了全局无名命名空间,并允许对全局函数和变量进行作用域划分。命名空间支持嵌套与合并,便于协同开发。其使用需谨慎处理同名冲突。
|
4月前
|
安全 编译器 C++
C++一分钟之-C++中的属性命名空间
【7月更文挑战第22天】C++11引入属性作为元数据,虽无内置属性命名空间,但可通过自定义属性与命名空间组合实现类似效果。例如,创建`perf`命名空间存放`slow`和`fast`属性来标记函数性能。正确使用属性需注意位置、避免重复和确保与实现一致,以提升代码可读性和编译器理解。通过模拟属性命名空间,可以更有效地管理和使用属性。
43 1
|
4月前
|
存储 安全 编译器
【C++入门 四】学习C++内联函数 | auto关键字 | 基于范围的for循环(C++11) | 指针空值nullptr(C++11)
【C++入门 四】学习C++内联函数 | auto关键字 | 基于范围的for循环(C++11) | 指针空值nullptr(C++11)
|
4月前
|
存储 编译器 C++
C++从遗忘到入门问题之float、double 和 long double 之间的主要区别是什么
C++从遗忘到入门问题之float、double 和 long double 之间的主要区别是什么
|
6天前
|
存储 编译器 C++
【c++】类和对象(中)(构造函数、析构函数、拷贝构造、赋值重载)
本文深入探讨了C++类的默认成员函数,包括构造函数、析构函数、拷贝构造函数和赋值重载。构造函数用于对象的初始化,析构函数用于对象销毁时的资源清理,拷贝构造函数用于对象的拷贝,赋值重载用于已存在对象的赋值。文章详细介绍了每个函数的特点、使用方法及注意事项,并提供了代码示例。这些默认成员函数确保了资源的正确管理和对象状态的维护。
29 4