【从零开始学习计算机科学】编程语言(二)名字、关键字、保留字 与 变量
【从零开始学习计算机科学】编程语言(二)名字、关键字、保留字 与 变量
- 名字、关键字和保留字部分
- 变量部分
-
- 变量的绑定
- 类型绑定
-
- 静态的类型绑定
- 动态的类型绑定
- 存储绑定和生存期
-
- 静态变量
- 栈动态变量
- 显式堆动态变量
- 隐式堆动态变量
- 作用域
-
- 静态作用域
- 块
- 变量声明的次序
- 全局作用域
- 动态作用域
- 作用域与生存期
- 引用环境
- 命名常量
名字、关键字和保留字部分
在编程语言中,名字是一个很重要的部分,名字和标号与子程序、形参以及其他的程序结构相关联。
名字是用来标识程序中某些实体的字符串。名字的命名规则在不同的编程语言中通常是不同的,并且,名字不能被取为保留字或关键字。
在编程语言中,保留字(Reserved Words)一般是等同于关键字(Keywords)的。从字面含义上理解,保留字是语言中已经定义过的字,使用者不能再将这些字作为变量名或过程名使用。而关键字则指在语言中有特定含义,成为语法中一部分的那些字,比如if、else,for,while等等。在一些语言中,一些保留字可能并没有应用于当前的语法中,这就成了保留字与关键字的区别。一般出现这种情况可能是由于考虑扩展性。例如,Javascript有一些未来保留字,如abstract、double、goto等等。它可能未来要增加直接跳转的功能,那么为了使当前版本的程序代码能向后兼容,所以不允许使用goto作为变量名,但当前版本的语言并不支持goto的直接跳转功能,它目前就不是关键字。
变量部分
程序中的变量是计算机的存储单元或对计算机一系列存储单元的抽象。 程序人员常常认为变量是存储地址的名字,但变量比名字具有更多的意义。从机器语言到汇编语言,主要是用名字来替代数据存储地址的绝对数值,以使程序的可读性更好,因而也就更方便编写和维护。 这一步也避免了绝对寻址问题,因为将名字转化成实际地址的拥译器也是选择的这些存储地址。
变量可以用一个属性六元组来刻画:(名字,地址,数值,类型,生存期,作用域),尽管这可能使这个看似简单的概念显得过于复杂,但正是这6种属性才能最清晰的解释变量的各个方面。
关于变量属性的讨论开启了对许多相关重要概念的研究,包括别名,绑定,绑定时间,声明,类型检测,强制类型转化,作用域规则以及引用环境。
变量的地址是与这个变量相关联的存储地址。然而这个关联关系却不是第一眼看上去那么简单。在很多语言里,程序中相同的名字可以在不同的时刻与不同的地址相关联。例如, 如果一个子程序有一个局部变量,它是在子程序被调用时从运行时堆栈里分配的,对子程序的不同调用会导致该变量有不同的地址。从某种意义上说,它们是相同变量的不同实例。
变量地址有时也被称为变量的左值,这是因为变量通常要出现在赋值语句的左边。
多个变量可以具有同一个地址。 当用多个变量名来访问相同的存储地址时,这些变量名就被称为别名。 别名使用有损于可读性,因为它允许通过给一个变量赋值来改变另一个变量的值。例如,变量 total
和 sum
为别名,total
的任何变化也能改变 sum
,反之亦然。程序的读者必须时刻记住,total
和 sum
是同一个存储单元的不同名字。因为在一个程序中可以具有任何数量的别名, 这在实际使用时非常困难。 别名使用也使得程序的验证更为困难。在程序中可以用多种不同的方式产生别名。 在 C 和 C++语言中产生别名的一种常用方式是使用联合(union)类型。当然,两个指向同一存储地址的指针变量也是别名。 对于引用变量也有同样的情形。这种类型的别名是指针与引用特性的一种副作用。设定一个 C++指针指向一个命名变量后,当指针被解引用时,就是那个命名变量的别名。在许多语言中,通过子程序的参数也可以产生别名。
变量的类型决定变量可以存储值的范围,并决定为这种类型的值所定义的操作集合。
一个变量的值是与这个变量相关联的存储单元的内容。我们将计算机存储单元想成抽象的单元,比想成物理的单元要容易得多。无论是存储单元或单个地址单元,在大多数现代的计算机中是以字节为单位的,一个字节具有八个位长度。
变量的值有时被称为右值(r-value), 这是因为变量通常位于赋值语句的右边。要想访问右值,必须首先要确定左值。