我的C++学习历程(二)

const链接方式

在C语言中const默认是外部链接

//test.c

const int a = 10;   //C语言中const默认是外部链接

//a.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
    extern const int a; //告诉编译器a在外部
    printf("a = %d \n",a);
    return 0;
}

在C++语言中const默认是部内部链接

//test.cpp

extern const int a = 10; //C++中的const默认内部链接  extern 提高作用域

//a.cpp

#include <iostream>
using namespace std;

int main()
{
    extern const int a;
    cout<<"a = "<<a<<endl;
    return 0;
}

const内存分配情况

1.取地址会临时分配内存

2.加extern 编译器也会给const变量分配内存

3.用变量初始化 const变量

4.自定义分配类型  加const也会分配内存

#include <iostream>
#include <string>
using namespace std;
 
//const分配内存 
//1.取地址会临时分配内存
void test01()
{
    const int m_A = 10;
    int *p = (int *)&m_A;  //会分配临时内存
}

//2.extern 编译器也会给const变量分配内存
//3.用变量初始化 const变量
void test02()
{
    int a = 10;
    const int b = a; //会分配内存
    int *p = (int *)&b;
    *p = 20;    //如果分配内存可以通过指针改变数值
    cout<<"b = "<<b<<endl;
}

//4.自定义分配类型  加const也会分配内存
struct Person
{
    string m_Name;  //姓名
    int m_Age;
};

void test03()
{
    const Person p1 = {"li",22};
    Person *p = (Person *)&p1;
    p->m_Name = "wang";
    (*p).m_Age = 18;
    cout<<"name = "<<p1.m_Name<<endl;
    cout<<"age = "<<p1.m_Age<<endl;
}

int main()
{
    //test02();
    //test03();
    return 0;
}

引用的基本语法

1.引用必须初始化

2.一旦初始化后不可以修改

3.对数组建立引用

#include <iostream>
#include <string>
using namespace std;

//1.引用的基本语法 Type &别名 = 原名
int test01()
{
    int a = 10;
    int &b = a;

    b = 20;
    cout<<"a = "<<a<<endl;
    cout<<"b = "<<b<<endl;
}

//2.引用必须q初始化
int test02()
{
    //int &a; 必须初始化

    int a = 10;
    int &b = a;  //引用初始化后不可以修改
    int c = 20;
    b =c;  //赋值!
}

//3.对数建立引用
int test03()
{
    int array[10];
    for(int i = 0; i < 10; i++)
    {
        array[i] = i;
    }

    //给数组起别名
    int (&pArray)[10] = array;
    for(int i = 0; i < 10; i++)
    {
        cout << pArray[i] <<" ";
    }
    cout << endl;

    //第二种方式取别名
    typedef int(ARRAY)[10];   //一个具有10个元素的int类型的数组
    ARRAY &pArray2 = array;
    for(int i = 0; i < 10; i++)
    {
        cout << pArray2[i] <<" ";
    }
    cout << endl;
}


int main()
{
    //test01();
    test03();
    return 0;
}

参数的传递方式

1.值传递

2.地址传递

3.引用传递

#include <iostream>
#include <string>
using namespace std;

void mySwap(int a,int b)
{
    int temp = a;
    a = b;
    b = temp;
    cout << "mySwap::a= " << a << endl;
    cout << "mySwap::b= " << b << endl;
}

void test01()
{
    int a = 10;
    int b = 20;
    mySwap(a,b);   //值传递
    cout << "a= " << a << endl;
    cout << "b= " << b << endl;
}

//地址转递
void mySwap2(int * a,int * b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}

void test02()
{
    int a = 10;
    int b = 20;
    mySwap2(&a,&b);   //址传递
    cout << "a= " << a << endl;
    cout << "b= " << b << endl;
}

//引用传递   类似地址传递
void mySwap3(int &a,int  &b) //&a = a &b = b
{
    int temp = a;
    a = b;
    b = temp;
}

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

int main()
{
    //test01();
    //test02();
    //test03();
    return 0;
}

引用的注意事项

1.不要返回局部变量的引用

2.如果函数的返回值是引用,那么函数的引用可以作为左值

#include <iostream>
#include <string>
using namespace std;

//引用的注意事项
//引用必须引用一块合法的内存空间
//1.不要返回局部变量的引用

int& doWork()
{
    int a = 10;
    return a;
}

void test01()
{
    //int &a = 10;    //引用必须引用一块合法的内存空间
    int &ret = doWork();  //不要返回局部变量的引用
    cout<<"ret = " <<ret<<endl;
    cout<<"ret = " <<ret<<endl;
}

int& doWork2()
{
    static int a = 10;
    return a;
}

//2.如果函数的返回值是引用,那么函数的引用可以作为左值
void test02()
{
    int &ret = doWork2();
    cout<<"ret = " <<ret<<endl;
    cout<<"ret = " <<ret<<endl;
    //如果函数的返回值是引用,那么这个函数的x调用可以作为左值
    doWork2() = 100;   //相当于 a = 100;
}
int main()
{
    //test01();
    //test02();
    return 0;
}

引用的本质

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

#include <iostream>
#include <string>
using namespace std;

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

//发现是引用,转换为 int *const temp = &b
void testfunc(int& temp)
{
    temp = 100;  //temp是引用,转换为 *temp = 100;
}

void test01()
{
    int a = 10;
    int &b = a;  //自动转换为 int* const b = &a; (指针常量必须初始化)
                 //这也能说明引用为什么必须初始化
    b = 20;      //内部发现b是引用,自动转换为 *b = 20;
    cout << "a = "<<a<<endl;
    cout << "b = "<<b<<endl;
    testfunc(a);
    cout << "change a = "<<a<<endl;
    cout << "change b = "<<b<<endl;

}

int main()
{
    test01();
    return 0;
}

指针的引用

1.用一级指针代替二级指针

#include <iostream>
#include <string>
using namespace std;

//指针的引用

struct Person
{
    int m_Age;
};

void allocatMemory(Person **p) //**p:具体的Person对象   *p:对象的指针   p:指针的指针
{
    *p = (Person *)malloc(sizeof(Person));
    (*p)->m_Age = 15;
}

void test01()
{
    Person *p = NULL;
    allocatMemory(&p);
    cout<<"age="<<p->m_Age<<endl;

}

//利用指针引用来开辟空间

void allocatMemorybyRef(Person* &p)  //指针的引用
{
    p = (Person *)malloc(sizeof(Person));
    p->m_Age = 20;
}

void test02()
{
    Person *p = NULL;
    allocatMemorybyRef(p);
    cout<<"age="<<p->m_Age<<endl;

}

int main()
{
    //test01();
    //test02();
    return 0;
}

常量的引用

1.使用场景,修饰形参为只读(可以通过指针进行修改)

2.用const修饰,会分配空间

#include <iostream>
#include <string>
using namespace std;

//常量的引用


void test01()
{
    //int &ref = 10;   //引用了不合法的内存
    const int &ref = 10;    //加入const后,编译器处理方式: int temp = 10; const int &ref = temp;会分配内存

    //ref = 20;
    int *p = (int *)&ref;
    *p = 30;
    cout<<"ref = "<<ref<<endl;
}

//常量引用的使用场景  用来修饰形参
void showValue(const int &val)
{
    //val += 10;   //如果只是想显示而不修改内容,就需要const修饰形参
    cout<<"val = "<<val<<endl;
}

void test02()
{
    int a = 10;
    showValue(a);
    cout<<"a = "<<a<<endl;
}

int main()
{
    //test01();
    //test02();
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值