12.x — 第12章 总结与测验

快速回顾

复合数据类型(也称为组合数据类型)是可以由基本数据类型(或其他复合数据类型)构造的数据类型。

表达式的值类别表示表达式解析为值、函数还是某种类型的对象。

左值是求值为具有身份的函数或对象的表达式。具有身份的对象或函数具有标识符或可识别的内存地址。左值有两种子类型:可修改左值是可修改的左值,而不可修改左值是其值不可修改的左值(通常因为它们是const或constexpr)。

右值是既非左值也非左值的表达式。这包括字面值(字符串字面值除外)以及函数或运算符的返回值(按值返回时)。

引用是现有对象的别名。一旦引用被定义,对引用的任何操作都会应用于被引用的对象。C++包含两种类型的引用:左值引用和右值引用。左值引用(通常简称为引用)充当现有左值(例如变量)的别名。左值引用变量是充当左值(通常是另一个变量)引用的变量。

当引用用对象(或函数)初始化时,我们说它绑定到该对象(或函数)。被引用的对象(或函数)有时称为被引用者

左值引用不能绑定到不可修改的左值或右值(否则您将能够通过引用更改这些值,这将违反它们的const属性)。因此,左值引用有时被称为非const左值引用(有时缩写为非const引用)。

一旦初始化,C++中的引用不能被重新绑定,这意味着它不能更改为引用另一个对象。

当被引用的对象在指向它的引用之前被销毁时,引用将指向一个不再存在的对象。这样的引用称为悬空引用。访问悬空引用会导致未定义行为。

通过在声明左值引用时使用const关键字,我们告诉左值引用将其引用的对象视为const。这样的引用称为指向const值的左值引用(有时称为const引用const引用)。const引用可以绑定到可修改的左值、不可修改的左值和右值。

临时对象(有时也称为无名对象匿名对象)是在单个表达式中为临时使用而创建(然后销毁)的对象。

使用按引用传递时,我们将函数参数声明为引用(或const引用),而不是普通变量。当函数被调用时,每个引用参数都绑定到相应的实参。因为引用充当实参的别名,所以不会创建实参的副本。

取地址运算符 (&) 返回其操作数的内存地址。解引用运算符 (*) 返回给定内存地址处的值作为左值。

指针是持有内存地址(通常是另一个变量的内存地址)作为其值的对象。这允许我们存储其他一些对象的地址以供以后使用。像普通变量一样,指针默认不初始化。未初始化的指针有时称为野指针悬空指针是持有不再有效(例如,因为它已被销毁)的对象的地址的指针。

除了内存地址,指针还可以包含一个额外的值:空值。空值(通常缩写为)是一个特殊值,表示某物没有值。当指针包含空值时,表示该指针未指向任何内容。这样的指针称为空指针nullptr关键字表示空指针字面值。我们可以使用nullptr来显式初始化或将空值分配给指针。

指针应持有有效对象的地址,或设置为nullptr。这样我们只需要测试指针是否为空,并可以假定任何非空指针都是有效的。

指向const值的指针(有时简称为指向const的指针)是(非const)指向常量值的指针。

const指针是初始化后其地址不能更改的指针。

指向const值的const指针既不能更改其地址,也不能通过该指针更改其指向的值。

使用按地址传递,调用者不提供对象作为参数,而是提供对象的地址(通过指针)。该指针(持有对象的地址)被复制到被调用函数的指针参数中(该参数现在也持有对象的地址)。然后函数可以解引用该指针以访问传递了地址的对象。

按引用返回返回绑定到被返回对象的引用,这避免了创建返回值的副本。使用按引用返回有一个主要注意事项:程序员必须确保被引用的对象在返回引用的函数之外仍然存在。否则,返回的引用将悬空(引用已被销毁的对象),并且使用该引用将导致未定义行为。如果参数通过引用传递到函数中,则可以安全地通过引用返回该参数。

如果函数返回一个引用,并且该引用用于初始化或赋值给非引用变量,则返回值将被复制(就像按值返回一样)。

变量的类型推导(通过auto关键字)将从推导出的类型中删除任何引用或顶层const限定符。如果需要,可以在变量声明中重新应用它们。

按地址返回的工作方式几乎与按引用返回相同,只是返回的是指向对象的指针而不是对对象的引用。

小测验时间

问题 #1

对于运算符 << 右侧的以下每个表达式,指示表达式是左值还是右值

a)

std::cout << 5;

显示答案

b)

int x { 5 };
std::cout << x;

显示答案

c)

int x { 5 };
std::cout << x + 1;

显示答案

d)

int foo() { return 5; }
std::cout << foo();

显示答案

e)

int& max(int &x, int &y) { return x > y ? x : y; }
int x { 5 };
int y { 6 };
std::cout << max(x, y);

显示答案

问题 #2

此程序的输出是什么?

#include <iostream>

int main()
{
	int x{ 4 };
	int y{ 6 };

	int& ref{ x };
	++ref;
	ref = y;
	++ref;

	std::cout << x << ' ' << y;

	return 0;
}

显示答案

问题 #3

说明我们尽可能地偏好通过 const 引用而不是非 const 引用传递参数的两个原因。

显示答案

问题 #4

const指针和指向const的指针有什么区别?

显示答案

问题 #5

编写一个名为 sort2 的函数,允许调用者传递 2 个 int 变量作为参数。函数返回时,第一个参数应保存两个值中较小的一个,第二个参数应保存两个值中较大的一个。

提示:std::swap() 函数(位于 <algorithm> 头文件中)可用于交换两个变量的值。例如:std::swap(x, y) 交换变量 xy 的值。

以下代码应运行并打印注释中指出的值

#include <iostream>

int main()
{
    int x { 7 };
    int y { 5 };

    std::cout << x << ' ' << y << '\n'; // should print 7 5

    sort2(x, y); // make sure sort works when values need to be swapped
    std::cout << x << ' ' << y << '\n'; // should print 5 7

    sort2(x, y); // make sure sort works when values don't need to be swapped
    std::cout << x << ' ' << y << '\n'; // should print 5 7

    return 0;
}

显示答案

guest
您的电子邮箱地址将不会被显示
发现错误?请在上方留言!
与勘误相关的评论在处理后将被删除,以帮助减少混乱。感谢您帮助使网站对每个人都更好!
来自 https://gravatar.com/ 的头像与您提供的电子邮箱地址相关联。
有回复时通知我:  
127 评论
最新
最早 最多投票
内联反馈
查看所有评论