一、局部变量和全局变量
1.局部变量
- 定义:在函数内部定义的变量,只在本函数范围内有效。
- 特点:
- 不同函数中可以使用相同名字的局部变量,它们代表不同的对象,互不干扰。
- 形式参数也是局部变量。
- 函数内的复合语句中定义的变量只在本复合语句中有效。
2.全局变量
- 定义:在函数之外定义的变量,称为外部变量,即全局变量。
- 特点:
- 全局变量可以为本文件中其他函数所共用,它的有效范围为从定义变量的位置开始到本源文件结束。
- 设置全局变量可以增加函数间数据联系的渠道,但过多使用会降低程序的可读性和可靠性。
- 如果在同一个源文件中,外部变量与局部变量同名,则在局部变量的作用范围内,外部变量被“屏蔽”,即它不起作用。
二、变量的存储类别
1.动态存储方式与静态存储方式
- 动态存储方式:在程序运行期间根据需要进行动态的分配存储空间的方式,如函数的形参、自动变量等数据存放在动态存储区。
- 静态存储方式:在程序运行期间由系统分配固定的存储空间的方式,全局变量全部存放在静态存储区中。
2.auto变量
- 定义:函数中的局部变量,如果不专门声明为static存储类别,都是动态地分配存储空间的,数据存储在动态存储区中,这类局部变量称为自动变量。
- 特点:自动变量用关键字auto作存储类别的声明,但关键字“auto”可以省略,隐含确定为“自动存储类别”。
3.static声明局部变量
- 定义:用关键字static声明的局部变量称为静态局部变量。
- 特点:
- 静态局部变量属于静态存储类别,在静态存储区内分配存储单元,在程序整个运行期间都不释放。
- 对静态局部变量是在编译时赋初值的,且只赋初值一次,在程序运行时它已有初值,以后每次调用函数时不再重新赋初值而只是保留上次函数调用结束时的值。
- 如在定义局部变量时不赋初值,对静态局部变量来说,编译时自动赋初值0(对数值型变量)或空字符(对字符变量);而对自动变量来说,如果不赋初值则它的值是一个不确定的值。
4.register变量
- 定义:用关键字register声明的变量叫做寄存器变量。
- 特点:
- 只有局部自动变量和形式参数可以作为寄存器变量,其他(如全局变量)不行。
- 一个计算机系统中的寄存器数目是有限的,不同的系统对register变量的处理方法也不同。
- 局部静态变量不能定义为寄存器变量。
5.用extern声明外部变量
- 在一个文件内声明外部变量:如果外部变量不在文件的开头定义,其有效的作用范围只限于定义处到文件结束。如果在定义点之前的函数想引用该外部变量,则应该在引用之前用关键字extern对该变量作“外部变量声明”。
- 在多文件的程序中声明外部变量:一个C程序由多个源程序文件组成时,在一个文件中想引用另一个文件中已定义的外部变量,需要在使用该外部变量的文件中用extern对其作“外部变量声明。
6.用static声明外部变量
- 定义:在定义外部变量时加一个static声明,该外部变量就成为静态外部变量。
- 特点:静态外部变量只能被本文件引用,而不能被其他文件引用。
7.关于变量的声明和定义
- 定义:一个函数一般由声明部分和执行语句组成,声明部分对有关的标识符的属性进行说明。对变量而言,建立存储空间的声明称为定义,如“int a;”既是声明,又是定义。
- 声明:不需要建立存储空间的声明称为声明,如“extern a;”是声明而不是定义。
- 作用:extern声明的作用是声明该变量是一个已在后面(或在其他文件中)已定义的外部变量,仅仅是为了扩展该变量的作用范围。
三、内部函数和外部函数
1.内部函数
- 定义:如果一个函数只能被本文件中其他函数所调用,它称为内部函数。在定义内部函数时,在函数名和函数类型的前面加static。
- 特点:使用内部函数,可以使函数的作用域只局限于所在文件,在不同的文件中有同名的内部函数,互不干扰。
2.外部函数
- 定义:在定义函数时,如果在函数首部的最左端加关键字extern,则表示此函数是外部函数,可供其他文件调用。如果在定义函数时省略extern,则隐含为外部函数。
- 特点:使用extern声明就能够在一个文件中调用其他文件中定义的函数,或者说把该函数的作用域扩展到本文件。
四、预处理命令
1.宏定义
- 不带参数的宏定义:用一个指定的标识符来代表一个字符串,在预编译时将程序中在该命令以后出现的所有的宏名都用指定的字符串代替。
- 带参数的宏定义:宏定义的一般形式为
#define宏名(参数表)字符串
,在程序中如果有带实参的宏,在展开时将实参字符串代替#define命令行中的形参。
2.“文件包含”处理
- 定义:一个源文件可以将另外一个源文件的全部内容包含进来,C语言提供了
#include
命令用来实现“文件包含”的操作,其一般形式为#include"文件名" 或 #include<文件名>
。 - 特点:
- 一个
#include
命令只能指定一个被包含文件,如果要包含n个文件,要用n个#include
命令。 - 在
#include
命令中,文件名可以用双撇号或尖括号括起来,二者的区别是用尖括号时,系统到存放C库函数头文件的目录中寻找要包含的文件;用双撇号时,系统先在用户当前目录中寻找要包含的文件,若找不到,再按标准方式查找。 - 被包含文件与其所在的文件,在预编译后已成为同一个文件,因此,如果被包含文件中有全局静态变量,它也在所在文件中有效,不必用extern声明。
- 一个
3.条件编译
- 定义:希望程序中一部分内容只在满足一定条件时才进行编译,这就是“条件编译”。
- 形式:
#ifdef标识符 程序段1 #else 程序段2 #endif
:若所指定的标识符已经被#define
命令定义过,则在程序编译阶段编译程序段1;否则编译程序段2。#ifdef标识符 程序段1 #endif
:若所指定的标识符已经被#define
命令定义过,则在程序编译阶段编译程序段1;否则不编译。