C++ Primer 学习笔记_17_从C到C++(3)--引用、const引用、引用传递、引用作为函数返回值、引用与指针区别

欢迎大家阅读参考,如有错误或疑问请留言纠正,谢谢

一、引用

1、引用是给一个变量起别名

变量:

名称

空间

引用:

引用不是变量

引用仅仅是变量的别名

引用没有自己独立的空间

引用要与它所引用的变量共享空间

对引用所做的改变实际上是对它所引用的变量的改变

引用在定义的时候必须要进行初始化

引用一经初始化,不能重新指向其他变量

2、定义引用的一般格式:

(1)类型  &引用名 = 变量名;

(2)例如:

int a=1;
int &b=a;  // b是a的别名,因此a和b是同一个单元

(3)注意:定义引用时一定要初始化,指明该引用变量是谁的别名

(4)示例

#include <iostream>
using namespace std;
int main(void)
{
 int val = 100;
 //int& refval;	 Error,引用必须初始化
 int& refval = val;
 refval = 200;	 // 将200赋值给refval
               // 实际上改变的是val这个变量
 cout << "val=" << val << endl;
 int val2 = 500;
 refval = val2;	 // 不代表将refval引用至val2这个变量
                // 仅仅只是代表将val2赋值给refval,改变的还是val的值
 cout << "val=" << val << endl;
 return 0;
}

运行结果:

val=200

val=500

3、在实际应用中,引用一般用作参数传递与返回值

二、const引用

1、const引用是指向const对象的引用

2、示例

#include <iostream>
using namespace std;

int main(void)
{
 const int val = 1024;
 const int& refval = val;
 //int& ref2 = val;	// Error,nonconst reference to const object
 //refval = 200;	 Error,refval是一个常量
 int val2 = 1024;
 const int& ref3 = val2;	//const reference to nonconst object
 double val3 = 3.14;
 const int& ref4 = val3;	 // int temp = val3;
                         // const int& ref4 = temp;
 cout << "ref4=" << ref4 << endl;
 cout << "val3=" << val3 << endl;
 //int& ref5 = val3;	 Error ,不会产生中间变量
 return 0;
}

运行结果:

ref4=3

val3=3.14

三、引用传递

1、引用传递方式是在函数定义时在形参前面加上引用运算符"&"

例如:swap(int &a,int &b);

2、在C语言中两种传递方式:

(1)按值传递:按值传递方式容易理解,但形参值的改变不能对实参产生影响

(2)指针传递:地址传递方式通过形参的改变使相应的实参改变,但程序容易产生错误且难以阅读

3、C++中,引用作为参数对形参的任何操作都能改变相应的实参的数据,又使函数调用显得方便、自然

(1)值传递     实参要初始化形参要分配空间,将实参内容拷贝到形参

(2)引用传递   实参初始化新参时不分配空间(效率更高)

(3)指针传递   本质是值传递,实参初始化形参也要分配指针空间(4个字节)。如果我们要修改指针的地址,单纯用指针传递也是不行的。

4、示例:

#include <iostream>
using namespace std;
void swap(int &x, int &y);
int main()
{
    int a, b;
    a = 10;
    b = 20;
    swap(a, b);  //在函数调用时,引用被初始化x = a, y = b;
    cout << "a=" << a << "b=" << b << endl;
    return 0;
}
void swap(int &x, int &y)
{
    int temp;
    temp = x;
    x = y;
    y = temp;
}

运行结果:

a=20b=10

四、引用作为函数返回值

1、引用的另一个作用是用于返回引用的函数

2、函数返回引用的一个主要目的是可以将函数放在赋值运算符的左边。

(1)示例

#include <iostream>
using namespace std;
// 引用作为函数返回值
int a[] = {0,1,2,3,4};
int& index(int i)
{
 return a[i];  //全局变量
}
int main(void)
{
 index(3) = 100;	 // 引用作为函数返回值,使得函数可以放在赋值运算符左边
                 // 函数返回引用,引用在函数返回的时候初始化
                 // index(3)在函数返回的时候被初始化为a[3];

 cout << "a[3]=" << a[3] << endl;
 return 0;
}

运行结果:

a[3]=100

3、注意:不能返回对局部变量的引用。

(1)示例

#include <iostream>
using namespace std;

int& add(int a, int b)
{
 int sum;
 sum = a + b;
 return sum; // 不能返回对局部变量的引用
}

int main(void)
{
 int n = add(3, 4);
 int& n2 = add(5, 6);	 // n2是引用,没有自己独立的空间
                      // n2的值依赖于它所引用的变量
                      // 如果n2所引用的变量的生命期结束了,也就是说n2是一个
                      // 无效的引用,那么n2的值将是不确定的。
 cout << "n2=" << n2 <<endl; //可能还没被 n 覆盖,因此正确
 cout << "n=" << n << endl;
 cout << "n2=" << n2 << endl;
 return 0;
}

运行结果:

n2=11

n=7

n2=20395849

五、引用与指针区别

1、引用访问一个变量是直接访问,而指针是间接访问。

2、引用是一个变量的别名,本身不单独分配自己的内存空间,而指针有自己的内存空间。

3、引用一经初始化不能再引用其它变量,而指针可以。

4、尽可能使用引用,不得已时使用指针。

参考:

C++ primer 第四版

C++ primer 第五版

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-05 07:49:16

C++ Primer 学习笔记_17_从C到C++(3)--引用、const引用、引用传递、引用作为函数返回值、引用与指针区别的相关文章

