当前位置: 首页 > news >正文

三、重学C++—CPP基础

上一章节:

二、重学C++—C语言核心-CSDN博客https://blog.csdn.net/weixin_36323170/article/details/146191640?spm=1001.2014.3001.5501

本章代码:

cpp · CuiQingCheng/cppstudy - 码云 - 开源中国https://gitee.com/cuiqingcheng/cppstudy/tree/master/cpp

一、引言

接下来开启 C++ 的学习旅程,这里有一些基础概念看似简单,实则蕴含着诸多重要的特性和应用场景。今天我们就来深入探讨一下 “引用” 和 “结构体” 这两个知识点,特别是将 C++ 中的结构体与 C 语言中的进行对比,帮助大家更好地理解。

二、神奇的引用

1、引用的概念

在 C++ 里,引用就像是一个 “别名”。想象一下,你有一个朋友叫小明,他同时还有个昵称叫 “阿明”,不管你喊 “小明” 还是 “阿明”,回应的都是同一个人。在代码中,变量的引用就是给这个变量另取一个名字,它们指向的是同一块内存空间

比如我们定义一个整数变量 num,然后为它创建一个引用 ref_num:

int num = 10;
int& ref_num = num;

这里引用也是指向一块明确的内存空间,因为这里在定义“引用”时,必须明确其对象。在描述内存空间上是与“指针”类似。

这里 ref_num 就是 num 的引用,对 ref_num 进行操作,就等同于对 num 操作。比如修改 ref_num 的值:

ref_num = 20;
printf("num = %d, ref_num = %d\n", num, ref_num);   // 这里两个值均发生改变

运行结果:

引用的一个重要用途是在函数参数传递中。传统的值传递会创建一个新的副本,占用额外的内存空间。而使用引用传递,就可以直接操作原始数据,提高效率,同时也能方便函数修改传入的参数值

”前面提到引用使用跟原来数据共用同一个内存的数据,那么指针和引用有什么异同,各自使用场景是什么样?“

2、引用/指针

相同点

  • 间接访问数据:引用和指针都能实现对数据的间接访问。引用是变量的别名,对引用的操作等同于对原变量操作;指针存储的是变量的地址,通过解引用操作(*)能访问指针所指向的变量
  • 用于函数参数传递:两者都能在函数参数传递时,避免对大对象进行值传递所带来的开销。使用引用传递或指针传递,函数可以直接操作原始数据,提高程序效率

不同点

  • 定义和初始化:引用在定义时必须初始化,且初始化后不能再引用其他变量,例如 int num = 10; int& ref_num = num; 而指针定义时可以不初始化,初始化后也能重新指向其他同类型变量,如 int num = 10; int *ptr = # 之后还能让 ptr 指向其他 int 类型变量;指针在使用时可以定义多级指针,但是引用使用时,无多级的使用方式;
  • 语法和操作:引用的使用就像普通变量一样,直接操作即可;而指针操作时,需要通过 * 进行解引用访问指向的数据,通过 & 取变量地址。比如修改值,引用是 ref_num = 20; ,指针则是 *ptr = 20; 。
  • 空值处理:引用不能为 nullptr ,因为它必须指向一个有效的对象。而指针可以被赋值为 nullptr ,表示不指向任何对象,在使用指针前通常需要检查是否为 nullptr ,避免空指针错误。
  • 内存占用:一般情况下,引用本身不占用额外内存(仅作为别名),而指针变量本身需要占用一定内存空间(通常为 4 字节或 8 字节,取决于系统的寻址空间),用于存储所指向变量的地址

优势场景

  • 引用的优势场景
    • 函数参数传递:当希望函数能够修改传入的参数值,同时又不想在语法上显得过于复杂时,引用传递是很好的选择。比如 void swap(int& a, int& b) 实现两个整数的交换,简洁直观。
    • 性能差异:引用传递的变量本体内存,使用时直接只用该变量,但是指针使用时存在解引用的操作,需要映射到具体内存中,在绝大数场景下两者差异不明显,但是在两者都能使用的时候建议使用引用。
  • 指针的优势场景
    • 动态内存分配在需要动态分配内存(如使用 new 操作符)时,必须使用指针来管理这些动态分配的内存。例如 int *arr = new int[10]; 动态创建一个包含 10 个整数的数组。
    • 数据结构实现:在实现链表、树等复杂数据结构时,指针用于表示节点之间的连接关系。例如链表节点定义 struct ListNode { int val; ListNode *next; }; ,next 指针指向下一个节点。
    • 灵活的地址操作:当需要进行底层的内存地址操作,或者实现一些复杂的算法(如内存池管理)时,指针能提供更灵活的控制能力。
实例代码:
#include <stdio.h>

int addResut(int &a, int &b)
{
    ++a;
    ++b;
    return a+b;
}

