-
局部变量和全局变量
定义变量可能有三种情况:
- 在函数的开头定义
- 在函数内的复合语句内定义
- 在函数的外部定义
-
局部变量
- 在一个函数内部定义的变量只在本函数范围内有效
- 在复合语句内定义的变量只在本复合语句范围内有效
- 在函数内部或复合语句内部定义的变量称为“局部变量”
-
全局变量
- 在函数内定义的变量是局部变量,而在函数之外定义的变量称为外部变量,也称全局变量
- 全局变量可以为本文件中其他函数所共用
- 有效范围为从定义变量的位置开始到本源文件结束
- 可以通过extern关键字扩展到其它文件使用
例 :使用全局变量接收2个输入的整数,并计算最大值存入全局变量中输出
解题思路:
- 定义三个整型全局变量int a,b,m;
- 写个求最大值的函数max,运算数为全局变量,运算结果存入全局变量m中
- 在主函数调用max函数
- 打印最大值,也就是全局变量m的值
#include <stdio.h> //包含标准IO头文件
extern int a,b,m; //对全局变量声明,将其作用域扩展到此处
void max(void); //对函数max进行声明
int main() //主函数,程序的入口
{
scanf(“%d,%d\n”,&a,&b); //输入值存入全局变量a,b
max(); //调用函数max求出最大值
printf(“最大值是%d\n”,m); //打印最大值
return 0; //函数的返回值为0
}
int a,b,m; //定义int型全局变量a,b,m
void max(void) //定义max函数
{
m = a > b ? a :b;
} //求出最大值存入全局变量m中
-
动态存储方式与静态存储方式
- 从变量的作用域的角度来观察,变量可以分为全局变量和局部变量
- 从变量值存在的时间(即生存期)观察,变量的存储有两种不同的方式:静态存储方式和动态存储方式
- 静态存储方式是指在程序运行期间由系统分配固定的存储空间的方式
- 动态存储方式是在程序运行期间根据需要进行动态的分配存储空间的方式
每一个变量和函数都有两个属性:数据类型和数据的存储类别
- 数据类型,如整型、浮点型等
- 存储类别指的是数据在内存中存储的方式(如静态存储和动态存储)
- 存储类别包括:
自动的、静态的、寄存器的、外部的
4. 根据变量的存储类别,可以知道变量的作用域和生存期
-
局部变量的存储类别
1.自动变量(auto变量)
- 局部变量,如果不专门声明存储类别,都是动态地分配存储空间的
- 调用函数时,系统会给局部变量分配存储空间,调用结束时就自动释放空间。因此这类局部变量称为自动变量
- 自动变量用关键字auto作存储类别的声明
2.静态局部变量(static局部变量)
希望函数中的局部变量在函数调用结束后不消失而继续保留原值,即其占用的存储单元不释放,在下一次再调用该函数时,该变量已有值(就是上一次函数调用结束时的值),这时就应该指定该局部变量为“静态局部变量”,用关键字static进行声明
例:输出1到5的阶乘值。
解题思路:可以编一个函数用来进行连乘,如第1次调用时进行1乘1,第2次调用时再乘以2,第3次调用时再乘以3,依此规律进行下去。
3.寄存器变量(register变量)
- 一般情况下,变量(包括静态存储方式和动态存储方式)的值是存放在内存中的
- 寄存器变量允许将局部变量的值放在CPU中的寄存器中
- 现在的计算机能够识别使用频繁的变量,从而自动地将这些变量放在寄存器中,而不需要程序设计者指定
-
全局变量的存储类别
- 全局变量都是存放在静态存储区中的。因此它们的生存期是固定的,存在于程序的整个运行过程
- 一般来说,外部变量是在函数的外部定义的全局变量,它的作用域是从变量的定义处开始,到本程序文件的末尾。在此作用域内,全局变量可以为程序中各个函数所引用。
在一个文件内扩展外部变量的作用域
- 外部变量有效的作用范围只限于定义处到本文件结束。
- 如果用关键字extern对某变量作“外部变量声明”,则可以从“声明”处起,合法地使用该外部变量
例: 调用函数,求3个整数中的大者。
解题思路:用extern声明外部变量,扩展外部变量在程序文件中的作用域。
#include <stdio.h>
int main()
{
int max( );
extern int A,B,C;
scanf(“%d %d %d”,&A,&B,&C);
printf("max is %d\n",max());
return 0;
}
int A ,B ,C;
int max( )
{
int m;
m=A>B?A:B;
if (C>m) m=C;
return(m);
}
将外部变量的
- 如果一个程序包含两个文件,在两个文件中都要用到同一个外部变量Num,不能分别在两个文件中各自定义一个外部变量Num
- 应在任一个文件中定义外部变量Num,而在另一文件中用extern对Num作“外部变量声明”
- 在编译和连接时,系统会由此知道Num有“外部链接”,可以从别处找到已定义的外部变量Num,并将在另一文件中定义的外部变量num的作用域扩展到本文件作用域扩展到其他文件
例: 给定b的值,输入a和m,求a*b和am的值。
解题思路:
- 分别编写两个文件模块,其中文件file1包含主函数,另一个文件file2包含求am的函数。
- 在file1文件中定义外部变量A,在file2中用extern声明外部变量A,把A的作用域扩展到file2文件。
文件file1.c:
#include <stdio.h>
int A;
int main()
{
int power(int);
int b=3,c,d,m;
scanf("%d,%d",&A,&m);
c=A*b;
printf("%d*%d=%d\n",A,b,c);
d=power(m);
printf("%d**%d=%d\n",A,m,d);
return 0;
}
文件file2.c:
extern A;
int power(int n)
{
int i,y=1;
for(i=1;i<=n;i++)
y*=A;
return(y);
}
说明:
- 不要误认为对外部变量加static声明后才采取静态存储方式,而不加static的是采取动态存储
- 声明局部变量的存储类型和声明全局变量的存储类型的含义是不同的
- 对于局部变量来说,声明存储类型的作用是指定变量存储的区域以及由此产生的生存期的问题,而对于全局变量来说,声明存储类型的作用是变量作用域的扩展问题
用static 声明一个变量的作用是:
(1) 对局部变量用static声明,把它分配在静态存储区,该变量在整个程序执行期间不释放,其所分配的空间始终存在。
(2) 对全局变量用static声明,则该变量的作用域只限于本文件模块(即被声明的文件中)。
注意:用auto、register、static声明变量时,是在定义变量的基础上加上这些关键字,而不能单独使用。
下面用法不对:
int a;
static a;
编译时会被认为“重新定义”。
(4) 关于作用域和生存期的概念
对一个变量的属性可以从两个方面分析:
- 作用域:如果一个变量在某个文件或函数范围内是有效的,就称该范围为该变量的作用域
- 生存期:如果一个变量值在某一时刻是存在的,则认为这一时刻属于该变量的生存期
作用域是从空间的角度,生存期是从时间的角度
二者有联系但不是同一回事
(5) static对局部变量和全局变量的作用不同
- 局部变量使变量由动态存储方式改变为静态存储方式
- 全局变量使变量局部化(局部于本文件),但仍为静态存储方式
- 从作用域角度看,凡有static声明的,其作用域都是局限的,或者是局限于本函数内(静态局部变量),或者局限于本文件内(静态外部变量)
-
关于变量的声明和定义
- 一般为了叙述方便,把建立存储空间的变量声明称定义,而把不需要建立存储空间的声明称为声明
- 在函数中出现的对变量的声明(除了用extern声明的以外)都是定义
- 在函数中对其他函数的声明不是函数的定义
内部函数和外部函数
内部函数
如果一个函数只能被本文件中其他函数所调用,它称为内部函数。
在定义内部函数时,在函数名和函数类型的前面加static,即:
static 类型名 函数名(形参表)
- 内部函数又称静态函数,因为它是用static声明的
- 通常把只能由本文件使用的函数和外部变量放在文件的开头,前面都冠以static使之局部化,其他文件不能引用
- 提高了程序的可靠性
外部函数
- 如果在定义函数时,在函数首部的最左端加关键字extern,则此函数是外部函数,可供其他文件调用。
- 如函数首部可以为
extern int fun (int a, int b)
3. 如果在定义函数时省略extern,则默认为外部函数