首页 > 编程语言 >c++学习笔记(二)

c++学习笔记(二)

时间:2024-06-16 17:10:54浏览次数:14  
标签:函数 形参 int 笔记 学习 c++ 指针 ref 引用

c++中的引用

引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字。一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量。


C++ 引用 vs 指针

引用很容易与指针混淆,它们之间有三个主要的不同:

  • 不存在空引用。引用必须连接到一块合法的内存。

  • 一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。

  • 引用必须在创建时被初始化。指针可以在任何时间被初始化。

    ​ int &b; //错误的 int *p; //正确的

引用的基本使用

作用:给变量起别名

语法:数据类型 &别名 = 原名

int main()
{
	int a = 10;
    int &b = a;
    
    std::cout << a << std::endl;
    std::cout << b << std::endl;
    //a = 10; b = 10;
    b = 100;
    std::cout << a << std::endl;
    std::cout << b << std::endl;
    //a = 100; b = 100;
    return 0;
}

引用用于函数参数列表和函数返回值。

引用做函数参数

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

优点:可以简化指针修改实参

void swap01(int a, int b) //值传递
{
    int temp = a;
    a = b;
    b = a;
}
void swap02(int* a, int* b) //指针(地址)传递
{
    int temp = *a;
    *a = *b;
    *b = *a;
}
void swap03(int& a, int& b) //引用传递
{
    int temp = &a;
    &a = &b;
    &b = &a;
}
int main()
{
    int a = 1, b = 2, c = 3, d = 4, i = 5, j = 6;
    swap01(a, b);//值传递形参不改变(修饰)实参
    swap02(&c, &d);//指针传递将地址传递过去,可以改变(修饰)实参
    swap03(i, j);//同样可以改变(修饰)实参,但相比指针传递更间接方便
}

引用做函数返回值

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

用法:函数调用可以作为左值

C++ 函数可以返回一个引用,方式与返回一个指针类似。

当函数返回一个引用时,则返回一个指向返回值的隐式指针。这样,函数就可以放在赋值语句的左边。

double vals[] = {10.1, 12.6, 33.1, 24.1, 50.0};
 
double& setValues(int i) //函数名前加&代表该函数返回引用 
{  
   double& ref = vals[i];    
   return ref;   // 返回第 i 个元素的引用,ref 是一个引用变量,ref 引用 vals[i]
}
 
// 要调用上面定义函数的主函数
int main ()
{
 
   cout << "改变前的值" << endl;
   for ( int i = 0; i < 5; i++ )
   {
       cout << "vals[" << i << "] = ";
       cout << vals[i] << endl;
   }
 /*
改变前的值
vals[0] = 10.1
vals[1] = 12.6
vals[2] = 33.1
vals[3] = 24.1
vals[4] = 50
*/
   setValues(1) = 20.23; // 改变第 2 个元素
   setValues(3) = 70.8;  // 改变第 4 个元素
 
   cout << "改变后的值" << endl;
   for ( int i = 0; i < 5; i++ )
   {
       cout << "vals[" << i << "] = ";
       cout << vals[i] << endl;
   }
/*
改变后的值
vals[0] = 10.1
vals[1] = 20.23
vals[2] = 33.1
vals[3] = 70.8
vals[4] = 50
*/
   return 0;
}

当返回一个引用时,要注意被引用的对象不能超出作用域。所以返回一个对局部变量(保存在栈区)的引用是不合法的,但是,可以返回一个对静态变量(保存在全局区)的引用。

int& func() {
   int q;
   //! return q; // 在编译时发生错误
   static int x;
   return x;     // 安全,x 在函数作用域外依然是有效的
}
#include <iostream>
using namespace std;

// 返回对静态变量的引用
int& getStaticRef() {
    static int num = 5; // 静态变量
    return num;
}

int main() {
    int& ref = getStaticRef(); // 获取对静态变量的引用
    cout << "初始值:" << ref << endl;// 5

    ref = 10; // 修改静态变量的值

    cout << "修改后的值:" << ref << endl;// 10
    cout << "再次调用函数后的值:" << getStaticRef() << endl; // 10

    return 0;
}

引用的本质

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

//发现是引用,转换为 int* const ref = &a;
void func(int& ref)
{
    ref = 100; //ref是引用,转换为*ref = 100
}
int main()
{
    int a =10;
    
    //自动转换为 int* const ref = &a;指针常量是指向不可改的指针,也说明了为什么引用不可更改
    int& ref = a;
    ref = 20; //内部发现ref是引用,自动帮我们转换为 *ref = 20;
    
    std::cout<< "a:" << a <<std::endl;
    std::cout<< "ref:" << ref <<std::endl;
    
    func(a);
    return 0;
}

常量引用

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

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

