嵌入式养成计划-36----C++引用--const--函数重载--结构体--类

八十、 引用

80.1 概念

  • 引用是给目标取了个别名。
  • 引用与目标,它俩的地址一样

80.2 格式

  • 数据类型 &引用名 = 同类型的变量名;
    数据类型 &引用名 = 同类型的变量名;
    eg:
      int a;
      int &b = a; //b引用a,给a取个别名叫b
    

80.3 数组的引用

80.3.1 概念

  • 给数组取个别名

80.3.2 实例

#include <iostream>
using namespace std;
int main()
{
    int a[5] = {10,20,30,40,50};
    //数组指针
    int (*p)[5] = &a;

    //数组引用
    int (&b)[5]  = a; //给a 数组取个别名叫b
    cout << a[4] << endl;

    b[4] = 9999;  // ==>  a[4] = 9999
    cout << a[4] << endl;
    return 0;
}

80.4 函数的引用

  • 给函数取个别名

80.5 结构体中有引用成员

  • 如果结构体中有引用成员,那么使用这样结构体类型定义变量时,必须初始化,否则报错。

80.6 实例

#include <iostream>
using namespace std;
//结构体中有引用
struct student{
    int id;
    string name;
    float &socre;
};

int my_get_max(int a, int b){
    return a > b ? a : b;
}
//函数重载
//参数列表不同,与返回值类型无关
double my_get_max(double a, double b){
    return a > b ? a : b;
}

int main()
{
    int arr[10] = {1, 2, 3};
    //数组的引用
    int (&aa)[10] = arr;
    aa[1] = 0;
    for(int i = 0; i < 3; i++)
        cout << "aa[" << i << "] = " << aa[i] << endl;

    //函数的引用
    int (&get_max)(int , int) = my_get_max;
    cout << get_max(10, 20) << endl;

    //函数指针,调用重载的函数
    double (*get_max_double)(double , double) = my_get_max;
    cout << get_max_double(10.23, 20.12) << endl;

    //结构体中有引用
    //在声明时,必须初始化
    float  f = 101;
    struct student s1 = {1, "lalal", f};
    return 0;
}

80.7 传值、传址、传引用

  1. 传值 一定不会改变目标的值
  2. 传址 有可能改变目标的值 具体看代码设计
  3. 传引用 有可能改变目标的值 具体看代码设计
#include <iostream>
using namespace std;
void fun(int a, int b) // int a = a
{
    a++;
    b++;
}
void fun2(int *a, int *b) // int *a = &a
{
    (*a)++;
    (*b)++;
}
void fun3(int &x, int &y) // int &x = a
{
    x++;
    y++;
}
int main()
{
    int a = 10, b= 20;
    cout << "a = " << a << "  b = " << b << endl;
    
    fun(a, b);  //传值  一定不会改变目标的值
    cout << "a = " << a << "  b = " << b << endl;

    fun2(&a, &b); //传址  有可能改变目标的值 具体看代码设计
    cout << "a = " << a << "  b = " << b << endl;

    fun3(a, b); //传引用 有可能改变目标的值 具体看代码设计
    cout << "a = " << a << "  b = " << b << endl;
    return 0;
}

80.8 当引用作为函数返回值

  • 当引用作为函数返回值,要求变量的生命周期要长。
    1. 静态局部变量
    2. malloc申请的堆区空间
#include <iostream>
using namespace std;
int &fun()
{
    //int num = 10;局部变量不能最为函数的引用返回值
    static int num = 10;
    return num;
}
int main()
{
    cout << fun() << endl;
    int a = 12;
    fun() = a;
    cout << fun() << endl;
    return 0;
}

总结:指针和引用区别 (面试重点)

回答方式:先回答指针与引用分别是啥,然后再回答区别

  • 指针:指针是保存变量的地址的变量
  • 引用:引用就是给变量取个别名
    1. 定义指针是需要占用空间,而引用不需要。
    2. 指针可以先定义后指向,而引用必须定义时初始化。
    3. 指针可以改变(目标)指向,而引用不可以。
    4. 指针有二级指针,而引用没有二级引用(没有引用的引用,原因:引用不是数据类型)
    5. 有指针数组,但没有引用数组(原因:引用不是数据类型)

八十一、 const

  • 修饰变量,表示变量的值不能被修改。
int *p;
int const *p; //指向可变,指向里的值不可变
int * const p; //指向不可变,指向里的值可变
int const * const p; //都不可变

int a = 10;
int const b = 20; // ==> const int b = 20;
int *pa = &a; //可以
int *pb = &b; //不可以 不合法

int const *paa = &a;//可以
int const *pbb = &b;//可以 合法

int a = 10;
int const b = 20; // ==> const int b = 20;

int &aa = a; //可以
int &bb = b; //不可以 不合法
const int &bbb = b; //可以 合法

八十二、 函数重载

82.1 概念

  • 在同一个作用域下,两个以上的函数,取相同的函数名,其参数个数或者类型不同,编译器会根据实参的个数或者类型自动调用哪一个函数,这就是函数重载。
