跳至内容
Topos Uranos

摘要

命令式程序不是一下子算出结果的:它一步一步地构造结果,保存中间值并不断改变它们。本课研究保存这些值的地方,即变量:它是一个有名字、类型和值的存储单元。本课讲授如何用花括号声明并初始化变量,以及为什么花括号是首选的写法;如何用赋值改变变量的值,而赋值的符号 = 并不是它在数学中的意思;如何用跟踪表追踪程序的状态,也就是程序在每一时刻所有变量的值;如何选择能说明变量保存什么的名字;以及如何避免这一阶段最无声无息的错误:读取一个从未被赋予值的变量,这在 C++ 中是未定义行为。

学习目标

  1. 用花括号声明并初始化变量,并在给定的程序中区分初始化与赋值。
  2. 用跟踪表手工追踪由一连串赋值组成的程序的状态,并据此预测其输出。
  3. 按照语言的规则和本课程的指南,选择能说明每个变量保存什么的英文名字。
  4. 解释为什么读取未初始化的变量是未定义行为,在程序中识别它,并通过始终初始化来预防它。

作为存储单元的变量

在从问题到算法一课中,算法是用 qq 和 rr 这样的字母写成的,它们先取一个值,后来又取另一个值:“rr 取值为 r−br - b”。在数学中,一个字母表示一个固定的值,尽管这个值可能未知;而在算法中,它表示一个内容会变化的位置。C++ 程序也需要同样的东西,它从计算机的内存中得到它。

主存是一长串字节,每个字节都有自己的序号,即它的地址。变量是程序为其赋予名字和类型的一段内存。因此,变量有四个属性:

  1. 名字,程序用它来指称这个变量(count、price);
  2. 类型,它规定变量能保存哪些值、占用多少字节、允许哪些运算:int 保存整数,double 保存带小数的数;
  3. 值,即变量在某一时刻保存的值,它在程序运行期间可以改变;
  4. 内存中的位置,由编译器和系统选定,程序几乎从来不需要知道它。

值得记住的图景是一个格子:名字写在上方,值放在里面。类型就是格子的大小和形状;int 的格子放不进 2.5,正如信箱的投信格放不进一个包裹。本课的图就是这样画出程序的状态,并在每条语句之后重新画一次。

类型决定大小,这一点可以看到:运算符 sizeof 给出一个变量或一个类型所占的字节数。

C++ 程序
#include <print>​int main(){    const int count{12};    const double price{4.5};    std::println("count 占 {} 个字节", sizeof(count));    std::println("price 占 {} 个字节", sizeof(price));}
输出
count 占 4 个字节price 占 8 个字节

在这里,int 占 4 个字节,double 占 8 个。这些数字并非在所有系统上都相同,每种类型能容纳多少个不同的值取决于它们;整数及其表示和浮点数两课将研究这一点。这里只需记住要点:变量的类型在声明时确定,永不改变;改变的是它的值。