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

news2024/11/27 22:42:23

八十、 引用

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)

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1070169.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ps安装遇到问题

安装PhotoShop报错 无法写入注册表值请检查权限(错误代码160)_ps安装无法写入注册表值错误160_Zhac的博客-CSDN博客在Visual Studio中创建DLL项目 打开VS 新建一个项目&#xff1a;文件→→新建→→项目 选择Visual C#类库(.NET Framework)Unity当前只支持最高 3.5版本将UnityE…

MySQL增删查改(进阶1)

一、数据库约束 约束&#xff1a;按照一定条件进行规范的做事&#xff1b; 表定义的时候&#xff0c;某些字段保存的数据需要按照一定的约束条件&#xff1b; 1.null约束 字段null&#xff1a;该字段可以为空&#xff1b;not null&#xff1a;该字段不能为空不指定的话就是…

Bigemap是如何在生态林业科技行业去应用的

选择Bigemap的原因&#xff1a; ①之前一直是使用的谷歌地球&#xff0c;现在谷歌不能使用了就在网上搜索找一款可以替代的软件&#xff0c;工作使用需求还是挺大的&#xff0c;谷歌不能用对工作进展也非常影响&#xff0c;在网上搜索到软件大部分功能都可以满足需求 ②软件卫…

小白自学—网络安全(黑客技术)笔记

目录 一、自学网络安全学习的误区和陷阱 二、学习网络安全的一些前期准备 三、网络安全学习路线 四、学习资料的推荐 想自学网络安全&#xff08;黑客技术&#xff09;首先你得了解什么是网络安全&#xff01;什么是黑客&#xff01; 网络安全可以基于攻击和防御视角来分类…

Unity Golang教程-Shader编写一个流动的云效果

创建目录 一个友好的项目&#xff0c;项目目录结构是很重要的。我们先导入一个登录界面模型资源。 我们先创建Art表示是美术类的资源&#xff0c;资源是模型创建Model文件夹&#xff0c;由于是在登录界面所以创建Login文件夹&#xff0c;下面依次是模型对应的资源&#xff0c…

3D 生成重建004-DreamFusion and SJC :TEXT-TO-3D USING 2D DIFFUSION

3D 生成重建004-DreamFusion and SJC &#xff1a;TEXT-TO-3D USING 2D DIFFUSION 文章目录 0 论文工作1 论文方法1.1论文方法1.2 CFG1.3影响1.4 SJC 2 效果 0 论文工作 对于生成任务&#xff0c;我们是需要有一个数据样本&#xff0c;让模型去学习数据分布 p ( x ) p(x) p(x…

如何查看端口占用(windows,linux,mac)

如何查看端口占用&#xff0c;各平台 一、背景 如何查看端口占用&#xff1f;网上很多&#xff0c;但大多直接丢出命令&#xff0c;没有任何解释关于如何查看命令的输出 所谓 “查端口占用”&#xff0c;即查看某个端口是否被某个程序占用&#xff0c;如果有&#xff0c;被哪…

HDLbits: Shift18

先补充一下算术移位寄存器和按位移位寄存器&#xff1a; SystemVerilog具有按位和算术移位运算符。 按位移位只是将向量的位向右或向左移动指定的次数&#xff0c;移出向量的位丢失。移入的新位是零填充的。例如&#xff0c;操作8’b11000101 << 2将产生值8’b00010100…

【LeetCode高频SQL50题-基础版】打卡第3天:第16~20题

文章目录 【LeetCode高频SQL50题-基础版】打卡第3天&#xff1a;第16~20题⛅前言 平均售价&#x1f512;题目&#x1f511;题解 项目员工I&#x1f512;题目&#x1f511;题解 各赛事的用户注册率&#x1f512;题目&#x1f511;题解 查询结果的质量和占比&#x1f512;题目&am…

拆解CPU的基本结构和运行原理