#include <iostream>
using namespace std;
int fun()
{
    return 10+10;
}
int fun(int x)
{
    return x+10;
}
int fun(int x, int y)
{
    return x+y;
}
int main()
{
    int a = 10, b=20;
    cout << fun() << endl;
    cout << fun(23) << endl;
    cout << fun(a,b) << endl;
    return 0;
}

82.2 默认参数的函数定义和使用

  • 实参为空时,按照形参的默认参数来
  • 实参不为空时,按照实参来
void fun2(string name = "hello world") //默认参数
{
    cout << name << endl;
}
int main()
{
    fun2();
    fun2("hello kitty");
    return 0;
}

82.3 哑元(了解)

  • 定义函数的时候,只定义形参类型,不定义形参名,在函数中也不使用该形参。
  • 作用:没有作用,占位。
  • 一般会发生在 :
    • 假设原本函数的功能时三个数运算
    • 现在需要换成俩数运算
    • 那么就把不需要的那个数的位置,参数名不写
    • 且函数功能中也更新成俩数运算的
  • 这样使用 哑元 的方式迭代更新,避免了修改主调处代码(在大量调用该函数时就明白为啥了)
#include <iostream>
using namespace std;
//int fun(int m, int n, int k)
//{
//    return m+n+k;
//}
int fun(int m, int, int k)
{
    return m+k;
}
int main()
{
    cout << fun(1,2,3) << endl;
    cout << fun(1,2,3) << endl;
    cout << fun(1,2,3) << endl;
    cout << fun(1,2,3) << endl;
    cout << fun(1,2,3) << endl;
    return 0;
}

82.4 内联函数


  • 要求:
    1. 函数体要小
    2. 不能有复杂的语句 比如循环、递归
    3. 一般代码不超过5行
  • 目的:提高代码的运行效率,在编译的时候展开
  • 关键字: inline

  • 内联函数和带参宏替换的区别
    1. 内联函数是函数的调用,宏替换就是替换
    2. 内联函数是在编译时展开,宏替换在预处理的时展开

#include <iostream>
using namespace std;

#define MAX(m,n) m>n?m:n

inline int max(int m, int n) //内联函数
{
    return m>n?m:n;
}
int main()
{
    int m = 1;
    int n = 1;
    int c;
    c = max(++m, n);
    cout << "m = " << m << "  n = " << n << "   c = " << c << endl;

    m = 1;
    n = 1;
    c = MAX(++m, n);
    cout << "m = " << m << "  n = " << n << "   c = " << c << endl;
    return 0;
}

八十三、 C++的结构体

83.1 C语言与C++结构体的区别

  1. C语言中结构体,在c++中依然适用。
  2. C++中的结构体中可以函数,C语言中不可以。
  3. C++中在定义结构体类型的时候,可以给变量初始值,C语言中不可以。
  4. C++中在使用结构体类型定义变量时,可以省略关键字struct不写,C语言中不可以。
  5. C++中的结构体中的成员有访问权限,C语言没有访问权限。
  6. C++中的结构体存在继承,C语言没有。
  7. C++中的结构体中有特殊的成员函数,C语言没有。
  • 注意:结构名首字母大写、C++中的结构体的权限默认是共有的
权限 : 	共有权限、	保护权限、	私有权限
		public		protected	private
  • 示例:
#include <iostream>
using namespace std;
struct Student
{
    string name;
    int id = 1001; //可以给定初始值
    double score;
    
    void show() //可以在结构体内部封装函数
    {
        cout << name << endl;
        cout << id << endl;
    }
};
int main()
{
    Student s1; //可以省略关键字struct不写
    s1.name = "zhangsan";
    
    cout << s1.name << endl;
    s1.show();
    return 0;
}

八十四、 C++中的类

  • C++中类是有C++中的结构体演变而来的,只是默认访问权限和默认继承方式以及关键字不同。
  • 类的关键字:class
  • 默认访问权限是私有的。

84.1 格式(语法)

class 类名
{
    public:
        公共的数据成员、成员函数
    protected:
        受保护的数据成员、成员函数
    private:
        私有的数据成员、成员函数
};

84.2 访问权限介绍

  • public:
    该权限是公共权限,表示该权限下的属性(变量)、方法(函数),可以在类内、子类、类外被访问。
    
  • protected:
    该权限是保护权限,表示该权限下的属性(变量)、方法(函数),可以在类内、子类可以被访问,类外不可以被访问。
    
  • private:
    该权限是私有权限,表示该权限下的属性(变量)、方法(函数),只可以类内被访问,子类和类外不可以被访问。
    
  • 一般数据成员权限是私有的private, 成员函数是共有的public ,
  • 成员函数一般是作为接口,供外界使用的。
  • 具体还是要看代码设计。

  • 相关名称:
    • 类里有成员组成,
    • 成员 :数据成员、成员函数