int addResult1(int *a, int *b)
{
    ++(*a);
    ++(*b);
    return *a+*b;
}

void createInt(int **p)
{
    // new 就像是一个 “内存采购助手”,专门帮你从计算机的内存 “仓库” 中获取存储数据的空间,
    // 这里需要代码编写者自己维护这块内存,如果反复申请,不去释放,就会造成内存的不可控即“内存泄漏”
    *p = new int(4);
}

void createInt1(int*& p)
{
    p = new int(8);
}

int main()
{
    {   
        // 引用
        int num = 10;
        int& ref_num = num; // 引用时必须要赋值,如int& ref_num; 这样就是错误的使用方式
        ref_num = 20;
        printf("num = %d, ref_num = %d\n", num, ref_num);   // 这里两个值均发生改变
        // int&& ref_refNum = num;  错误
    
        int a = 4, b = 8;
        int ret = addResut(a, b);
        printf("a = %d, b = %d, ret = %d\n", a, b, ret);   // 这里a, b两个值均发生改变
    
        int ret1 = addResult1(&a, &b);
        
        printf("a = %d, b = %d, ret1 = %d\n", a, b, ret1);   // 这里a, b两个值均发生改变

        int *p = nullptr;
        createInt(&p);                  // 这里指针作为变量,用于创建一个int对象
        printf("*p = %d\n", *p);   

        int *p1 = nullptr;
        createInt1(p1);                 // 这里传引用,指针作为一个变量,引用为这块内存的别名。
        printf("*p1 = %d\n", *p1);  

        // delete:与new是一对一使用的,delete 来 “归还” 给内存 “仓库”
        delete p;
        p = nullptr;
        delete p1;
        p1 = p1;
    }

    return 0;
}

三、结构体

C++ 中的结构体在本质上和 C 语言类似,也是用于组合不同类型的数据。但 C++ 中的结构体功能更强大,它可以包含成员函数,这是 C 语言结构体所不具备的

struct Student {
    char name[20];
    int age;
    float score;
    Student(){}
    Student(char* pNm, int iAge, float fScore)
    {
        strcpy(name, pNm);
        age = iAge;
        score = fScore;
    }
    void printInfo() {
        std::cout << "姓名: " << name << ", 年龄: " << age << ", 成绩: " << score << std::endl;
    }
};

使用方式:

        // 与C语言类似的使用方式
        struct Student stu;
        strcpy(stu.name, "李四");
        stu.age = 19;
        stu.score = 90.0;
        stu.printInfo();
        
        // C++ 中使用方式
        struct Student stu1("Tom", 18, 99);
        stu1.printInfo();

此外,在 C++ 中,结构体和类的语法非常相似,区别在于结构体默认成员访问权限是 public(公共的),而类默认是 private(私有的)

四、总结

C++ 中的引用为我们提供了一种更灵活高效的数据操作方式,而结构体在 C 和 C++ 中既有传承又有发展,C++ 中的结构体拥有更多面向对象的特性。理解这些基础概念,对于深入学习 C++ 语言以及后续的项目开发都有着重要的意义。

相关文章:

  • Tsfresh + TA-Lib + LightGBM :A 股市场量化投资策略实战入门
  • Suno的对手Luno:AI音乐开发「上传参考音频 - 方式二:通过URL的方式」 —— 「Luno Api系列|AI音乐API」第12篇
  • 程序地址空间:深度解析其结构,原理与在计算机系统中的应用价值
  • 【Linux进程通信】————匿名管道命名管道
  • 超详细kubernetes部署k8s----一台master和两台node
  • 【网络】简单的 Web 服务器架构解析,包含多个服务和反向代理的配置,及非反向代理配置
  • Java学习------初识JVM体系结构
  • 格雷码.
  • YOLOV8添加ASPP改进
  • Pyhon第五章01:函数的定义和练习
  • Qt 控件概述 QWdiget 1.1
  • 运维面试题(四)
  • C++|范围for
  • OpenCV基础知识
  • 分类操作-06.根据id删除分类
  • JS基础部分
  • 奇安信二面
  • 北京大学第六弹:《DeepSeek应用场景中需要关注的十个安全问题和防范措施》
  • 【论文阅读】Adversarial Patch Attacks on Monocular Depth Estimation Networks
  • 硬件地址反序?用位操作为LED灯序“纠偏”。反转二进制数即可解决
  • 产假工资是谁出?女职工生育能领多少生育津贴?解答来了
  • 五一假期上海口岸出入境客流总量预计达59.4万人,同比增约30%
  • “80后”蒋美华任辽宁阜新市副市长
  • 中央党校(国家行政学院)举行2025年春季学期第一批进修班毕业典礼
  • 狄威已任国铁集团副总经理
  • 被算法重塑的世界,人与技术如何和谐共处