目录
namespace-命名空间
指定命名空间
前提须知:c++的库头文件几乎不带.h
早期c++库头文件带.h是因为很多时候还是沿用C语言的库,但是自从c++98标准引入了新的头文件命名约定,去除了传统的.h
扩展名,并引入了命名空间std
#include <stdio.h>
int a = 0;
//::域作用限定符
int main() {
int a = 1;
printf("%d\n", a); 1
printf("%d\n", ::a); 0 //如果::左边为空则代表全局域,带东西了代表指定域
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int rand = 10;
// C语言没办法解决类似这样的命名冲突问题,所以C++提出了namespace来解决
//因为rand既是变量也是函数名所以两者冲突如果不加stdlib头文件可以通过编译因为不存在函数名了
int main()
{
printf("%d\n", rand);
return 0;
}
namespace定义的是命名空间域类似于结构体但又不完全一样
所以命名空间解决的是命名冲突的问题-解决的是我们与库冲突的问题
一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中
#include<stdio.h>
namespace a1 { //命名空间域
int x = 1; //命名空间域可以是变量,函数,结构体等
int add(int left, int right) {
return left + right;
}
}
namespace a2 {
int x = 2; //还是全局变量
}
//编译器在编译的时候会进行搜索:1.局部域2.全局域3.如果指定了直接去指定域搜索 如果都搜索不到会报错
int main() {
printf("%d\n", a1::x);//指定的域查找
printf("%d\n", a2::x);
printf("%d\n", a1::add(1,3));
//printf("%d\n", x);//报错因为在全局和局部没找到x-为声明的标识符
}
//namespace a { //命名空间域
// int x = 1;
//}
//namespace a {
// int x = 2; //还是全局变量
//}//如果命名空间一样相当于两个namespace合并了报错信息是x重定义多次初始化
同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中
一个工程中的test.h和上面test.cpp中两个N1会被合并成一个,如果重定义了那么修改变量名即可
当然命名空间可以嵌套例如
#include<iostream>
using std::cout;
using std::endl;
namespace wwz {
namespace zs {
void push() {
cout << "zs" << endl;
}
}
namespace ls {
void push(){
cout << "ls" << endl;
}
}
}
int main() {
wwz::zs::push();
wwz::ls::push();
return 0;
}
不指定命名空间
using namespace xxx;//展开命名空间-是把指定域权限展开
例如:
using namespace std; std是将c++库的东西都放到std命名空间-std是c++库的命名空间
C++将标准库的定义实现都放到这个命名空间中
命名空间域它封装的是全局的东西,所以打开后最多相当于全局的,所以被打开后还是遵从先局部后全局,但是有冲突的话就不能展开(using namespace)--所以全展开慎用,在日常可以但是大项目最好不用
#include<iostream> int main() { cout<< "hello world "<< endl; return 0; } 包了头文件就能用cout,endl 但是实际上不管用是因为std封装了 所以 #include<iostream> int main() { std::cout<< "hello world "<< std::endl;//要么这样 return 0; } #include<iostream> using namespace std;//要么这样 int main() { cout << "hello world" << endl; std::cout<< "hello world "<< std::endl; return 0; }
三种命名空间的使用
指定命名空间 #include<iostream> int main() { cout<< "hello world "<< endl; return 0; } 包了头文件就能用cout,endl 但是实际上不管用是因为std封装了 所以 #include<iostream> int main() { std::cout<< "hello world "<< std::endl;//要么这样 return 0; }
展开命名空间 #include<iostream> using namespace std;//要么这样 int main() { cout << "hello world" << endl; std::cout<< "hello world "<< std::endl; return 0; } using namespace std展开,标准库就全部暴露出来了,如果我们定义跟库重名的类型/对 象/函数,就存在冲突问题。日常可以但是项目不建议
部分展开 #include<iostream> using std::cout; using std::endl; int main() { cout << "hello" << endl;//仅仅展开常用的std中的cout和endl,不完全展开std return 0; }
c++不推荐用宏定义很排斥但是宏能用但是不经常用
总结:1.如果定义了多个同名的命名空间则他们会合并,可能会导致域内变量冲突那么我们可以再套一层命名空间解决2.命名空间可以定义函数,变量,类型等3.三种命名方式展开
命名空间展开不同于头文件展开,头文件展开是在程序翻译时的预处理过程中将包含的头文件内容拷贝到源代码
命名空间的展开不是拷贝,是一种公开将权限放开
C++输入&输出
cin(标准输入对象(键盘))和cout(标准输出对象(控制台))都在iostream(io流)头文件里面所以必须包含#include<iostream>同时也被std命名空间封装所以也要有std命名空间
使用C++输入输出更方便,不需要像printf/scanf输入输出时那样需要手动控制格式
<<
既代表左移 (跟单独变量)
又代表流插入(跟cout在一起)-自动识别数据类型
#include<iostream> int main() { int i = 100; i = i << 1; const char* str = "hello world"; char ch = '\n'; std::cout << str << i << ch << std::endl;//自动识别数据类型 std::cout << str << i << ch ; std::cout << str << i << std::endl ;//endl相当于换行,更倾向于endl printf("%s%d%c", str, i, ch); return 0; }
>>
右移
流提取(从键盘)
int i; char ch; cin>>i>>ch; scanf("%d %c",&i,&ch);
cin自动识别输入类型,相比较于c语言更简单
如果输出要保留小数点建议用c语言的printf这样方便
缺省参数
概念
缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参
具体分析就是函数传参
#include<iostream>
void Func(int a = 0)//a=0就是缺省参数
{
cout<<a<<endl;
}
int main()
{
Func(); // 没有传参时,使用参数的默认值
Func(10); // 传参时,使用指定的实参,而不是使用a=0
return 0;
}
缺省参数分类
全缺省参数
void Func(int a = 10, int b = 20, int c = 30) { cout<<"a = "<<a<<endl; cout<<"b = "<<b<<endl; cout<<"c = "<<c<<endl; }
半缺省参数
void Func(int a, int b = 10, int c = 20)//从右往左连续给缺省参数 { cout<<"a = "<<a<<endl; cout<<"b = "<<b<<endl; cout<<"c = "<<c<<endl; }
#include<iostream>
using namespace std;
void push(int a = 10, int b = 20, int c = 30) {
cout << a << endl;
cout << b << endl;
cout << c << endl<<endl;
}
int main() {
push(1, 2, 3);//三个都传
push(1, 2);//两个传给a,b
//push(,1,2);//不可以跳着传,这个传参是错的
push(1);//一个传给a
push();//缺省参数
}
1
2
3
1
2
30
1
20
30
10
20
30
如果函数的声明和定义分开了,一个在.h一个在.cpp那么我们要在声明中写缺省参数因为我们调用的是.h(声明头文件),有声明就可以帮助我们通过语法检查(翻译的编译阶段进行语法检查),如果声明和定义分开那么在编译阶段我没有函数的地址,得有定义才有函数地址
链接阶段把多文件代码合并
注意:1. 半缺省参数必须从右往左依次来给出,不能间隔着给,也不能从左往右
2. 缺省参数不能在函数声明和定义中同时出现
3. 缺省值必须是常量或者全局变量
4. C语言不支持(编译器不支持)