重学c语言系列二---(变量)
2014-03-14 02:39
176 查看
在C语言中,对变量的存储类型说明有以下四种:
auto 自动变量
register 寄存器变量
extern 外部变量
static 静态变量
自动变量和寄存器变量属于动态存储方式,外部变量和静态变量属于静态存储方式。
按作用域又可分为全局变量和局部变量
自动(auto)变量
C语言规定, 函数内凡未加存储类型说明的变量均视为自动变量, 也就是说自动变量可省去说明符auto
作用域和生存期都局限于定义它的个体内( 函数或复合语句内),我当初理解就是最内层包含它的花括号内。
需要注意的是,变量从声明开始就是可见的了。
举例:
这种变量存放在CPU的寄存器中,使用时,不需要访问内存,而直接从寄存器中读写, 这样可提高效率。寄存器变量的说明符是register。
对于循环次数较多的循环控制变量及循环体内反复使用的变量均可定义为寄存器变量。
求∑200i=1imain()
{
register i,s=0;
for(i=1;i<=200;i++)
s=s+i;
printf("s=%d/n",s);
}
本程序循环200次,i和s都将频繁使用,因此可定义为寄存器变量。对寄存器变量还要说明以下几点:
1. 只有局部自动变量和形式参数才可以定义为寄存器变量。因为寄存器变量属于动态存储方式。凡需要采用静态存储方式的量不能定义为寄存器变量。
2. 在Turbo C,MS C等微机上使用的C语言中, 实际上是把寄存器变量当成自动变量处理的。因此速度并不能提高。
而在程序中允许使用寄存器变量只是为了与标准C保持一致。
ps:按照《c专家编程》书中的观点,这样设计是不合理,应该是由编译器处理变量储存的分配工作,这样肯定会比人为死板设定更灵活,实际运行更有效率
虽然这样减轻了编译器的负担,而只是吧工作交给了程序员。
全局变量也称为外部变量,它是在函数外部定义的变量。 它不属于哪一个函数,它属于一个源程序文件。
其作用域是整个源程序(严谨一点是在使用位子说明后产生作用)。在函数中使用全局变量,一般应作全局变量说明。
否则作用域应该是从声明处到整个源程序结束
举例:
只有在函数内经过说明的全局变量才能使用。全局变量的说明符为extern。
即在一个函数之前定义的全局变量,在该函数内使用可不再加以说明。
外部变量的几个特点:
1. 外部变量和全局变量是对同一类变量的两种不同角度的提法。全局变量是从它的作用域提出的,外部变量从它的存储方式提出的,表示了它的生存期。
2. 当一个源程序由若干个源文件组成时, 在一个源文件中定义的外部变量在其它的源文件中也有效。例如有一个源程序由源文件Source1.C和Source2.C组成:
Source1.C
int a,b; /*外部变量定义*/
char c; /*外部变量定义*/
main()
{
……
}
Source2.C
extern a,b; /*外部变量说明*/
extern c; /*外部变量说明,只需要标示符就行了,不再需要类型声明*/
func (int x,y)
{
……
}
在Source1.C和Source2.C两个文件中都要使用a,b,c三个变量。在Source1.C文件中把a,b,c都定义为外部变量。在Source2.C文件中用extern把三个变量说明为外部变量,
表示这些变量已在其它文件中定义,并把这些变量的类型和变量名,编译系统不再为它们分配内存空间。
ps: gcc source1.c source2.c -o a.out
静态局部变量属于静态存储方式,它具有以下特点:
(1)静态局部变量在函数内定义,但不象自动变量那样,当调用时就存在,退出函数时就消失。静态局部变量始终存在着,也就是说它的生存期为整个源程序。
(2)静态局部变量的生存期虽然为整个源程序,但是其作用域仍与自动变量相同,即只能在定义该变量的函数内使用该变量。退出该函数后,
尽管该变量还继续存在,但不能使用它。
对基本类型的静态局部变量若在说明时未赋以初值,则系统自动赋予0值。而对自动变量不赋初值,则其值是不定的。
全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。
这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,
非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效,
在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,
因此可以避免在其它源文件中引起错误。从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。
把全局变量改变为静态变量后是改变了它的作用域, 限制了它的使用范围。因此static 这个说明符在不同的地方所起的作用是不同的。
auto 自动变量
register 寄存器变量
extern 外部变量
static 静态变量
自动变量和寄存器变量属于动态存储方式,外部变量和静态变量属于静态存储方式。
按作用域又可分为全局变量和局部变量
自动(auto)变量
C语言规定, 函数内凡未加存储类型说明的变量均视为自动变量, 也就是说自动变量可省去说明符auto作用域和生存期都局限于定义它的个体内( 函数或复合语句内),我当初理解就是最内层包含它的花括号内。
需要注意的是,变量从声明开始就是可见的了。
举例:
#include<stdio.h> int i=1; int main(){ int i=i; printf("%d",i); }这段程序的输出其实并不是1,而是不确定的,i从声明开始就可见了,在作用域了,它遮盖了全局变量。
寄存器(register)变量
上述各类变量都存放在存储器内, 因此当对一个变量频繁读写时,必须要反复访问内存储器,从而花费大量的存取时间。 为此,C语言提供了另一种变量,即寄存器变量。这种变量存放在CPU的寄存器中,使用时,不需要访问内存,而直接从寄存器中读写, 这样可提高效率。寄存器变量的说明符是register。
对于循环次数较多的循环控制变量及循环体内反复使用的变量均可定义为寄存器变量。
求∑200i=1imain()
{
register i,s=0;
for(i=1;i<=200;i++)
s=s+i;
printf("s=%d/n",s);
}
本程序循环200次,i和s都将频繁使用,因此可定义为寄存器变量。对寄存器变量还要说明以下几点:
1. 只有局部自动变量和形式参数才可以定义为寄存器变量。因为寄存器变量属于动态存储方式。凡需要采用静态存储方式的量不能定义为寄存器变量。
2. 在Turbo C,MS C等微机上使用的C语言中, 实际上是把寄存器变量当成自动变量处理的。因此速度并不能提高。
而在程序中允许使用寄存器变量只是为了与标准C保持一致。
ps:按照《c专家编程》书中的观点,这样设计是不合理,应该是由编译器处理变量储存的分配工作,这样肯定会比人为死板设定更灵活,实际运行更有效率
虽然这样减轻了编译器的负担,而只是吧工作交给了程序员。
外部(extern)变量
(关于extern关键词与c++引用c函数等一些关系此处不讨论)全局变量也称为外部变量,它是在函数外部定义的变量。 它不属于哪一个函数,它属于一个源程序文件。
其作用域是整个源程序(严谨一点是在使用位子说明后产生作用)。在函数中使用全局变量,一般应作全局变量说明。
否则作用域应该是从声明处到整个源程序结束
举例:
#include<stdio.h> int main(){ extern int i; printf("%d",i); } int i=1;如果没有extern说明,是编译不了的,即未说明前全局变量作用不了那里。
只有在函数内经过说明的全局变量才能使用。全局变量的说明符为extern。
即在一个函数之前定义的全局变量,在该函数内使用可不再加以说明。
外部变量的几个特点:
1. 外部变量和全局变量是对同一类变量的两种不同角度的提法。全局变量是从它的作用域提出的,外部变量从它的存储方式提出的,表示了它的生存期。
2. 当一个源程序由若干个源文件组成时, 在一个源文件中定义的外部变量在其它的源文件中也有效。例如有一个源程序由源文件Source1.C和Source2.C组成:
Source1.C
int a,b; /*外部变量定义*/
char c; /*外部变量定义*/
main()
{
……
}
Source2.C
extern a,b; /*外部变量说明*/
extern c; /*外部变量说明,只需要标示符就行了,不再需要类型声明*/
func (int x,y)
{
……
}
在Source1.C和Source2.C两个文件中都要使用a,b,c三个变量。在Source1.C文件中把a,b,c都定义为外部变量。在Source2.C文件中用extern把三个变量说明为外部变量,
表示这些变量已在其它文件中定义,并把这些变量的类型和变量名,编译系统不再为它们分配内存空间。
ps: gcc source1.c source2.c -o a.out
静态(static)变量
静态变量又分为静态全局变量和静态局部变量。静态局部变量属于静态存储方式,它具有以下特点:
(1)静态局部变量在函数内定义,但不象自动变量那样,当调用时就存在,退出函数时就消失。静态局部变量始终存在着,也就是说它的生存期为整个源程序。
(2)静态局部变量的生存期虽然为整个源程序,但是其作用域仍与自动变量相同,即只能在定义该变量的函数内使用该变量。退出该函数后,
尽管该变量还继续存在,但不能使用它。
对基本类型的静态局部变量若在说明时未赋以初值,则系统自动赋予0值。而对自动变量不赋初值,则其值是不定的。
全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。
这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,
非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效,
在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,
因此可以避免在其它源文件中引起错误。从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。
把全局变量改变为静态变量后是改变了它的作用域, 限制了它的使用范围。因此static 这个说明符在不同的地方所起的作用是不同的。
相关文章推荐
- C语言系列——局部变量和全局变量
- C语言中变量声明和定义----笛风读书笔记系列
- 【我解C语言面试题系列】002 局部变量和全局变量小结?
- 重学c语言系列四--变量在内存中的布局(二)
- 【我解C语言面试题系列】002 局部变量和全局变量小结?
- 重学c语言系列三---变量在内存中的布局
- 【c语言问题系列教程之一】变量声明和初始化
- JAVA面试题解惑系列(三)——变量(属性)的覆盖
- 关于C语言变量和函数命名规范
- 【linux草鞋应用编程系列】_2_ 环境变量和进程控制
- Unity Shader 系列笔记一:内置变量
- C语言变量的存储布局
- 解决全局变量共享---C语言的extern关键字用法
- awk 系列:如何使用 awk 内置变量
- 第17节 C语言之函数与全局变量局部变量
- 追着嘟嘟学c#系列入门第二篇-----c#的变量和数据类型【蓝鸥出品】
- C语言中全局变量、局部变量、静态全局变量、静态局部变量的区别
- C语言的变量
- 从c语言中常用变量的生命周期,作用域,默认值,内存区域及链接属性
- C/C++——C++变量的作用域与生命周期,C语言中变量的作用域和生命周期