一.命名空间
1.命名冲突
#include<stdio.h>
#include<stdlib.h>
int rand = 0;
int main()
{
printf("%p\n", rand);
return 0;
}
全局变量"rand"跟库里面的"rand"冲突,为了解决这一问题,C++引入了命名空间
#include<stdio.h>
#include<stdlib.h>
namespace peach //命名空间域
{
int rand = 0;
}
int main()
{
printf("%p\n", rand);//标准库的rand
printf("%p\n", peach::rand);//命名空间的rand
return 0;
}
定义一个命名空间,将所用的变量放在命名空间里,然后用“空间名”+“:”进行调用
2.命名空间域
不同的域可以定义同一个名字
#include<stdio.h>
#include<stdlib.h>
int a = 0;//全局域
int main()
{
int a = 1;//局部域
printf("%d\n", a);//a的值为1
printf("%d\n", ::a);//a的值为0
// ::域作用限定符
return 0;
}
#include<iostream>
//using namespace std;
int main()
{
//流插入
std::cout << "Hello world" << std::endl;
std::cout << "Hello world" << "\n";
//自动识别类型
int i = 11;
double d = 11.11;
/*printf("%d,%f\n", i, d);
std::cout << i << "," << d << std::endl;*/
//scanf("%d %f", &i, &d);
std::cin >> i >> d;//>>流提取
std::cout << i << "," << d << std::endl;
return 0;
}
二.输入输出
">>"--流提取,也就是输入
"<<"--流插入,也就是输出
C++能自动识别变量的类型,所以输出的时候会输出变量对应类型的值
#include<iostream>//IO流
using namespace std;
int main()
{
//特点:类型自动识别
int i;
double d;
// >>流提取--输入
cin >> i >> d;
// <<流插入--输出
cout << i << endl;// endl=='\n'--换行
cout << d << endl;
//兼容了C语言
printf("%d %.2lf\n", i, d);
cout << "hello world" << endl;
return 0;
}
三.缺省参数
函数未传参则使用临时变量
void Func1(int a = 0)//函数未传参则使用a=0
{
cout << a << endl << endl;
}
1.全缺省
需要从做往右连续给参数
void Func2(int a = 10, int b = 20, int c = 30)
{
cout << "a=" << a << endl;
cout << "b=" << b << endl;
cout << "c=" << c << endl << endl;
}
int main()
{
//全缺省从左往右给参数
Func2();
Func2(1);
//Func2(, 1, );//从左往右给,这种情况是错误的
Func2(1, 2);
Func2(1, 2, 3);
}
2.半缺省
void Func3(int a, int b = 10, int c = 20)//必须从右往左连续缺省,不能间隔
{
cout << "a=" << a << endl;
cout << "b=" << b << endl;
cout << "c=" << c << endl << endl;
}
int main()
{
Func3(1);
Func3(1, 2);
Func3(1, 2, 3);
}
3.缺省的处理
1.缺省可以提前开好空间,再插入数据时避免扩容,提高了效率
2.缺省参数不能在声明和定义中同时出现
3.分离定义时:声明给缺省参数
四.函数重载
1.定义
C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表必须不同(参数个数、类型、顺序)
2.样例
int Add(int left, int right)
{
return left + right;
}
double Add(double left, double right)
{
return left + right;
}
3.错误使用
<1>.顺序不同的前提是类型不同
double Add(double left, double right)
{
return left + right;
}
double Add(double right, double left) //顺序不同的前提是类型不同
{
return left + right;
}
<2>.返回值不同不构成重载
int Add(short left, short right)
{
return left + right;
}
short Add(short left, short right)
{
return left + right;
}
4.作用
函数重载的重要作用:让用的地方很方便,就像用同一个函数一样
void Swap(int* p1, int* p2)
{
int tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
void Swap(double* p1, double* p2)
{
double tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
int main()
{
int a = 1, b = 2;
double c = 1.1, d = 2.2;
Swap(&a, &b);
Swap(&c, &d);
//实质上运用了函数重载
cout << a;
cout << c;
}
5.C++如何支持函数重载的
C++有新的函数命名规则
参考上面的Swap函数来说,C++会把Swap函数命名成"Swap"+"变量类型的首字母"也就是Swapii和Swapdd来区分
五.引用
1.概念
引用就是给变量取别名
要求:
1.引用在定义是必须初始化 int a=1; int& b=a;
2.一个变量可以有多个引用 int& b=a; int& c=a; int& d=c;
3.一旦引用一个实体,再不能引用其他实体 int x=10; b=x;-->x赋值给b
2.应用
<1>.做参数 -- a 输出型参数 b 大对象传参,提高效率
void Swap(int& r1, int& r2)
{
int tmp = r1;
r1 = r2;
r2 = tmp;
}
typedef struct SeqList
{
//...
}SL;
void SLPushBack(SL& s, int x)
{
//...
}
int main()
{
int a = 0, b = 2;
Swap(a, b);//要么传a,b的地址,要么对a,b进行引用
SL sl;
SLPushBack(sl, 1);
SLPushBack(sl, 2);
SLPushBack(sl, 3);
return 0;
}
<2>.做返回值 -- a 输出型返回对象,调用者可以修改返回对象 b 减少拷贝,提高效率
错误样例
int& Count()
{
int n = 0;
n++;
return n;
}
int main()
{
int& ret = Count();
cout << ret << endl;
cout << ret << endl;
cout << ret << endl;
return 0;
}
ret的结果是未定义的,如果栈帧结束时,系统会清理栈帧置成随机值,那么这里ret的结果就是随机值
结论:上面程序使用引用返回本质是不对的,结果是没有保障的,取决于编译器
总结:出了函数作用域,返回对象就销毁了
那么一定不能用引用返回,一定要用传值返回
正确样例
int& Count()
{
static int n = 0;
n++;
return n;
}
int main()
{
int& ret = Count();
cout << ret << endl;
cout << ret << endl;
return 0;
}
3.const引用
void func1(int n)
{
;
}
void func2(int& n)
{
;//如果使用引用传参,函数内如果不改变n,那么建议尽量用const引用传参
}
void func3(const int& n)
{
;
}
1.权限平移
权限的平移
//int a = 10;
//int& b = a;
2.权限放大
//权限放大
const int c = 20;
//int& d = c;//error
const int& d = c;//平移权限
3.权限缩小
权限缩小
//int e = 30;//可读可写
//const int& f = e;//只可读