C程序设计语言——七、函数(3)局部、全局、寄存器、外部变量
目录
一、变量的作用域:存在空间性
1、指变量在程序中的有效范围
2、局(内)部变量,分布在动态存储区
3、全(外)局变量,分布在静态存储区(静态局部变量也分布在此)
4、不同的变量所分配的程序区
二、变量的生存期:存在的时间性
1、静态存储(static) static int a;
2、动态存储(auto) auto int a;
三、C程序的存储类别
1、auto 型(自动变量)(缺省:系统默认状态)
2、static 型(静态变量)
3、register 型(寄存器变量)
4、extern 型(外部变量)
四、例题
1、《选择法对数组中的6个整数按由小到大排序,过程由函数实现》
2、《编写一个函数,判断一个5位数是否是回文数》
3、《编程找出3~1000的所有完数》
4、《斐波那契数列》
一、变量的作用域:存在空间性
1、指变量在程序中的有效范围
2、局(内)部变量,分布在动态存储区
- 在函数内(符合语句内)定义的变量,它只在本函数内(复合语句内)有效
- 生存期是该语句块,进入语句块时获得内存,仅能由语句块内语句访问,退出语句块时释放内存,不再有效;随用随分配,用完就释放;
- 定义时不会自动初始化,除非程序员制定初值;
- 并列语句块各自定义的同名变量互补干扰,不同函数可以有相同的变量名;
- 形参和实参可以同名;
- 形参也是局部变量;
- 主函数里的变量也是局部变量;
- 复合语句里定义的变量也是局部变量;复合语句的局部变量和本函数的局部变量同名时,本函数的局部变量不起作用;内部的优先
3、全(外)局变量,分布在静态存储区(静态局部变量也分布在此)
- 在所有函数之外定义的变量;
- 生存期是整个程序,从程序运行起占内存,程序退出时释放内存;
- 有效范围是从定义变量的位置开始到本程序结束;
- 全局变量必须在所有函数之外定义,且只能定义一次;
- 如果在其作用域内的函数定义了同名局部变量,则在局部变量的作用域内,同名全局变量暂时不起作用;内部的优先
- 可以通过声明一个extern的全局变量扩展全局变量的作用域,也可以通过定义一个static的全局变量限制这种扩展;
- 全局变量增加函数间数据联系,函数只能返回一个值,可用影响全局变量的方式带回给主调函数多个值;
- 全局变量会降低程序的清晰性,因为所有函数都能影响变量的值;
- 全局变量的初值为0。
4、不同的变量所分配的程序区
程序区 | 静态存储区 | 动态存储区 |
变量作用域 | 全(外)局变量,静态局部变量 | 局部变量,寄存器变量 |
分配 | 编译时分配内存 | 随用随分配 |
释放 | 用完不释放,程序结束时释放 | 用完就释放 |
初值 | 初值为0 |
初值为随机数 |
初始化 | 初始化只执行一次 | 初始化执行多次 |
二、变量的生存期:存在的时间性
1、静态存储(static) static int a;
- static 数据类型 变量名表;
- 局部静态变量编译时赋初值一次,以后每次调用不再重新赋初值,而是保留上次函数调用结束时的值;
- 局部静态变量定义时不赋初值则自动赋初值0;
- 全局变量、静态局部变量
2、动态存储(auto) auto int a;
- 数据类型 变量名表;
- 进入语句块时自动申请内存,退出时自动释放内存;
- 未赋初值时,其值不确定,每次调用重新赋值;
- 局部变量(不含静态局部变量)、形参;
- 默认为auto = int a;
三、C程序的存储类别
1、auto 型(自动变量)(缺省:系统默认状态)
- 每次重新调用
2、static 型(静态变量)
- 保留上次调用结果
3、register 型(寄存器变量)
- 为了提高某些变量和函数形参的存取速度,C允许将局部变量的值存在cpu寄存器中,不用去内存取数据
4、extern 型(外部变量)
- 如果需要用其他文件中的全局变量,则需要在本文件中使用extern int x;说明一下,全局变量扩展到其他文件
注意:
- 只有局部自动变量和形参能作为寄存器变量,静态变量不可以
- 寄存器变量数目有限,不能定义任意多个寄存器变量
- 一个变量只能声明一个存储类型
- 全局变量只能定义一次
- 限制全局变量的范围:static int x;
- 拓展全局变量的范围:extern int x;
四、例题
1、《选择法对数组中的6个整数按由小到大排序,过程由函数实现》
#include<stdio.h>
void sort(int a[],int n)
{int i,j,k,t; //选择法排序for(i=0;i<n-1;i++) //比较轮次{k=i;for(j=i+1;j<n;j++) //打擂台if(a[j]<a[k]) k=j; //降序t=a[k];a[k]=a[i];a[i]=t;}
}
void main()
{int ay[6],i;for(i=0;i<6;i++)scanf("%d",&ay[i]);sort(ay,6);printf("输出:\\n");for(i=0;i<6;i++)printf("%d\\n",ay[i]);
}
2、《编写一个函数,判断一个5位数是否是回文数》
#include<stdio.h>
void main()
{int fan(long n);int n;scanf("%ld",&n);if(fan(n))printf("%ld是回文数\\n",n);elseprintf("%ld不是回文数\\n",n);}
int fan(long n)
{int g,s,q,w;w=n/10000; //万位q=n/1000%10; //千位s=n/10%10; //十位g=n%10; //个位if(g==w&&s==q)return 1;elsereturn 0;
}
3、《编程找出3~1000的所有完数》
一个数如果恰好等于它的因子之和,这个数称为完数
#include<stdio.h>
void main()
{int wan(long n);long n;printf("3~1000之间的完数有:\\n");for(n=3;n<=1000;n++)if(wan(n))printf("%4ld",n);printf("\\n");}
int wan(long n)
{int i,s=0;for(i=1;i<=n/2;i++) //求因子和if(n%i==0) s=s+i;if(s==n)return 1;elsereturn 0;
}
4、《斐波那契数列》
#include<stdio.h>
#define N 5
int fib(int n);
void main()
{int i;printf("斐波那契数列:\\n");for(i=1;i<=N;i++)printf("%4d",fib(i));printf("\\n");
}
int fib(int n)
{if((n==1)||(n==2))return 1;elsereturn fib(n-1)+fib(n-2);
}
拜拜~