目录
1.程序的内存模型
1.1代码区:存放所有代码
1.2全局区:存放全局变量和静态变量以及常量(字符串常量、全局常量const修饰)
1.3栈区:由编译器自动分配和释放,存放函数的参数值、局部变量等
??
1.4堆区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收
1.5 new运算符
2、引用:给变量取别名
2.1 引用的基本语法
2.2 引用注意事项
2.3 引用做函数参数
2.4引用做函数返回值
2.5引用的本质
2.6 常量引用
3、函数
3.1函数默认参数
3.2函数占位参数
3.3函数重载:函数名可以相同,提高复用性
3.3.1函数重载的注意事项
1.程序的内存模型
意义:不同区域存放的数据,赋予不同的生命周期,给我们更大的灵活编程
在程序编译后,生成了exe可执行程序,未执行该程序前分为两个区域:代码区、全局区。
1.1代码区:存放所有代码
存放cpu执行的机器指令
代码区是共享的,共享的目的是对于频繁被执行的程序,只需要在内存中有一份代码即可
代码区是只读的,使其只读的原因是防止程序意外地修改了它的指令
1.2全局区:存放全局变量和静态变量以及常量(字符串常量、全局常量const修饰)
该区域的数据在程序结束后由操作系统释放
程序运行后分配的区域:
1.3栈区:由编译器自动分配和释放,存放函数的参数值、局部变量等
注:不要返回局部变量的地址,栈区开辟的数据在函数执行完后自动释放
//不要返回局部变量的地址
int* func(int b) {
b = 100;
int a = 10;//局部变量 存放在栈区,栈区的数据在函数执行完后自动释放
return &a;//返回局部变量的地址
}
int main() {
//接受func函数的返回值
int *p = func(5);
cout << *p << endl;//第一次打印正确的数字,是因为编译器做了保留
cout << *p << endl;//第二次打印乱码
system("pause");
return 0;
}
?
1.4堆区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收
在c++中主要利用new在堆区开辟内存
知识点tips:
利用new关键字,可以将数据开辟到堆区
指针本质也是局部变量,指针保存的数据是在栈区
1.5 new运算符
new 数据类型
利用new创建的数据,会返回该数据对应的类型的指针
释放内存用delete
int* func() {
//利用new关键字,可以将数据开辟到堆区
//指针本质也是局部变量,指针保存的数据是在栈区
//new 返回指针
int *p = new int(10);
return p;
}
int main() {
int *p = func();
cout << *p << endl;
delete p;//释放内存
//cout << *p << endl;//这行代码是非法操作,运行会报错,因为delete已释放内存了
system("pause");
return 0;
}
//在堆区利用new开辟数组
void test() {
//创建数组
int *arr = new int[10];//代表数组有10个元素
for (int i = 0; i < 10; i++) {
arr[i] = i + 10;//赋值 10~19
}
//释放数组
delete[] arr;
}
2、引用:给变量取别名
2.1 引用的基本语法
数据类型 &别名 = 原名
int &b = a;//引用
2.2 引用注意事项
引用必须初始化:
int?&b;//是错误的, 引用必须初始化
引用在初始化后,不可以改变:
int a = 10;
int &b = a;//引用初始化
int c = 20;
//int &b = c;//运行时会报错,显示“b:重定义,多次初始化”
或者
int a = 10;
int &b = a;//引用
int c = 20;
b = c;//是赋值操作,此时打印a,b,c的值为20
2.3 引用做函数参数
函数传参时,可以利用引用的技术让形参修饰实参
可以简化指针修改实参
例:两数交换
//值传递
void swap01(int a,int b) {
int temp = a;
a = b;
b = temp;
cout << "值传递,a:" << a << " b:" << b << endl;
}
//地址传递
void swap02(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
//引用传递
void swap03(int &a, int &b) {
int temp = a;
a = b;
b = temp;
}
int main() {
int a = 10, b = 20;
swap01(a,b);
cout << "值传递,a:" << a << " b:" << b << endl;
swap02(&a, &b);
cout << "地址传递,a:" << a << " b:" << b << endl;
swap03(a, b);//引用参数 形参会修饰实参,相当于int &a 是 a 的一个别名
cout << "引用传递,a:" << a << " b:" << b << endl;
system("pause");
return 0;
}
通过引用参数产生的效果同按地址传递是一样的,引用的语法更加清晰更加简单
2.4引用做函数返回值
不要返回局部变量的引用:
int& test01() {
int a = 10;//局部变量,栈区
return a;
}
int& test02() {
static int a = 10;//静态局部变量,全局区
return a;
}
int main() {
int & ref = test01();//用引用的方式返回
cout <<"ref = "<< ref << endl;
cout << "ref = " << ref << endl;//乱码
int & ref1 = test02();//ref别名
cout << "ref1 = " << ref1 << endl;
cout << "ref1 = " << ref1 << endl;
system("pause");
return 0;
}
函数调用可以作为左值
同上:
int & ref1 = test02();//ref别名
test02() = 1000;
如果函数的返回值是引用,这个函数调用可以作为左值
2.5引用的本质
引用的本质在c++内部实现是一个指针常量
//引用的本质
int a = 10;
int &ref = a;//即int* const ref = &a,ref存放的是a的地址
ref = 20;//ref是引用,*ref=20;
cout << "a = " << a << endl;//结果是20
cout << "ref = " << ref << endl;//结果是20
2.6 常量引用
int &ref = 10;//这行代码是错误的
const int &ref = 10;//编辑器优化代码,int temp = 10;const int& ref = temp;
3、函数
3.1函数默认参数
在c++中,函数的形参列表是可以有默认值的
如果函数声明有默认参数,函数实现不能有默认参数
3.2函数占位参数
C++中函数的形参列表里可以有占位参数,用来做参数,调用函数时必须填补该位置
返回值类型 函数名 (数据类型){}
3.3函数重载:函数名可以相同,提高复用性
函数重载满足条件:(函数的返回值不可以作为函数重载的条件
同一个作用域下
函数名称相同
函数参数类型不同 或者 个数不同 或者 顺序不同
void func() {
cout << "func的函数重载" << endl;
}
void func(int a) {
cout << "func的函数重载1" << endl;
}
void func(double a,int b) {
cout << "func的函数重载2" << endl;
}
void func(int a, double b) {
cout << "func的函数重载3" << endl;
}
func();
func(10);
func(20.1,5);
func(20, 5.1);
3.3.1函数重载的注意事项
引用作为重载条件
函数重载碰到函数默认参数
?写在最后:最近几天进度有点慢了,但会督促自己每天都要有一点进步!!!
|