理解 C++ 变量引用的使用

在C++中,引用是一种特殊的变量,它为变量起了一个别名。
从如下几点进行介绍,持续补充

1. 引用的声明与初始化
2. 引用作为函数参数
3. 引用作为函数返回值
4. 扩充内容:C++内存存储方式
5. 常引用
6. 引用的好处
1. 引用的声明与初始化

引用的声明在类型名加上&符号,并且在声明时必须进行初始化,之后不能再引用其他变量(与指针不同之处)
简单示例:

#include <iostream>

int main()
{
	int a = 5;
	int& b = a; // 声明引用b 并初始化
	// b是a的引用,指向同一块内存地址,所以输出a b值相同
	std::cout << "a :" << std::endl;
	std::cout << "b : " << std::endl;
	
	return 0;
}
2. 引用作为函数参数

引用常被用作函数参数,在函数内部对引用参数的修改会同步修改原变量,也被称为“传引用调用”。
简单示例:

#include <iostream>

void numSwap(int& num1, int& num2)
{
	int temp = num1;
	num1 = num2;
	num2 = temp;
}

int main()
{
	int a = 5;
	int b = 10;
	numSwap(a, b);
	std::cout << "交换前:a = " << a << "b = " << b << std::endl;
	std::cout << "交换后:a = " << a << "b = " << b << std::endl;
	
	return 0;
}
3. 引用作为函数返回值

函数返回引用,这样可以直接操作返回对象
代码示例:

#include <iostream>

int& getLarger(int& a, int& b)
{
    return (a > b) ? a : b;
}

int main()
{
    int x = 5;
    int y = 10;

    // 获取较大值的引用
    int& largest = getLarger(x, y);

    std::cout << "较大的值是: " << largest << std::endl;  // 输出10

    // 修改较大值,同时改变原变量的值
    largest = 11;

    std::cout << "修改后较大的值是: " << largest << std::endl;  // 输出11
    std::cout << "x 的值是: " << x << std::endl;  // 输出5
    std::cout << "y 的值是: " << y << std::endl;  // 输出11

    return 0;
}

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

int& test()
{
    int testData = 10;  //局部变量
    return testData;
}

上述代码段,testData是局部变量,存放在栈区,函数结束后自动释放,再次访问为违法访问,编译会报错

上述问题中,可以定义static静态变量,存放在全局区,在程序结束后释放。

int& test()
{
    static int testData = 10;  //局部变量
    return testData;
}
4. 扩充内容:C++内存存储方式

C++内存主要分为 栈区、 堆区、 全局/静态存储区、常量存储区
栈区:
由编译器自动分配和释放,存放函数的参数值、局部变量等。每当一个函数被调用时,系统会在栈上为该函数的局部变量和参数分配内存;当函数执行完毕返回时,这些内存会被自动释放。

内存分配和释放速度快:栈的操作类似于数据结构中的栈,遵循后进先出(LIFO)原则,内存分配和释放只是移动栈指针,因此速度非常快。
空间有限:栈的空间通常比较小,不同操作系统和编译器对栈的大小有不同的限制。如果在栈上分配过多的内存,可能会导致栈溢出错误。

堆区
由程序员手动分配和释放,若不手动释放,程序结束后可能由操作系统回收。堆区用于动态分配内存,c++中,例如使用newdelete (数组new[]delete[])

内存分配灵活:堆区的内存可以根据程序的需要动态分配和释放,大小可以在运行时确定。
内存分配和释放速度慢:堆的内存管理需要更复杂的算法,涉及到内存块的分配和回收,因此速度相对较慢。
可能产生内存碎片:频繁地分配和释放不同大小的内存块可能会导致内存碎片,降低内存的利用率。

全局变量
全局变量是在函数外部定义的变量,其作用域是从定义位置开始到整个源文件结束,并且可以在其他源文件中通过extern关键字声明后使用。

生命周期长:全局变量在程序开始执行时就被分配内存,直到程序结束才释放。
全局可见性:可以被多个函数访问和修改,因此在使用时需要注意避免命名冲突和数据的不一致性。

静态变量
静态变量可以分为: 静态局部变量静态全局变量静态变量定义时初始化。
静态局部变量在函数内部定义,但它的生命周期与程序的生命周期相同。
静态全局变量在函数外部定义,其作用域仅限于定义它的源文件。

生命周期长:静态变量在程序开始执行时就被分配内存,直到程序结束才释放。
初始化一次:静态变量只在第一次执行到其定义语句时进行初始化,以后再次执行到该语句时,不会再次初始化。

全局变量和静态变量都存储在全局/静态存储区,该区域在程序的整个生命周期内都存在栈区和堆区则是动态分配和释放内存的区域。

5. 常引用

声明方式使用const关键字,不能修改引用的对象,常用于函数参数避免意外修改传入的对象。

#include <iostream>

void printNum(const int& value)
{
    std::cout << "值是: " << value << std::endl;
    // 下面这行代码会导致编译错误,因为不能通过常引用修改对象
    // value = 10; 
}

int main()
{
	int a  = 5;
	printNum(a);
	
	return 0;
}

6.引用的好处
避免数据复制,提升性能:如大型数组、结构体或类对象作为参数传递给函数时,采用值会创建实参的副本,消耗时间和内存资源。
使用引用作为函数参数时,可以直接对原变量实现操作,在需要修改外部变量时,如交换两个变量的值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值