使用命名空间的目的是:对标识符的名称进行本地化,以避免命名冲突或名字污染。
命名空间中可以定义变量、函数、类型,还可以嵌套;
代码如下:
namespace lmx//命名空间
{
int rand = 0;//变量
int Add(int x, int y)//函数
{
return x + y;
}
struct Node//类型
{
int val;
struct Node* next;
};
//可以嵌套
namespace cty
{
int a = 10;
}
}
int main()
{
int s = lmx::Add(5, 4);
printf("%d\n", s);
printf("%d\n", lmx::cty::a);
return 0;
}
在同一个工程中,允许多个相同名字的命名空间,编译时会把它们合并起来。
命名空间用法一:直接展开到全局域
using namespace lmx;
using namespace std;
int main()
{
struct Node n1;
//cout << rand << endl;//std中就定义了一个rand,而lmx中还有一个rand,冲突了
int n = Add(1, 2);
cout << n << endl;
return 0;
}
用法二:不展开,使用时前面标明域
int main()
{
std::cout << lmx::rand << std::endl;
lmx::Node n1;
int m = lmx::Add(1, 2);
std::cout << m << std::endl;
return 0;
}
用法三:部分展开
using std::cout;
using std::cin;
using std::endl;
int main()
{
int a = 0;
double b = 11.11;
cin >> a >> b;
cout << a << ',' << b << endl;
return 0;
}
使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含头文件;
<<是流插入运算符,>>是流提取运算符;
cout和cin都是自动识别类型的(库里面写好了运算符重载函数,相当于函数重载);
endl是换行符,相当于 \n。
using std::cout;
using std::cin;
using std::endl;
int main()
{
int a = 0;
double b = 11.11;
cin >> a >> b;
cout << a << ',' << b << endl;
return 0;
}
声明或定义是为函数参数指定一个缺省值,在调用该函数时,若没有指定实参则使用形参的缺省值。
函数缺省只在声明处给出,以声明为准,定义处无需给出。
C++通过函数名修饰规则来实现函数重载,参数不同,修饰出来的函数名就不同。
代码如下:
void fun1(int a = 10, int b = 8, int c = 9)
{
cout << a << endl;
cout << b << endl;
cout << c << endl;
}
代码如下:
void fun2(int a, int b = 9, int c = 8)//缺省必须从右往左连续缺省
{
cout << a << endl;
cout << b << endl;
cout << c << endl;
}
函数重载:允许在同一作用域中声明几个功能类似的同名函数
这些函数的参数个数、类型或类型顺序不同
只有参数类型不同才能构成重载,返回值类型不同不构成重载
代码如下:
int Add(int x, int y)
{
return x + y;
}
double Add(double x, double y)
{
return x + y;
}
代码如下:
void f()
{
cout << "f()" << endl;
}
void f(int a)
{
cout << "f(int a)" << endl;
}
代码如下:
void f1(int a, char b)
{
cout << "f1(int a, char b)" << endl;
}
void f1(char b, int a)
{
cout << "f1(char b, int a)" << endl;
}
引用:给已存在的变量取一个别名,不会开辟新的空间
1.引用一定要初始化;
2.一个变量可以有多个引用;
3.一旦引用一个实体,就不能再引用其他实体;
引用底层使用指针实现的,所以本质上还是传地址,并不是传值。
void test1()
{
int a = 0;
int& b = a;//引用
//int& c;//引用一定要初始化
int x = 10;
b = x;//这里是赋值
}
以下是引用的使用场景:
代码如下:
void Swap(int& left, int& right)//这样传参,left就是实参的别名,而不是实参的拷贝,所以left改变,实参也会跟着变
{
int tmp = left;
left = right;
right = tmp;
}
代码如下:
//传引用返回
//传值返回时,返回的值是临时拷贝的值
int& Count()
{
static int n = 9;//n是静态变量,存放在静态区,函数结束时栈帧销毁,n不会销毁
//若不是静态变量,则传引用返回时,count的栈帧销毁,传引用返回可能会出现错误
n++;
return n;
}
代码如下:
int main()
{
int a = 10;
int& b = a;
cout << typeid(a).name() << endl;//打印变量类型
cout << typeid(b).name() << endl;
const int c = 9;
//int& d = c;//因为c是const类型的,不可修改,这叫做权限放大
const int& d = c;//这是正确写法
int e = 5;
const int& f = e;//这是权限缩小,是允许的
int ii = 1;
double dd = (double)ii;//强制类型转换并不会改变变量ii的类型,中间有一个临时变量
//double& rdd = ii;//引用时中间也是临时变量,而临时变量是具有常量性质的,相当于const,所以这里是权限放大
const double& rdd = ii;//正确写法
const int& x = 10;//const也可以引用常量,具有很强的接受度
return 0;
}
1.相当于c中的宏,在符合条件的情况下,在调用的地方展开;
2.需要直接定义在.h文件中,声明和定义不能分离,否则会出现连接错误;
3.inline对于编译器来说只是一个建议,一般建议将函数规模小的、不是递归、频繁调用的函数用inline修饰。
inline int Add(int x, int y)
{
return x + y;
}
auto关键字 – 自动推导类型;
auto不能作为函数的参数;
auto不能直接用来声明数组;
int TestAuto()
{
return 10;
}
int main()
{
int a = 0;
auto b = a;//使用auto定义变量时,必须将其初始化
auto c = 'a';
auto d = TestAuto();
cout << typeid(b).name() << endl;
cout << typeid(c).name() << endl;
cout << typeid(d).name() << endl;
return 0;
}
auto的用法:范围for遍历数组(C++11)
int main()
{
int a[] = { 1,2,3,4,5 };
for (auto e : a)
{
cout << e << " ";
}
}