C++学习(1)

稳扎稳打,记录点滴成长

1. 内存分区模型

1.1 程序运行前

程序编译后,生成了可执行程序,未执行该程序前,分为两个区域

注意1:常量分为 "字符串常量" 和 "被const修改的"常量两种

注意2:"被const修改的"常量 又分为全局常量(放全局区)和局部常量。

1.2 程序运行后

形参数据也会放在栈区

1.3 new操作符

// 堆区开辟一个存放10的整型数;并返回其地址
int *p = new int(10);
// 释放这个开辟的数
delete p;


// 堆区开辟一个有6个整型数成员的数组;并返回地址
int *arr = new int[6];
// 释放这个开辟的数组;注意释放数组时添加[]
delete[] arr;

2. 引用

2.1 引用的基本使用

2.2 引用的注意事项

1. 引用必须要初始化

int &b; //错误的

int a = 10;
int &b = a; //正确的

2. 引用一旦初始化后就不可以更改了

//延续上面代码
int c = 3;
b = c; //这是赋值操作不是原来的意思了,不是更改别名 =》引用不可以更改

2.3 引用做函数参数

作用:函数传参时,可以利用引用的技术让形参修饰实参

优点:可以简化指针

通过引用参数产生的效果同地址传递是一样的。引用的语法更清楚简单。

2.4 引用做函数返回值

作用:引用是可以作为函数的返回值存在的

注意:不要返回局部变量的引用

int& Function(void)
{
    int a = 10;
    return a;
}
int main()
{
    int &ret = Function(); //错误,就和值传递的方式一样,空间已经被释放了
}

用法:函数调用作为左值

int& Function()
{
    static int b = 66; //静态变量存放再全局区,程序结束后由系统释放
    return b;
}

int main()
{
    int &ret2 = function();
    cout << "ret2  = " << ret2 << endl;

    function() = 6666; //做左值得本质,就是相当于a = 6666 这样的一个赋值操作
    cout << "ret2  = " << ret2 << endl;

    return 0;
}

//结果
//ret2  = 66
//ret2  = 6666

2.5 引用的本质

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

引用一旦被初始化,就不可以发生改变

int main()
{
    int a = 10;
    int &data = a; // 等于常量指针int* const ref = &a, 也说明了引用不可更改的原因

    ref = 20; // 等于 *ref = 20;

    func(a);

    return 0;
}

void func(int& ref) // int* const ref = &
{
    ref = 100; // *ref = 20;
}

2.6 常量引用

作用:常量引用主要用来修改形参,防止误操作

在函数形参列表中,可以加const修饰形参,防止形参改变实参

3 函数提高

3.1 函数默认参数

int main()
{
    function(10, 10, 10); //由默认参数自己重新传覆盖它可以,结果 = 30
    function(10); //只传一个也可以,传值是从左至右传,结果 = 60
}

int function(int a, int b = 20, int c = 30)
{
    return a + b +c;
}

//注意1:默认参数和传值相反,依次从右至左,不可以跳跃
int function(int a, int b = 20, int c) // 类似这样就是错误的
{
    return a + b +c;
}

//注意2:声明和实现只能有一个有默认参数
// 假如像如下代码,计算机将无法判断是采用声明的还是实现的
int function(int a = 10, int b = 20);

int function(int a = 20, int b = 10)
{
    return a + b;
}
// 以上这种错误,成为二异性,需要程序员自己注意,故统一采用声明处作为默认参数的初始化

3.2 函数占位参数

// 占位参数:函数名 (数据类型) {}

int function(int a = 20, int) // 其中第2个int就是一个占位参数
{
    cout << "this is function" << endl;
}

// 占位参数可以有默认参数。例如如下:
int function(int a = 20, int = 10) // 其中第2个int就是带默认参数的占位参数
{
    cout << "this is function too" << endl;
}

int main()
{
    function(10, 10); // 调用时必须传入与之匹配的整型参数才可以正确调用

    function(10); // 调用时可以不匹配默认参数相关位置
}

3.3 函数重载

3.3.1 函数重载概述

作用:函数名相同,可以提高函数复用性

// 函数重载
// 函数名相同
// 函数参数的类型、个数或者顺序任何一个不同即可重载,代码就不演示了

// 注意:不可以用函数返回值作为函数重载,例如下面的两个函数
void function(int a, char *b)
{
    cout << "this is function A" << endl;
}
int function(int a, char *b)
{
    cout << "this is function A" << endl;
}

// 为什么?
// 我理解,返回值已经是函数的结果了,但在执行时,计算机已经分辨不出该调用谁了
// 故,返回值不可以作为函数重载
3.3.2 函数重载注意事项
  • 引用作为重载条件
  • 函数重载碰到函数默认参数
// 引用作为重载条件

void function(int &a)
{
    cout << "function(int &a)" << endl;
}

void function(const int &a)
{
    cout << "function(const int &a)" << endl;
}

// 对于上面两个函数,因为int 和 const int 的区别,所以是可以发生函数重载的

int main()
{
    int a = 10;
    // 这个函数调用的是第一个function
    // 因为a是一个变量,可读可写,所以计算机会走第一条函数
    function(a); 


    // 如果传个常量值,就会调用第二条函数,原因如下:
    // 原因1:因为10是一个可读不可写的
    // 原因2:对于函数1,相当于int &a = 10 ,这是不合法的
    // 但对于函数2,因为加了const =》取一个临时int temp = 10; const int &a = &temp,是合法的
    function(10); 
}
//函数重载碰到函数默认参数

void function(int a, int b = 10)
{
    cout << "function(int a, int b = 10)" << endl;
}

void function(int a)
{
    cout << "function(int a)" << endl;
}

// 调用时,下面方式调用,函数不知道走上面那条
// 这个就是默认参数引起的 二义性,会报错
// 故,在使用函数重载的时候,尽量不要使用默认参数
function(10);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值