C++兼容C语言
命名空间:namespace
标准库的东西都放到std。
using namespace std;
展开命名空间。
意义:补C语言的坑,弥补不足。没有解决命名重复的问题
命名冲突问题
命名空间namespace后面定义一个名字,名字是一个域,可以把其保护起来
namespace ljq
#include
#include
namespace ljq
{
int rand = 0;
}
int main()
{
printf("%d", rand);
return 0;
}
using namespace ljq;//全局域里找
//打印的是函数名,是地址,作为函数名走的
C语言中同一个域不能定义同一个变量,不同的域可以定义
int a=0;//全局域
int main()
{
int a=1;
printf("%d",a);//就近原则,局部优先
printf("%d", ::a);//::域作用限定符,指定去左边的域找。空白表示全局域
return 0;//输出1
}
//用库的std命名空间
#include
int main()
{
std::cout << "hello world" <<std:: endl;//std:进行指定访问
return 0;
}
#include
using std::cout;//把std中的cout和endl放到全局里
using std::endl;
int main()
{
std::vector<int> v;//指定
v.push_back(1);//push_back:进行尾插数据
cout<<"hello world"<<endl;
return 0;
}
可以定义变量,函数,类型
int a;
int Add(int left,int right)
{
return left+right;
}
嵌套
namespace N2
{
int a;
int b;
int Add(int left,int right)
{
return left+right;
}
namespace N3
{
int c;
int d;
int Sub(int left,int right)
{
return left-right;
}
}
}
同一工程中允许存在多个名称相同的命名空间,编译器最后会合成同一个命名空间中
namespace N1
{
int Mul(int left,int right)
{
return left*right;
}
}
C++可以自动识别类型
IO流
#include
#include
using namespace std;
int main()
{
int i;
double d;
cin >> i >> d;
cout << i << endl;
cout << d << endl;
return 0;
}
endl:\n
cin:istream类型对象
cout:ostream类型对象
特点:自动识别类型
.>>:流提取
<<:流插入
缺省参数:声明参数时可以给形参缺省值。
觉得C语言不好用,C加加补的。
#include
#include
using namespace std;
void Func(int a)//形参
{
cout << a << endl;
}
int main()
{
Func(1);
Func(2);
Func(3);//传一个实参给形参
return 0;
}
void Func(int a=0)
//缺省参数,备胎
//传了参数没关系,没传写缺省值0去传参
#include
#include
using namespace std;
void Func(int a = 10,int b = 20,int c=30)
{
cout << "a= " <<a<< endl;
cout << "b= " << b << endl;
cout << "c= " << c << endl<<endl;
}
int main()
{
Func(1,2,3);
Func(2);
Func();
return 0;
}
struct Stack
{
int* _a;
int _top;//前面的_为了更好的区分
int _capacity;//之前全部初始化为空不好
//1.扩容有代价
//2.初始化为0时扩容扩2倍仍为0
};
void StackInit(struct Stack* ps,int capacity=4)//半缺省
{
ps->_a=()malloc(sizeof(int)*capacity);//capacity:默认第一次要开的空间
//。。。检查
ps->_top=0;
ps->_capacity=capacity;
}
int main()
{
struct Stack st1;
StackInit(&st1,100);//知道一定会插100个,就会传参数100
//提前开好空间,插入数据避免扩容
}
缺省参数不能在函数声明和定义的位置同时出现
分离定义时,以声明为准,声明说的算。
也是觉得C语言不好用,C加加补的。
函数重载:一词多义应该可以区分。
函数的一种特殊情况。C++允许在同一作用域中声明几个功能相类似的同名函数。这些同名函数的形参列表(参数个数或类型或顺序)必须不同,常用来处理实现功能类似数据类型不同的问题。
参数类型不同:
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;
}
double Add(double left, double right)
{
return left + right;
}
int Add(double left, double right)
{
return left + right;
}返回值不同不构成重载。调用时无法区分。只有参数不同才构成
int main()
{
cout << Add(1, 2) << endl;
cout << Add(1.1, 2.2) << endl;
return 0;
}
函数重载真正的意义:让用的地方很方便,就像用同一个函数一样
int main()
{
int a = 0;
int& b = a;//引用,共用同一空间
cout << &a << endl;
cout << &b << endl;//取地址
return 0;
}
int main()
{
int a = 0;
int& b = a;
int x=20;
//
b=x;//b是x的别名?还是x赋值给b?是赋值
}
引用使用场景:
1.做参数
a.一般做输出型参数
void Swap(int& r1, int& r2)//引用,r1是a的别名,r2是b的别名
{
int tmp = r1;
r1 = r2;
r2 = tmp;
}
int main()
{
int a = 0, b = 2;
Swap(a, b);
return 0;
}
b.大对象传参,提高效率
引用不开空间
2.引用可做返回值
a.输出型返回对象,调用者可以修改返回对象
int& Count()//传值返回
{
static int n = 0;
n++;
//...
return n;//用n的拷贝做表达式的返回值
}
int main()
{
int ret = Count();
return 0;
}
传引用返回
不产生拷贝
int& Count()//返回n的别名
引用返回的语法:返回返回对象的别名
前提:
出了函数作用,返回对象就销毁了。那么一定不能引用返回,一定要用传值返回
什么时候可以用引用返回?
出了作用域n还在,可以引用返回
下面的场景可以用
int& Count(){
static int n = 0;
n++;
//...
return n;
}
使用引用返回
减少拷贝,提高效率
//Stack.h
#pragma once
#include
#include
using namespace std;
void StackInit(struct Stack* ps, int capacity = 4);//声明
//引用返回的场景
typedef struct SeqList
{
int* a;
int size;
int capacity;
}SL;
void SLInit(SL& s, int capacity = 4);
void SLPushBack(SL& s, int x);
//顺序表支持一个修改顺序数据的函数
//void SLModity(SL& s, int pos, int x);
int& SLAt(SL& s, int pos);
//Stack.cpp
#include "Stack.h"
void StackInit(struct Stack* ps, int capacity)
{
ps->a = (int*)malloc(sizeof(int) * capacity);
ps->top = 0;
ps->capacity = capacity;
}
void SLInit(SL& s, int capacity )
{
s.a = (int*)malloc(sizeof(int) * capacity);
assert(s.a);
s.size = 0;
s.capacity = capacity;
}
void SLPushBack(SL& s, int x)
{
if (s.size == s.capacity)
{
//
}
s.a[s.size++] = x;
}
int& SLAt(SL& s, int pos)//引用返回,可随意修改
{
assert(pos >= 0 && pos <= s.size);
return s.a[pos];//关注这个对象,只要在堆上,出了作用域还在可以用引用返回。和其他无关
}
//Test.cpp
#include "Stack.h"
int main()
{
SL sl;
SLInit(sl);
SLPushBack(sl, 1);
SLPushBack(sl, 2);
SLPushBack(sl, 3);
SLPushBack(sl, 4);
for (int i = 0; i < sl.size; ++i)
{
cout << SLAt(sl, i) << " ";
}
cout << endl;
SLAt(sl, 0)++;
SLAt(sl, 0) = 10;
for (int i = 0; i < sl.size; ++i)
{
cout << SLAt(sl, i) << " ";
}
cout << endl;
return 0;
}