一、局部变量与全局变量
1.1、局部变量
函数内部或块内定义的变量。
1.2、局部变量的作用域(作用范围)
- 主函数中定义的变量只在主函数中有效,因为主函数也是一个函数,它与其他函数是平行关系。
- 不同的函数中可以使用相同的变量名,因为它们代表不同的变量,它们之间互不干扰。
- 在一个函数内部,在复合语句(块)中定义变量,这些变量只在本复合语句中有效。
- 如果局部变量的有效范围重叠,则有效范围小的优先。
#include "stdio.h"
void main()
{
int i=2,j=3,k;
k=j+i;
{
int h=8;
printf("%d\n",h);
}
printf("%d\n",k);
}
1.3、全局变量
在函数外面定义的变量为全局变量
1.4、全局变量的作用域
全局变量为文本中的其他函数共有,它的有效范围是从定义点开始,直到源文件结束,全局变量又称为外部变量。
/*打印10个100~200之间的随机数并输出最大和最小数*/
#include "stdio.h"
#include "math.h"
#include "stdlib.h"
int min; // 全局变量
int fid()
{
int max,r,i; // max局部变量
r=rand()%101+100;
//printf(" %d",r);
max=r;min=r;
for(i=1;i<10;i++){
r=rand()%101+100; // 产生100 ~200之间的随机数
if(r>max)
max=r;
if(r<min)
min=r;
printf("%d\t",r);
}
return max;
}
void main()
{
int m = fid();
printf("\n最大数:%d\n,最小数:%d\n",m,min);
}
/*局部变量与全局变量同名案例
当局部变量与全局变量同名,在局部变量的作用范围内,全局变量不起作用,局部变量优先
*/
#include "stdio.h"
//#include "math.h"
//#include "stdlib.h"
int a=3,b=5; // 全局变量 a,b
int max(int a, int b) // 局部变量 a,b
{
int c;
c=a>b?a:b;
return c;
}
void main()
{
int a=8; // 局部变量a
printf("%d\n",max(a,b));
}
/*
不建议使用全局变量的原因:
为了方便区别全局变量和局部变量,将局部变量的第一个字母用大写表示
1、全局变量在程序的全部执行过程中都占用存储单元,而不是在需要时才开辟单元。
2、它使等函数的通用性降低。
3、全局变量过多,会降低程序的清晰性
*/
1.5、全局变量的注意事项
为了方便区别全局变量和局部变量,将局部变量的第一个字母用大写表示
1、全局变量在程序的全部执行过程中都占用存储单元,而不是在需要时才开辟单元。
2、它使等函数的通用性降低。
3、全局变量过多,会降低程序的清晰性
二、变量的存储类别
按变量的存在时间(生命周期)来划分,可以分为静态存储变量和动态存储变量。
动态存储变量(这时一种节省内存空间的存储方式):当程序运行进入定义它的函数或复合语句时才被分配存储空间;程序运行结束离开此函数或复合语句时,释放动态动态存储变量所占用的空间。
静态存储变量:在程序运行的整个过程中,始终占用固定的内存空间,直到程序运行结束,才释放占用的内存空间。静态存储类别的变量被放于内在空间的静态存取区域
c程序运行时,占用三部分的内存空间
- 程序运行时数据分别存储在静态存储区和动态存储区;
- 静态存储区用来存放程序运行周期内所占用固定存储单元的变量,如全局变量;
- 动态存储区用来存放不需要长期占用内存的变量,如函数的形参等;
- 变量的存储类别有四种:自动类型(auto),寄存器类型(register),静态类型(static)和外部类型(extern)。
- 动态变量:自动类型、寄存器类型
- 静态变量:静态类型,外部类型
2.1、自动类型变量(auto)
用关键字auto说明变量是自动类型变量
格式:
auto 类型 变量名;
自动类型变量属于动态局部变量,存储在动态存储区,定义时可以加auto也可以不加,由此可知局部变量都是自动类型变量
自动类型的分配和释放存储空间的工作是由编译系统自动处理的
int function1(int a)
{
auto int b,c=3;
/*形参a,变量b,c都是自动类型变量
在调用该函数时,系统给它们分配存储空间调用结束时自动释放存储空间*/
}
2.3、寄存器类型变量(register)
用关键字register说明变量是寄存器类型
格式:
register 类型 变量名;
register int a;
寄存器变量是动态局部变量,存放于CPU的寄存器或动态存储区中,以提高存取速度,寄存器的存取速度比内存快。
该类变量的作用域、生存期与自动类型变量相同;如果没有存放在通用寄存器中,按自动类型变量处理
计数机中寄存器个数是有限的,使用register的注意事项
- 寄存器类型变量不宜过多,一般将频繁使用的变量放在寄存器中(循环涉及的内部变量),以提高程序执行的速度
- 变量的长度应该与常用寄存器的长度相当,一般为int型或char型。
- 寄存器变量的定义通常是不必要的,当今优化的编译系统能够识别频繁使用的变量,并能够在不需要编译人员说明变量是register的时候,把频繁使用的变量放到寄存器中。
#include "stdio.h"
//#include "math.h"
//#include "stdlib.h"
void main()
{
int x=5,y=10,k; // 自动类型变量
for(k=1;k<=2;k++)
{
register int m=0,n=0;
m=m+1;
n=n+y;
printf("m=%d\t=%d\n",m,n);
}
}
/*
用关键字register说明变量是寄存器类型
格式:
register 类型 变量名;
register int a;
寄存器变量是动态局部变量,存放于CPU的寄存器或动态存储区中,以提高存取速度,寄存器的存取速度比内存快。
该类变量的作用域、生存期与自动类型变量相同;如果没有存放在通用寄存器中,按自动类型变量处理
计数机中寄存器个数是有限的,使用register的注意事项
1、寄存器类型变量不宜过多,一般将频繁使用的变量放在寄存器中(循环涉及的内部变量),以提高程序执行的速度
2、变量的长度应该与常用寄存器的长度相当,一般为int型或char型。
*/
2.4、静态变量(static)
- 静态类型的变量占用静态存储区,用static关键字来说明
- static 类型 变量名;
- static int a;
- 静态变量=静态局部变量+静态全局变量
- c语言规定了静态局部变量(静态全局变量)有默认值:
- int类型等于0
- float型等于0.0
- 自动变量和寄存器变量没有默认值,值为随机数
- char型为'\0'
静态局部变量
静态局部变量是存储在静态存储区的,所以在整个程序开始的时候就被分配固定的存储单元,整个程序运行期间内不再被重新分配,故其生存期是整个程序的运行期间。
静态局部变量本身也是局部变量,具有局部变量的性质,即其作用域是局限在定义它的本函数内的,如果离开了定义它的函数,该变量就不再起作用,但其值任在,因为存储空间并未释放。
静态局部变量赋初值的时间是编译阶段,并且只被初值一次,即使它所有的函数调用结束,也不释放存储单元,因此不管调用多少此该静态局部变量的函数,它任保留上一次调用函数时的值。
2.5、外部变量
- 定义在任何函数之外的变量都叫做外部变量。外部变量通常用关键字extern说明。
- 一般形式: extern 类型 变量名;
- extern int a;
- extern double k;
一个文件中定义的全局变量默认为外部的,即extern关键字可以省略。但是如果其他文件要使用这个文件中定义的全局变量,则必须在使用前用extern作为外部声明,外部声明通常放在文件的开头
三、案例
#include <stdio.h>
extern int days();
extern int year,month,day;
void main(){
printf("输入年,月,日:\n");
scanf("%d%d%d",&year,&month,&day);
printf("%d月%d日是%d年的第%d\n",month,day,year,days());
}
int year,month,day;
int days()
{
int i,count=0;
int a[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
if((year%100)&&!(year%4)||!(year%400))
a[2]=20;
for(i=0;i<month;i++)
count+=a[i];
count=count+day;
return count;
}