//引用使用的场景,通常原来修饰形参
void showValue(const int& v)
{
    //v += 10; 加入const后报错,防止形参改变实参
    std::cout<< v <<std::endl;
}

int main()
{
    //int& ref = 10; 引用必须引用一块合法的内存空间,此处直接引用了作为常量的10
    //const int& ref = 10; 在int前加上const之后为合法,因为编译器将代码修改为:int temp = 10; const int& ref = temp;
    //ref = 20; 加入const后为只读状态
    
    int a = 100;
    showValue(a);
    
    return 0;
}

标签:函数,形参,int,笔记,学习,c++,指针,ref,引用
From: https://www.cnblogs.com/StadarkBlog/p/18250904

相关文章

  • 03构建之法阅读笔记之三
    第八章需求分析需求分析也称为软件需求分析、系统需求分析或需求分析工程等,是开发人员经过深入细致的调研和分析,准确理解用户和项目的功能、性能、可靠性等具体要求,将用户非形式的需求表述转化为完整的需求定义,从而确定系统必须做什么的过程。但需求分析是软件开发中非常重要的......
  • UE4 C++ AI感官获取检测结果
    重写ActorsPerceptionUpdated函数有委托OnPerceptionUpdated,可以自己编写函数然后进行绑定。也可以直接对ActorsPerceptionUpdated进行重写,该函数会在有感官变化时进行调用其会根据委托获得一个数组,即AI感知到的所有发生变化的Actor。通过对这些Actor的判断即可判断是进入范围还......
  • SpringCloud2023 - 学习笔记
    文章目录1.简介1.1基础知识1.2组件更替与升级2.微服务基础项目构建2.1创建项目2.2Mapper4生成代码2.3支付模块编码2.4项目完善2.5订单模块编码2.6工程重构3.consul服务注册与发现3.1consul简介3.2consul下载安装3.3微服务入驻3.4order订单微服务入驻3.5......
  • [C++] vector && list 等容器的迭代器失效问题
    标题:[C++]容器的迭代器失效问题@水墨不写bug正文开始:什么是迭代器?    迭代器是STL提供的六大组件之一,它允许我们访问容器(如vector、list、set等)中的元素,同时提供一个遍历容器的方法。然而,在使用迭代器时,我们必须注意所谓的“迭代器失效”问题。一、插入/删......
  • 《梦断代码》读书笔记(二)
    这次阅读中体会最深的莫过于奇客和狗,作者通过Chandler狗、Cosmo狗以及各种狗来类比OSAF开发的项目,前面两种都是拉布拉多狮子狗,文章这样描写这两种狗,“它们是好宠物:‘和其他狗类融洽相处’”、“非常聪明,快活而友善。能快速学会不常见或特殊的技能。活跃,有时显得滑稽。如果管束不严......
  • 【C++课程设计】通讯录管理系统
    完整代码:开源地址一、任务书 手机通讯录中的联系人的信息既可以存储在手机中,也可以存储在手机卡中,也可以同时存储在两个位置上(假设每个位置上的存储容量为1000,即手机卡中或手机上最多只能存储1000个联系人)。存储在手机中的联系人的信息只包含姓名和电话号码两项信息。存储......
  • C++题解—1140—亲密数对(东方博宜OJ)
    题目描述:键盘输入 N,N 在2至 2000之间,求 2 至 N 中的亲密数对,就是A的因子和等于B,B的因子和等于A ,且A≠B。如 48和 75是亲密数对。48的因子和为2+3+4+6+8+12+16+24=75 ,而 75的因子和3+5+15+25=48 。输入:只有一行,为一个整数 N( 2≤N≤2000 )。输出:输出......
  • [笔记]AVL树
    AVL树是一种严格平衡的二叉搜索树,任何操作结束后,都能保证每个节点的左右子树高度相差不超过\(1\)。内容源自BV1rt411j7Ff-【AgOHの数据结构】平衡树专题之叁树旋转与AVL树。模板题:P3369【模板】普通平衡树。结构体定义&基本函数structnode{ intl;//左孩子int......
  • 【机器学习与R语言】系列笔记
    几年前做的机器学习与R语言相关笔记,迁移到公号记录之。1-机器学习简介2-懒惰学习K近邻(KNN)3-概率学习朴素贝叶斯(NB)4-决策树5-规则学习算法6-线性回归7-回归树和模型树8-神经网络9-支持向量机10-关联规则11-Kmeans聚类12-如何评估模型的性能?13-如何提高模型的性能?......
  • go学习06
    go读取yaml文件配置config.yaml文件如下mysql:host:localhostport:3306username:myuserpassword:mypassworddatabase:mydatabase读取packagemainimport( "github.com/spf13/viper")funcmain(){ //设置配置文件名和路径(可选) viper.SetConfig......