2.C++基本特性
C++内存分区模型
- 代码区:函数二进制代码
- 全局区:全局变量,静态变量,常量,全局区的数据在程序结束后系统释放
- 栈区:编译器自动分配释放
- 堆区:程序员分配释放,结束系统自动回收
new、delete关键字在堆区操作内存
void test(){
//开辟单独变量
int *p = new int(10);
delete p;
//开辟数组
int *arr = new int[10];
delete[] arr; //释放数组要加中括号
}
引用
int &name2 = name1
给name1变量起了一个name2别名
注意:
-
引用必须初始化(指定具体给谁起别名)
-
引用不可更改
-
不要返回局部变量的引用
//错误写法 int& func(){ //引用的方式返回 int a = 10; //static int a = 10;此为正确写法 可以返回静态局部变量的引用,因为存放在全局区,全局区上的数据在程序结束后系统释放 return a; } int &ref=func();//返回局部变量的引用 cout<<ref<<endl;//结果正常 cout<<ref<<endl;//函数调用结束后栈区空间释放,结果错误
-
如果函数返回是一个引用,那么引用可以作为左值
func()=1000;
引用就是给变量起别名,实质是指针常量(指向不能修改,值可以修改)
常量引用:指向不能修改,值也不能修改
字符串
使用前要包含头文件 #include <string>
string name="liruiyan"
输入
cin>>name
命名空间
//一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中
namespace kxl // kxl 为空间名字
{
}
//嵌套定义
namespace kxl // kxl 为空间名字
{
int rand = 10;
namespace kdl
{
int x = 0;
int rand = 20;
}
}
//使用命名空间 ::
namespace kxl // kxl 为空间名字
{
int rand = 10;
int x = 0;
int y = 1;
namespace kdl
{
int x = 20;
int z = 100;
}
}
int main()
{
printf("%d\n", kxl::rand); // kxl 为命名空间名称,:: 为作用域限定符, rand 为变量名
printf("%d\n", kxl::kdl::x); // 访问kxl命名空间中的kdl里面的x变量
return 0;
}
//空间中某个对象经常使用,可以使用using关键字将空间中某个对象引入,作用域为全局作用域
//using 空间名称::标识符名;
//使用using namespace将整个空间成员引入,该命名空间中所有对象的作用域都是全局作用域,可以直接访问
namespace kxl // kxl 为空间名字
{
int x = 0;
int y = 1;
}
using namespace kxl;
int main()
{
printf("%d\n", x); // x 相当于正常定义的全局变量,可以直接访问
printf("%d\n", y);
return 0;
}
C++标准库中的函数或者对象都是在命名空间std中定义的,使用using namespace std也只为了使用cin
、cout
和endl
等价于
using std::cin;
using std::cout;
using std::endl;
函数高级
函数的默认参数
不传就用默认值,传入参数则用自己的参数
int func(int a,int b = 20,int c = 30){
//函数体
}
- 含有默认值的参数一定写在最后面
- 声明和实现只能有一个有默认参数
函数占位参数
void func(int,int a){
//函数体
}
函数重载
函数重载实际上就是使用同一个名字但是实现可以不同
重载满足条件
- 在同一个作用域
- 函数名称相同
- 参数类型不同/个数不同/顺序不同
- 返回值不可以作为重载条件
两个注意事项
-
引用作为重载条件
void func(int &a){ //A函数 //函数体 } void func(const int &a){ //B函数 //函数体 } func(10) //此时A函数执行非法,引用必须要有内存空间 //此时B函数执行成功,编译器自动开辟了一块空间,并写入10,同时返回该内存空间的引用
-
函数重载碰到默认参数
void func(int a,int b = 10){ //A函数 //函数体 } void func(int a){ //B函数 //函数体 } func(10) //AB函数都可以走,出现二义性,会报错 func(10, 20) //不存在二义性,执行A函数