C++---面向对象预备
- 一 、内存的分区:
- 1.1 代码区:
- 1.2 全局区:
- 1.3 栈区:
- 1.4 堆区:
- 二 、引用:
- 2.1、引用注意事项:
- 2.2、引用作函数参数:
- 2.3、引用作函数的返回值:
- 2.4、引用的本质:
- 2.5、常量引用:
- 三 、函数提高
- 3.1、函数默认参数值:
- 注意事项:
- 3.2、函数占位参数:(了解)
- 3.3、函数重载:
- 函数重载注意事项:
一 、内存的分区:
1.1 代码区:
所有书写后的代码都会在代码区,存放的是(转化后的二进制代码)
特点:共享,但只读
1.2 全局区:
存放
全局变量(函数体外的变量),
静态变量(普通变量前面加static就是静态变量)
常量(字符串常量和const修饰的全局常变量),这三种在内存种的距离比较近
特点:数据的声明周期由系统决定
相应的:
不在全局区中的数据:局部变量,const修饰的局部常变量
1代码区和 2全局区在程序运行前已经存在
程序运行后的3栈区和 4堆区
1.3 栈区:
特点:编译器自动分配和释放,方法进栈(存放函数的形参和局部变量)
栈区数据的注意事项:
不要返回局部变量的地址,因为函数执行完之后局部变量由编译器自动释放(方法弹栈),返回地址属于非法访问
1.4 堆区:
需要程序员自主进行管理和释放,否则在程序结束时候系统自动回收
堆区开辟空间:有new进堆(利用new关键字在堆区开辟空间)
//**利用new关键字在堆区开辟内存空间**
int *pa=new int(10);//在堆区创建的一个变量是10,**返回的是一个地址**,用指针变量接收
return pa;//返回一个堆区数据的地址(指针pa也是局部变量,也在栈上,指针指向的数据在堆区)
//在堆区创建一个数据并且使用后的释放:
//堆区数据的自主释放:使用关键字delete
void test1()
{
int* p = func();
cout << *p << endl;
cout << *p << endl;
cout << *p << endl;
cout << *p << endl;
cout << *p << endl;
delete p;//释放p指向的内存空间
}
//在堆区创建一个数组,使用后及时释放
void test2()
{
//堆区创建10个整形数据的数组
int *arr=new int[10];//返回首地址
for (int i = 0; i < 10; i++)
{
arr[i] = i + 100;//赋值100-109
}
for (int i = 0; i < 10; i++)
{
cout << arr[i] << endl;
}
//释放数组的时候需要加个中括号[]
delete [] arr;
}
不同区存在的意义:不同的区的数据,有不同的声明周期
二 、引用:
作用:给变量起别名
语法:数据类型 &别名=原名
原名是a,别名是b,一个变量有两个名字(a,b是同一块内存空间)
2.1、引用注意事项:
1 引用必须要初始化
int &b;//错误的,必须说明引用是谁的别名
2 引用在初始化后(某变量的别名)不能再改变
2.2、引用作函数参数:
函数传参的两种方式:(1)值传递(2)地址传递
值传递不能操作实参
地址传递才可以操作实参
引用的作用:函数传参的时候,可以使用引用计数让形参修饰实参(可以对实参进行操作),
优点是不用指针,也可修改实参
数字交换函数:
值传递(是赋值过去的,不能修改实参):
void myswap1(int a, int b)
{
int temp = a;
a = b;
b = temp;
}
修饰实参的两种方法:
(1)地址传递:
void myswap2(int* pa, int* pb)
{
int temp = *pa;
*pa = *pb;
*pb = temp;
}
(2)引用传递:
void myswap3(int &a,int &b)//
{
int temp = a;
a = b;
b = temp;
}
myswap(a,b);//传递实参a,b,对别名操作修改,跟对原名进行操作修改效果一样
2.3、引用作函数的返回值:
作用:引用可以作为函数的返回值
(1)不要返回局部变量的引用:局部变量函数结束后弹栈消失
(2)函数的调用用可以作为左值
2.4、引用的本质:
内部实现是一个指针常量(指针指向不能修改,指向的值可以修改)
因此引用不可以修改
解引用的操作编译器自动实现
2.5、常量引用:
作用:修饰形参,防止误操作
在函数形参列表中,可以加const修饰,防止修改实参
三 、函数提高
3.1、函数默认参数值:
C++中,函数的形参列表可以有默认值
语法:返回值类型 函数名(形参列表=默认值)
{
}
例子:
int func(int a, int b=5,int c=9)
{
return a + b + c;
}
int main()
{
cout << func(1) << endl;
system("pause");
return 0;
}
这样,实参的个数可以小于形参的个数
如果传递了,就使用传递的值,没传才使用默认的值。
注意事项:
1 如果某个位置已经有了默认参数值,那么从这个位置往后从左到右的参数,都必须有默认值
2 函数声明和函数实现中的参数只能有一个有默认参数值
3.2、函数占位参数:(了解)
c++函数参数列表中可以有占位参数,用来占位,调用函数时候必须填补这个占位参数
语法:
返回值类型 函数名 (数据类型)
{
}
3.3、函数重载:
作用:函数名可以相同,提高复用性
函数重载需要满足的三个条件:
(1)同一个作用域下
(2)函数名称相同
(3)函数参数类型不同 / 个数不同 / 顺序不同
注意:函数的返回值不能作为函数重载条件
函数重载注意事项:
1 引用作为重载条件
2 函数重载遇到函数形参存在默认参数值