#include <iostream>
using namespace std;
//属性---变量
//方法---函数
//封装 ---- 属性+方法
class Student  //封装了一个学生这样的 类
{
private:
    string name;
protected:
    int id;
public:
    double score;
public:
    void show()
    {
        cout << name << endl; //类内的成员函数,可以访问私有数据成员
        cout << id << endl; //类内的成员函数,可以访问保护数据成员
        cout << score << endl; //类内的成员函数,可以访问共有数据成员
    }
    void init(string n, int i)
    {
        name = n;
        id = i;
    }
};
int main()
{
    Student s1; //用学生这样的类 实例了一个 对象
    s1.score = 99; //共有权限下的成员,可以在类外被访问
    //s1.id = 1001; //保护权限下的成员,不可以在类外被访问
    //s1.name = "zhangsan"; //私有权限下的成员,不可以在类外被访问
    s1.init("张三",1001);
    s1.show();
    return 0;
}

84.3 封装

  • 类的三大属性:封装、继承、多态
    封装:把数据和对数据的处理捆绑在一起的过程,就叫封装 (属性(变量)+方法(函数))

84.4 成员函数中的形参和数据成员同名

  • 表明数据成员是 哪个类的 类名 加 作用域限定符
  • 在每个类里的成员函数(非静态成员函数)都一个隐藏的this指针。
  • this指针,谁使用我,我就指向谁。
#include <iostream>
using namespace std;
class Student
{
private:
    string name;
    int id;
public:
    void init(string name, int id)
    {
//        Student::name = name;
//        Student::id = id;
        this->name = name;
        this->id = id;
    }
    void show()
    {
        cout << "name = " << name << endl;
        cout << "id = " << id << endl;
    }
};
int main()
{
    Student stu1;
    stu1.init("张三",1001);
    stu1.show();

    return 0;
}

84.5 this指针

  • this指针是所有非静态成员函数里的隐藏的一个形参
  • this指针对像本身,谁使用我,我就指向谁。
  • this指针的原型,eg:
    Student * const this;
    
  • 示例 :
#include <iostream>
using namespace std;

class Student {
private:
    int id;
protected:
    string name;
public:
    double score;

    void init(int id, string name){
        this->id = id;
        this->name = name;
    }

    void show(){
        cout << "id = " << this->id << endl;
        cout << "name = " << this->name << endl;
        cout << "score = " << this->score << endl;
};
int main()
{
    Student s1;
    s1.init(1010, "法外狂徒");
    s1.score = 66.6;
    s1.show();
    return 0;
}

84.6 类外定义成员函数

  • 在类内声明函数
  • 在类外进行函数实现 表明属于哪个类的,需要加上类名和作用域限定符
    • eg: 函数返回类型 类名::函数名(形参列表)
#include <iostream>
using namespace std;

class Student {
private:
    int id;
protected:
    string name;
public:
    double score;

    void show();
    void init(int id, string name);
};

void Student::init(int id, string name){
    this->id = id;
    this->name = name;
}

void Student::show(){
    cout << "id = " << this->id << endl;
    cout << "name = " << this->name << endl;
    cout << "score = " << this->score << endl;
}

int main()
{
    Student s1;
    s1.init(1010, "法外狂徒");
    s1.score = 66.6;
    s1.show();
    return 0;
}

小作业 :

自己封装一个矩形类(Rect)
且多文件编译

拥有私有属性:
	宽度(width)、高度(height)

定义公有成员函数:
	初始化函数:void init(int w, int h)
	更改宽度的函数:set_w(int w)
	更改高度的函数:set_h(int h)
	输出该矩形的周长和面积函数:void show()

我写的:

main.cpp

#include "rect.h"

int main(){
	Rect rec;
	rec.init(2, 3);
	rec.show();
	rec.set_w(4);
	rec.show();
	rec.set_h(5);
	rec.show();
	return 0;
}

rect.h

#ifndef __RECT_H__
#define __RECT_H__

#include <iostream>

class Rect {
private:
	// 宽度
	double width;
	// 高度
	double height;
public:
	void init(double w, double h);
	void set_w(double w);
	void set_h(double h);
	void show();
};

#endif

rect.cpp

#include "rect.h"
using namespace std;

void Rect::init(double w, double h){
	this->width = w;
	this->height = h;
}
void Rect::set_w(double w){
	this->width = w;
}
void Rect::set_h(double h){
	this->height = h;
}
void Rect::show(){
	cout << "宽 = " << this->width << " 高 = " << this->height << endl;
	cout << "此矩形周长为 : " << 2 * (this->width + this->height) << endl;
	cout << "此矩形面积为 : " << this->width * this->height << endl << endl;
}

makefile

EXE=Rect
CC=g++
CFLAGs=-c
OBJs+=main.o
OBJs+=rect.o
all:$(EXE)
$(EXE):$(OBJs)
	$(CC) $^ -o $@
%.o:%.c
	$(CC) $(CFLAGs) $^ -o $@
clean:
	rm *.o $(EXE)

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhk___

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值