2.3 变量
变量(Variable)是编程语言最重要的概念之一,在程序中变量是一个名字,而这个名字代表的是计算机存储器中的一块空间,可以在里面保存一个值(Value),保存的值是可以随时变的,比如这次存个字符'a',变量的值就是'a',下次存个字符'b',变量的值就变成'b',正因为变量的值可以随时变所以才叫变量。
常量有不同的类型,变量也有不同的类型,变量的类型决定了它所占的存储空间的大小。在C语言中用声明(Declaration)来规定变量的名字和类型,例如下面有四条声明,规定了四个变量fred、bob、jimmy和tom的类型分别是字符型、整型、单精度浮点型、双精度浮点型:
char fred; int bob; float jimmy; double tom;
提示:声明和定义
C语言中的声明有变量声明、函数声明和类型声明三种。本节只讲变量声明,下一章会讲到函数声明,从第7章开始我们会看到类型声明。
从另一个角度来看,声明分为“是定义(Definition)的声明”和“不是定义的声明”,那么什么样的声明同时也是定义呢?简单地说,分配存储空间的声明同时也是定义,不分配存储空间的声明不是定义。
• 如果一个变量声明要求编译器为它分配存储空间,那么这个声明同时也是变量的定义。本章和接下来几章的示例代码中的变量声明都是要分配存储空间的,因而都是定义;等学到第19.2节我们会看到有些变量声明不分配存储空间,因而不是定义。
• 如果一个函数声明带有函数体,要求编译器为它生成指令(当然也需要分配存储空间来保存这些指令),那么这个声明同时也是函数的定义。在下一章我们会看到带函数体的声明和不带函数体的声明,不带函数体的声明不是函数定义。
• 类型声明总是不分配存储空间的,所以严格来说只有类型声明而没有类型定义,但通常我们习惯说“定义了某种类型”,所以在本书中“类型定义”和“类型声明”表示相同的含义,不加区分。
声明也是以;号结尾,这一点和语句类似,但是在语法上声明和语句是有区别的,语句只能出现在函数体中,而声明既可以出现在函数体中也可以出现在所有函数之外。
浮点型有三种:float是单精度浮点型;double是双精度浮点型;long double是精度更高的浮点型。它们之间的区别和转换规则将在第14章详细介绍,在随后的几章中我们只使用double类型,上一节介绍的常量3.14是double类型的常量,printf的%f也是double型的转换说明(注意%f不是float型的转换说明)。给变量起名不能太随意,上面四个变量的名字就不够好,我们猜不出这些变量是用来存什么的,像下面这样起名就比较有意义:
char firstletter; char lastletter; int hour, minute;
在这个例子中我们还看到两个相同类型的变量(同样是int类型的hour和minute)可以一起声明。
给变量起名有一定的限制,C语言规定必须以字母或下划线_(Underscore)开头,后面可以跟若干个字母、数字、下划线,但不能有其他字符。例如这些是合法的变量名:Abc、__abc__、_123。但这些是不合法的变量名:3abc、ab$。其实这条规则不仅适用于变量名,也适用于所有可以由程序员起名的语法元素,例如以后要讲的函数名、宏定义、结构体成员名等,在C语言中这些统称为标识符(Identifier)。
另外要注意,表示类型的char、int、float、double等虽然符合上述规则,但也不能用作标识符。在C语言中有些单词有特殊意义,不允许用作标识符,这些单词称为关键字(Keyword)或保留字(Reserved Word)。通常用于编程的文本编辑器都会高亮显示(Highlight)这些关键字,所以只要小心一点通常不会误用作标识符。C99规定的关键字有:
auto break case char const continue default do double else enum extern float for goto if inline int long register restrict return short signed sizeof static struct switch typedef union unsigned void volatile while _Bool _Complex _Imaginary
还有一点要注意,一般来说应避免使用以下划线开头的标识符,以下划线开头的标识符只要不和C语言关键字冲突都是合法的,但是往往被编译器用作一些功能扩展(比如第18.4节讲到gcc的__attribute__语法),C标准库也定义了很多以下划线开头的标识符留作内部使用,所以除非你对编译器的特性和C标准库的实现特别清楚,一般应避免使用这种标识符,以免造成命名冲突。
请记住:理解一个概念不是把定义背下来就行了,一定要理解它的外延和内涵,也就是什么情况属于这个概念,什么情况不属于这个概念,什么情况虽然属于这个概念但一般推荐的做法(Best Practice)是要尽量避免这种情况,这才算是真正理解了。