C++ Primer 学习笔记_17_类与数据抽象(3)_类作用域

C++ Primer 学习笔记_17_类与数据抽象(3)_类作用域 引言: 每个类都定义了自己的新作用域与唯一的类型.即使两个类具有完全相同的成员列表,它们也是不同的类型.每个类的成员不同与任何其他类(或任何其他作用域)的成员. 一.类作用域中的名字查找 1)首先,在使用该名字的块中查找名字的声明.只考虑在该项使用之前声明的名字. 2)如果在1)中找不到,则在包围的作用域中查找. 如果找不到任何声明,则出错. 类的定义实际上是在两个阶段中处理: 1)首先,编译器声明: 2)只有在所有成员出现之后

C++ Primer 学习笔记_98_特殊工具与技术 --优化内存分配

特殊工具与技术 --优化内存分配 引言: C++的内存分配是一种类型化操作:new为特定类型分配内存,并在新分配的内存中构造该类型的一个对象.new表达式自动运行合适的构造函数来初始化每个动态分配的类类型对象. new基于每个对象分配内存的事实可能会对某些类强加不可接受的运行时开销,这样的类可能需要使用用户级的类类型对象分配能够更快一些.这样的类使用的通用策略是,预先分配用于创建新对象的内存,需要时在预先分配的内存中构造每个新对象. 另外一些类希望按最小尺寸为自己的数据成员分配需要的内存.例如,

C++ Primer 学习笔记_73_面向对象编程 --再谈文本查询示例

面向对象编程 --再谈文本查询示例 引言: 扩展第10.6节的文本查询应用程序,使我们的系统可以支持更复杂的查询. 为了说明问题,将用下面的简单小说来运行查询: Alice Emma has long flowing red hair. Her Daddy says when the wind blows through her hair, it looks almost alive, like a fiery bird in flight. A beautiful fiery bird, he

C++ Primer 学习笔记_74_面向对象编程 --再谈文本查询示例[续/习题]

面向对象编程 --再谈文本查询示例[续/习题] //P522 习题15.41 //1 in TextQuery.h #ifndef TEXTQUERY_H_INCLUDED #define TEXTQUERY_H_INCLUDED #include <iostream> #include <fstream> #include <sstream> #include <vector> #include <set> #include <map&g

C++ Primer 学习笔记_19_类与数据抽象(5)_初始化列表(const和引用成员)、拷贝构造函数

C++ Primer 学习笔记_19_类与数据抽象(5)_初始化列表(const和引用成员).拷贝构造函数  从概念上将,可以认为构造函数分为两个阶段执行: 1)初始化阶段: 2)普通的计算阶段.计算阶段由构造函数函数体中的所有语句组成. 一.构造函数初始化列表 推荐在构造函数初始化列表中进行初始化 1.对象成员及其初始化 <span style="font-size:14px;">#include <iostream> using namespace std;

C++ Primer 学习笔记_14_标准模板库_bitset位集合容器

C++ Primer 学习笔记_14_标准模板库_bitset位集合容器 bitset容器是一个bit位元素的序列容器,每个元素只占一个bit位,取值为0或1,因而很节省内存空间.下图是一个bitset的存储示意图,它的10个元素只使用了两个字节的空间. 使用bitset需要声明头文件"#include <bitset>" 1.创建bitset对象 创建bitset对象时,必须要指定容器的大小.bitset对象的大小一经定义,就不能修改了.下面这条语句就定义了bitset对

C++ Primer 学习笔记_23_标准模板库_stack.

C++ Primer 学习笔记_11_标准模板库_stack.queue队列容器与priority_queue优先队列容器 1.stack堆栈 stack堆栈是一个后进先出(Last In First Out,LIFO)的线性表,插入和删除元素都只能在表的一端进行.插入元素的一端称为栈顶,而另一端称为栈底.插入元素叫入栈(Push),删除元素叫出栈(Pop).下图是堆栈示意图 堆栈只提供入栈,出栈,栈顶元素访问和判断是否为空等几种方法.采用push()方法将元素入栈:采用pop()方法出栈:采用

C++primer学习笔记(二)——Chapter 4

4.1  Fundamentals 1.Basic Concepts (1)操作符分为一元,二元或者三元操作符: (2)复杂的表达式中含有很多操作符时: 规则一:分为不同的级别,级别高的先运行: 规则二:相同级别的操作符有执行顺序的确定: (3)操作符可以改变操作数的类型 一般将级别低的转化成级别高的 (4)重载运算符 相同的运算符在对不同类型的对象进行操作的时候,会有不同的功能: (5)Lvalue和Rvalue 显而易见:Lvalue指的是Left value,Rvalue指的是Right

C++ Primer 学习笔记_104_特殊工具与技术 --嵌套类

特殊工具与技术 --嵌套类 可以在另一个类内部(与后面所讲述的局部类不同,嵌套类是在类内部)定义一个类,这样的类是嵌套类,也称为嵌套类型.嵌套类最常用于定义执行类. 嵌套类是独立的类,基本上与它们的外围类不相关,因此,外围类和嵌套类的对象是互相独立的.嵌套类型的对象不具备外围类所定义的成员,同样,外围类的成员也不具备嵌套类所定义的成员. 嵌套类的名字在其外围类的作用域中可见,但在其他类作用域或定义外围类的作用域中不可见.嵌套类的名字将不会与另一作用域中声明的名字冲突 嵌套类可以具有与非嵌套类相同