总结与测验

总结与测验

本章内容广泛,你已顺利完成,表现出色!

复合语句(或称语句块)是由零条或多条语句组成的整体,编译器将其视为单条语句。语句块以左花括号“{”开始,以右花括号“}”结束,中间放置待执行的语句。凡允许出现单条语句之处,皆可使用语句块;语句块结尾无需分号。语句块常与 if 语句配合使用,以实现多条语句的批量执行。

用户自定义命名空间系由程序员自行定义的命名空间,用于容纳自定义声明。C++ 自身提供的命名空间(如全局命名空间)或库提供的命名空间(如命名空间 std)均不属于用户自定义命名空间。

可通过作用域解析运算符(::)访问某命名空间内的声明。该运算符告知编译器,应在左侧操作数指定的作用域中查找右侧操作数所标识的符号;若左侧操作数缺省,则默认为全局命名空间。

局部变量系指在函数内部(含形参)定义的变量。局部变量具有块作用域,即自其定义之处起,直至所属语句块结束,均处于有效作用域内。局部变量采用自动存储期:在定义点创建,在所属语句块结束时销毁。

嵌套语句块中声明的名称可遮蔽(屏蔽)外层语句块中同名变量,应避免此种情况。

全局变量系指在所有函数外部定义的变量。全局变量具有文件作用域,即自其声明之处起,直至所在文件结束,均可见。全局变量采用静态存储期:程序启动时创建,程序结束时销毁。应尽可能避免对静态变量进行动态初始化。

标识符的链接属性决定其他同名声明是否指向同一实体。局部变量无链接;具有内部链接的标识符仅可在单个文件内部可见并可用,其他文件无法访问;具有外部链接的标识符既可在定义文件内部可见并可用,亦可通过前置声明在其他代码文件中使用。

应尽可能避免使用非常量全局变量;常量全局变量通常可接受。若编译器支持 C++17,可使用 inline 变量定义全局常量。

可在局部变量前加 static 关键字,使其获得静态存储期。

限定名称系指包含作用域限定符的名称(如 std::string);非限定名称则不含作用域限定符(如 string)。

using 语句(含 using 声明与 using 指令)可避免显式命名空间限定。using 声明允许将非限定名称作为限定名称的别名;using 指令则将某命名空间的所有标识符导入当前作用域。二者一般均应慎用。

内联展开系指用被调用函数的定义代码取代函数调用的过程。以 inline 关键字声明的函数称为内联函数。

内联函数与内联变量须满足两项主要要求:

  1. 在每个使用该函数的翻译单元中,编译器必须能够看见其完整定义(仅前置声明不足);若同时提供前置声明,定义可位于使用点之后。
  2. 所有内联函数或变量的定义必须完全一致,否则将导致未定义行为。

在现代 C++ 中,“inline”一词已演化为“允许多次定义”。因此,内联函数指可在多个文件中定义的函数。C++17 引入内联变量,指可在多个文件中定义的变量。

内联函数与内联变量尤其适用于仅含头文件的库,此类库由若干头文件实现功能,不涉及 .cpp 文件。

最后,C++ 支持无名命名空间,其内部所有内容隐式拥有内部链接;亦支持内联命名空间,可为命名空间提供初级的版本管理功能。

测验

问题 #1

修正以下程序:

#include <iostream>

int main()
{
	std::cout << "Enter a positive number: ";
	int num{};
	std::cin >> num;

	if (num < 0)
		std::cout << "Negative number entered.  Making positive.\n";
		num = -num;

	std::cout << "You entered: " << num;

	return 0;
}

问题 #2

编写一个名为 constants.h 的头文件,使下列程序能够编译运行。若编译器支持 C++17,请使用 inline constexpr 变量;否则使用普通 constexpr 变量。maxClassSize 的值应为 35。

main.cpp:

#include "constants.h"
#include <iostream>

int main()
{
	std::cout << "How many students are in your class? ";
	int students{};
	std::cin >> students;

	if (students > Constants::maxClassSize)
		std::cout << "There are too many students in this class";
	else
		std::cout << "This class isn't too large";

	return 0;
}

问题 #3

编写函数 int accumulate(int x)。该函数应返回所有已传入 x 值的总和。

提示:

下列程序应能编译运行,并按注释所示输出结果:

#include <iostream>

int main()
{
    std::cout << accumulate(4) << '\n'; // prints 4
    std::cout << accumulate(3) << '\n'; // prints 7
    std::cout << accumulate(2) << '\n'; // prints 9
    std::cout << accumulate(1) << '\n'; // prints 10

    return 0;
}

3b) 附加题

上述 accumulate() 函数存在哪两个缺陷?

关注公众号,回复"cpp-tutorial"

可领取价值199元的C++学习资料

公众号二维码

扫描上方二维码或搜索"cpp-tutorial"