🏠专栏介绍:浅尝C++专栏是用于记录C++语法基础、STL及内存剖析等。
🚩一些备注:之前的文章有点杂乱,这里将前面的知识点重新组织了,避免了过多冗余的废话。
🎯每日努力一点点,技术变化看得见。
命名空间
在编程中,经常需要团队合作,假如小A编写了一部分代码,我也编写了一部分代码。此时,将我们俩的代码组合到一起时,竟然报错了。原因竟然是:我们两个人都定义了Add函数。
如果这是在C语言中,则我们两个必须要有一个人改掉这个函数名。C++中为了避免命名冲突或名字污染,引入了namespace[命名空间]来解决这个问题。下面我们一起来学习以下命名空间。
#include <stdio.h>
//我的代码
int Add(int a, int b)
{
return a + b;
}
//小A的代码
double Add(double a , double b)
{
return a + b;
}
int main()
{
Add(1, 2);
//编译后报错:"Add"重定义
return 0;
}
命名空间定义
定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,后序接一对{}即可,{}中即为命名空间的成员。命名空间中可以定义变量、函数和类型(类、结构体等)。
namespace Jammingpro
{
//命名空间中可以定义变量/函数/类型。
int age = 18;
int Add(int a, int b)
{
return a + b;
}
struct Node
{
struct Node* next;
int val;
}
}
命名空间可以进行嵌套,也就是说,一个命名空间中可以再定义命名空间。
namespace XiaoA
{
namespace secret
{
int a;
}
double Add(double a, double b)
{
return a + b;
}
}
同一个工程中,允许存在多个相同名称的命名空间,编译器最后会将同名的命名空间合并为一个。
//test.h
namespace N1
{
int a = 100;
}
//add.h
namespace N1
{
int b = 666;
}
上面位于同一个工程不同头文件的命名空间N1将会被合并成一个。
注意:一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中。
命名空间的使用
命名空间该怎么使用呢?下面给出个出错的例子。由于命名空间像是一个隔离带一样,将变量a圈在了命名空间内,main函数无法访问到,所以报错。
namespace Jammingpro
{
int a = 100;
int b = 66;
}
int main()
{
//error:"a"未声明的标识符
printf("%d\n", a);
return 0;
}
下面介绍命名空间的3种使用方式↓↓↓
①加命名空间名称及作用域限定符
int main()
{
printf("%d\n", Jammingpro::a);
return 0;
}
②使用using将命名空间种某个成员引入
using Jammingpro::a;
int main()
{
printf("%d\n", a);
printf("%d\n", Jammingpro::b);
return 0;
}
③使用using namespace 命名空间名称 引入
using namespace Jammingpro;
int main()
{
printf("%d\n", a);
printf("%d\n", b);
return 0;
}
输入and输出
学习计算机语言,那就逃不过在屏幕上打印Hello World了。下面程序演示了打印"Hello World"。
#include <iostream>
using namespace std;
int main()
{
cout << "Hello World" << endl;
return 0;
}
使用cout标准输出对象时,包含于iostream头文件的std命名空间中。如果要使用它,需要包含对应头文件,并引入std命名空间的cout。endl是特殊的C++符号,表示换行输出,它也包含在iostream的std命名空间中。
下面再来看看C++如何进行数据输入↓↓↓
#include <iostream>
using namespace std;
int main()
{
int a;
double b;
char c;
cin >> a;
cin >> b >> c;
cout << a << " " << b << " " << c << endl;
return 0;
}
使用cin标准输入对象时一样要包含iostream头文件,并引入std命名空间中的cin。
下面给出关于cin、cout及endl的一些使用说明:
- 使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含< iostream >头文件以及按命名空间使用方法使用std。
- cout和cin是全局的流对象,endl是特殊的C++符号,表示换行输出,它们都包含在包含<
iostream >头文件中。 - <<是流插入运算符,>>是流提取运算符。
- 使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动控制格式。C++的输入输出可以自动识别变量类型。
- 实际上cout和cin分别是ostream和istream类型的对象,>>和<<也涉及运算符重载等知识,这些知识我们我们后续文章中陆续介绍。
★ps:早期标准库将所有功能在全局域中实现,声明在.h后缀的头文件中,使用时只需包含对应头文件即可,后来将其实现在std命名空间下,为了和C头文件区分,也为了正确使用命名空间,规定C++头文件不带.h;旧编译器(vc 6.0)中还支持<iostream.h>格式,后续编译器已不支持,因此推荐使用+std的方式。
std是C++标准库的命名空间,如果使用using namespace std,那么后序在定义变量和函数时要避免和std中的标识符重名。那如何展开std使用才更合理呢?
using namespace std展开,标准库就全部暴露出来了,如果我们定义跟库重名的类型/对象/函数,就存在冲突问题。该问题在日常练习中很少出现,但是项目开发中代码较多、规模大,就很容易出现。所以建议在项目开发中使用,像std::cout这样使用时指定命名空间或者using std::cout展开部分常用的库对象/类型等方式。
缺省参数
缺省参数概念
缺省参数分裂
全缺省参数
void func(int a = 1, int b = 2, int c = 3)
{
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl;
}
半缺省参数
void func(int a, int b = 2, int c = 3)
{
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl;
}
关于缺省参数的总结:
- 半缺省参数必须从右往左依次给出,不能间隔着给
- 缺省参数不能再函数声明和定义中同时给出(建议在函数声明中给出)。
//test.h
void func(int a = 1);
//test.cpp
void func(int a = 2)//error!!
{
}
★ps:如果生命与定义位置同时出现,恰巧两个位置提供的值不同,那编译器就无法确定到底该
用那个缺省值。即使是声明和定义给出的缺省参数是一样的,也会报错。编译器不允许声明和定义同时给出。
- 缺省值必须是常量或者全局变量
- C语言不支持缺省参数
下面给出一个使用缺省参数的场景。在初始化栈空间时,如果用户没有指定空间大小,则默认开辟5个空间。↓↓↓
void StackInit(int capacity = 5)
{
_a = (int*)malloc(sizeof(int) * capacity);
_size = 0;
_capacity = capacity;
}
🎈欢迎进入浅尝C++专栏,查看更多文章。
如果上述内容有任何问题,欢迎在下方留言区指正b( ̄▽ ̄)d