CPU的基本结构 CPU是一个计算系统的核心 南北桥芯片将CPU与外设连接起来 CPU执行流程 CPU的电路基础 组合电路基本原理 时序电路基本原理 多核成为主流 汇编语言和寄存器 中断的基本原理 中断的产生 中断服务程序 CPU 做为计算机的总司令官&#xff0c;它管理着计算…

NEFU数字图像处理(2)图像增强

一、背景 图像在传输或处理过程中会引入噪声或使图像变模糊&#xff0c;从而降低了图像质量&#xff0c;甚至淹没了特征给分析带来困难&#xff0c;因此要增强特征&#xff0c;进行处理 图像增强按特定的需要突出一幅图像中的某些信息同时&#xff0c;削弱或去除某些不需要的信…

一文带你了解IAM(身份与访问管理)

一文带你了解IAM&#xff08;身份与访问管理&#xff09; 在进入新公司时&#xff0c;领导说让我们改版之后采用IAM的方式进行资源管理&#xff0c;what&#xff1f;IAM是什么&#xff1f;恕我无知了。后来查阅了相关资料才知道。 IAM不仅是一种产品&#xff0c;也是大部分产品…

NewStarCTF 2023 WEEK1|PWN ret2text

拖进IDA&#xff0c;查看 int __cdecl main(int argc, const char **argv, const char **envp) {char buf[32]; // [rsp0h] [rbp-20h] BYREFinit();puts("Welcome to NewStar CTF!!");puts("Show me your magic");read(0, buf, 0x100uLL);return 0; } ma…

Golang 程序漏洞检测利器 govulncheck(三):github 集成方法

上一篇文章详细介绍了 Golang 程序漏洞扫描工具 govulncheck 使用的漏洞数据库&#xff08;Go vulnerability database&#xff09;&#xff0c;本文详细讲解下 Github 项目如何使用 govulncheck。 govulncheck 为 Golang 开发者提供了一种准确可靠的方式来了解程序中可能存在…

matlab高斯消元法求逆

算法实现基本与高斯消元法求解线性方程组相同&#xff0c;同样还是三层循环进行消元和回代&#xff0c;只是增广矩阵的规模由nn1变成了n2n&#xff0c;因此算法复杂度仍然为O(n3)。 A[1,1,2,1;1,2,0,1;1,4,2,1;1,8,2,4]; beye(4); A_b[A,b]; [n,m]size(A_b); for i1:nfor jm:-…

零基础,想做一名网络安全工程师,我可以去哪里学,或者有什么建议?

这应该是全网最全的网络安全扫盲帖了&#xff01;发CSDN也有一段时间了&#xff0c;经常会有朋友在后台问我各种问题&#xff0c;比如“应该如何选方向”、“网络安全前景如何”、“怎么选适合的安全岗位”等等。于是今天借这个问题来给大家好好说说&#xff0c;如果你是零基础…

C++简单上手helloworld 以及 vscode找不到文件的可能性原因

helloworld #include <iostream>int main() {std::cout << "hello world!" << std::endl;return 0; }输入输出小功能 #include <iostream> using namespace std; /* *主函数 *输出一条语句 */int main() {// 输出一条语句cout << &q…

有关java连接数据库报错的解决方案

Ⅰ 报错信息 在使用java连接数据库时&#xff0c;使用下面代码 Class.forName("com.mysql.jdbc.Driver"); Connection connection DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test1", "test1", "test");出现的报错…

Python3入门教程||Python3 SMTP发送邮件

在Python3 中应用的SMTP&#xff08;Simple Mail Transfer Protocol&#xff09;即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则&#xff0c;由它来控制信件的中转方式。 python的 smtplib 提供了一种很方便的途径发送电子邮件。它对 smtp 协议进行了简单的…

转行自学软件测试,8个月成功上岸(艰难的自学历程)

转行学软件测试&#xff0c;最后找到第一份工作&#xff0c;我一共用了八个月。六个半月学习技术&#xff0c;一个半月找到工作。 自学软件测试到就业并不容易&#xff0c;过程中多次想放弃&#xff0c;学习遇到的问题太多自己解决很麻烦加上网络上各种传达行情不好的信息。现…