C++核心编程笔记

C++核心编程

C++面向对象

1.内存分区模型

C++程序执行时会将内存大方向分为__4个区域__

  • 代码区:存放函数体的二进制代码,由操作系统管理
  • 全局区:存放全局变量、静态变量和常量
  • 栈区:由编译器自动分配释放,存放函数的参数值,局部变量等
  • 堆区:由程序员分配和释放,若不释放则程序结束时由系统回收

什么是堆:堆是大家共有的空间,分全局堆和局部堆。全局堆就是所有没有分配的空间,局部堆就是用户分配的空间。堆在操作系统对进程 初始化的时候分配,运行过程中也可以向系统要额外的堆,但是记得用完了要还给操作系统,要不然就是内存泄漏。

什么是栈:栈是线程独有的,保存其运行状态和局部自动变量的。栈在线程开始的时候初始化,每个线程的栈互相独立。每个函数都有自己的栈,栈被用来在函数之间传递参数。操作系统在切换线程的时候会自动的切换栈,就是切换SS/ESP寄存器。栈空间不需要在高级语言里面显式的分配和释放。

1.1程序运行前

在程序编译后,生成了exe可执行程序,在未执行程序前就已经分为两个区域

__代码区:__存放CPU执行的机器指令

  • 代码区是共享的,目的是对于被频繁执行的程序,只需要在内存中复制一份代码
  • 代码区是只读的,防止程序意外修改了其指令

__全局区:__存放全局变量、静态变量和常量

  • 全局区包含了常量区,字符串常量和其他常量也存放在此,但const修饰的局部变量(即局部常量)不在此区域存放
  • 该区域数据在程序结束后由系统释放

2.2程序运行时

**栈区:**由编译器自动分配释放,存放函数的参数值,局部变量等

注意事项:不要返回局部变量的地址,栈区开辟的数据由编译器自动释放

例:

int* func()
{
    int a = 10;
    return &a;		//错误
}

**堆区:**由程序员分配释放,未释放的在程序结束时由系统回收

使用内存分配与释放关键字new/delete管理内存

2.3new/delete关键字

语法:new 数据类型(初始化值);,初始化赋值可以没有,返回值为该数据类型的指针

new 数据类型[数组元素个数];,为数组开辟连续空间,返回值为连续空间的首地址

delete 指针;,将指针指向的内存空间释放

delete[] 数组指针;,将指针指向的数组空间释放

2.引用

https://www.cnblogs.com/mlgjb/p/8821340.html

引用的本质在c++内部实现是一个指针常量

2.1引用的基本使用

作用:给变量起别名

语法:数据类型 &别名 = 变量名

**注意:**引用定义时必须同时初始化,引用后名称不能修改

2.2引用作函数参数

效果等同于地址传递,减少了传值过程中的内存占用,比使用指针可读性高

void Swap(int &a , int &b)		//用引用的方式接受参数
{
    int temp = a;
    a = b;
    b = temp;
}

int main()
{
    int a = 10 , b = 20;
    Swap(a , b);		//正常传入参数,注意不能直接传入常量
}

2.3引用作函数返回值

语法:定义函数时在函数名前加&

注意:

  1. 不要返回局部变量的引用
  2. 函数的调用可以作为左值(等效于对函数返回的变量赋值)

2.4常量引用

作用:主要用来修饰形参,防止误操作

用法:用const修饰函数形参

void test(const int& x)
{
    cout << x <<endl;
}
int main()
{
    test( 10 );		//编译器先定义临时变量值为10,再将临时变量传入,只有在const修饰形参时有效
}

3.进阶函数

3.1函数默认参数

在调用函数但未传入参数时,函数形参使用默认参数。默认参数在函数定义时定义

语法:返回值类型 函数名(参数 = 默认值) {函数体}

注意:

  1. 有默认值的参数定义时需要放在最右边,即有默认值的参数右边都必须有默认值
  2. 如果函数声明时规定了默认参数,则函数实现不能再规定默认参数

例:

void main()
{
    int func(int a, int b = 2; int c = 3);		//有默认参数的参数后面全部有默认参数
    cout << func(10 , 20 , 30) <<endl;
}

int func(int a, int b, int c)		//函数实现中不能再次规定默认参数
{
    return a + b + c;
}

3.2函数占位参数

语法:返回值类型 函数名(数据类型){函数体}

当定义了占位参数时,调用函数必须传入相应数据类型的参数,除非定义带默认值的占位参数

例:

void func(int a, int, int = 10)		//三个参数分别为普通参数,占位参数,带默认值的占位参数
{
    return a;
}

3.3函数重载

条件:

  1. 在同一作用域中
  2. 函数名相同
  3. 传入参数的类型,数量,顺序不同(数据类型的数量和顺序)
  4. **注意:**返回值类型不同不能作为函数重载的条件

函数重载注意事项:

  • 引用作为重载条件
void func(int &a)
{
    cout << "func(int &a) used" <<endl;
}
void func(const int &a)
{
    cout << "func(const int &a) used" <<endl;
}
int main()
{
    int var = 10;
    func( var );		//调用func(int &a)
    func( 10 );		//调用func(const int &a)
    return 0;
}
  • 函数重载遇到函数默认参数
void func(int a, int b = 10)
{
    cout << "func(int a, int b = 10) used" <<endl;
}
void func(int a)
{
    cout << "func(int a) used" <<endl;
}
int main()
{
    func( 10 );		//当除去默认参数后两个函数的参数相同时,函数重载出错
    func(10, 20);		//正确
    return 0;
}

4.类和对象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值