- 前言
- 一、namespace是什么?
- namespace嵌套
- 输入&输出简述
- 缺省参数/默认参数
- 函数重载简述
前言
学习C++时,经常看到一句代码using namespace std,这句代码有什么用?是什么意思呢?下述文章中,将这个问题进行解答。
一、namespace是什么?
首先要知道,C++是解决C语言的一些不足。
在C语言中,没有规定定义一个变量时,变量名与库里的关键字不能相同。所以导致两人在写一个项目时,其中一人命名的函数名与另一人命名的变量名相同时,就会引发重定义问题。
例如:
#include#include int rand = 0; int main() { printf("%dn", rand); return 0; }
解决方法只有其中一方修改命名,但是一个大型项目中,冲突的地方太多,改起来会很麻烦。C语言是无法很好的解决这个问题。
为了解决这个问题,C++引入关键字namespace(命名空间)。
将冲突的命名变量放入namespace空间,这个空间可以随意命名。
例如:
#include#include namespace pro { int rand = 0; } int main() { printf("%dn", rand); return 0; }
现在rand是访问的是库
例如:
#include#include namespace pro { int rand = 0; } int main() { printf("%dn", pro::rand); return 0; }
在namespace中可以定义变量、函数、类型。
namespace嵌套
在同一块命名空间中,也可能存在命名冲突,这时候就需要嵌套。 例如,在一个项目中,一组人在命名空间pro中定义结构体ListNode,另一组人也在命名空间pro中定义了相同的内容,由于项目中可以存在多个相同命名的命名空间,编译器会将相同名字的命名空间合并,导致命名会重定义。解决方法是,在命名空间中再写一套命名空间。
例如,导致重定义的代码
namespace pro
{
struct ListNode
{
int val;
struct ListNode* next;
};
}
namespace pro
{
struct ListNode
{
int val;
struct ListNode* next;
};
}
int main()
{
return 0;
}
解决办法
namespace pro
{
namespace cb
{
struct ListNode
{
int val;
struct ListNode* next;
};
}
}
namespace pro
{
namespace mix
{
struct ListNode
{
int val;
struct ListNode* next;
};
}
}
int main()
{
return 0;
}
总结
- 多个同名的命名空间是可以同时存在,编译器编译时会合并同名命名空间
- 命名空间可以嵌套
使用时,先pro里找到cb,再从cb中找到ListNode。
int main()
{
pro::cb::ListNode n1;
pro::mix::ListNode n2;
return 0;
}
如果不想写pro,则需要加入一句代码using namespace pro,这句代码的意思是将pro这个命名空间定义的东西释放出来。
using namespace pro;
int main()
{
cb::ListNode n1;
mix::ListNode n2;
return 0;
}
例如下述命名空间
namespace pro
{
int f = 0;
int rand = 0;
}
不想将pro里定义的东西全部放出来,只单独放f,可以用using pro::f。
现在,看下述代码
#includeusing namespace std; int main() { cout << "hello world" << endl; return 0; }
std是C++标准库的命名空间。
这段代码的意思就是,释放std这个命名空间。因为cout和endl这个是定义在这个头文件中,如果不释放std,是不能编译成功的。
没有使用using namespace std;时:
如果不想加using namespace std;也是可以的,代码就得这样写
#includeint main() { std::cout << "hello world" << std::endl; return 0; }
std放出来,虽然方便使用,但是存在冲突风险。
使用方式:
- 加命名空间名称及作用域限定符(最安全的,写起来麻烦)
#includeint main() { std::cout << "hello world" << std::endl; return 0; }
- 使用using namespace将命名空间名称引入(可能引发冲突,写起来简洁)
#includeusing namespace std; int main() { cout << "hello world" << endl; return 0; }
- 使用using将命名空间中成员引入(放常用的出来)
#includeusing std::cout; using std::endl; int main() { cout << "hello world" << endl; return 0; }
输入&输出简述
在C++中,C语言的输入(scanf)和输出(printf)都是可以用的,但是需要指定类型。==C++==的输入是cin,输出是cout,不需要指定类型。
#include#include using namespace std; int main() { int a = 0; scanf("%d", &a); printf("%dn", a); cin >> a ; cout << a << endl; return 0; }
其中>>是流提取运算符,<<流插入运算符(之后细讲)。endl是换行,等价于n。可以一行输入多个,也可以输出多个。
例如:
#includeusing namespace std; int main() { int a; double d; cin >> a >> d; cout << a << d << endl; return 0; }
缺省参数/默认参数
如下述代码,假设int a = 0;是备胎,呢么TestFunc(1)中的1,就是原胎。有原胎时,用原胎,没原胎时,用备胎。
#includeusing namespace std; void TestFunc(int a = 0) { cout << a << endl; } int main() { TestFunc();//没有传参时,使用参数的默认值 TestFunc(1); return 0; }
如果有多个值,如下述代码,只能按顺序传值,不能直接改变b。
#includeusing namespace std; void TestFunc(int a = 10, int b = 20, int c = 30) { cout << "a = " << a << endl; cout << "b = " << b << endl; cout << "c = " << c << endl; } int main() { TestFunc(); TestFunc(1); TestFunc(1,2); TestFunc(1,2,3); return 0; }
上述代码为全缺省。
半缺省(缺省部分),如下述代码,它不能一个都不传。必须从右往左缺省,并且是连续的
#includeusing namespace std; void TestFunc(int a, int b = 20, int c = 30) { cout << "a = " << a << endl; cout << "b = " << b << endl; cout << "c = " << c << endl << endl; } int main() { TestFunc(1); TestFunc(1,2); TestFunc(1,2,3); return 0; }
函数重载简述
C语言不支持同名函数,C++支持同名函数,要求:参数名相同,参数不同(参数个数/类型/顺序)
#includeusing namespace std; int Add(int left, int right) { return left + right; } double Add(double left, double right) { return left + right; } int main() { cout << Add(1,2) << endl; cout << Add(1.1,2.2) << endl; return 0; }
顺序不同指的是不同类型的形参
void f(int i, double d)
{
cout << "int i ,double d" << endl;
}
void f(double i, int d)
{
cout << "double i, int d" << endl;
}



