zoukankan      html  css  js  c++  java
  • 【转载】变量的存储类型

    转载自:http://edu.cnzz.cn/852996fd.html

    C语言的变量有4种存储类型,分别是auto(自动型)、static(静态型)、register(寄存器型)和extern(外部型)。在定义或说明一个变量时可以加上存储类型关键字,以限定其存储类别。

    存 储类型决定了系统将在哪一个数据存储区为变量分配存储空间。auto型将在堆栈区分配存储空间;static型将在静态数据区分配存储空 间;register型将在CPU内部的寄存器中分配存储空间;而extern将不为变量分配存储空间,extern声明该变量在别的地方已经分配了存储 空间。
    变量存储类型关键字只需加在变量定义语句类型关键字前面即可。
    char ch1;/*定义了一个char型变量ch1,其存储类型默认为自动型(必须是内部变量)*/
    static char ch2;/*定义了一个char型变量ch2,其存储类型指定为静态型*/
    注意:以上auto型是对内部变量而言,对于外部变量不存在自动型的问题。内部变量自动在堆栈区分配空间。事实上,内部变量默认为自动型,所以auto限定词没有任何用处。
    1.自动型变量
    定义一个内部变量时,如果将auto加在定义语句前面,则该变量是自动型变量;定义内部变量时,如果没有加任何存储类型限定,该变量默认为自动型变量。
    auto只能修饰内部变量,不能修饰外部变量。也就是说只有内部变量可以定义为自动型变量,外部变量不能定义为自动型变量。
    事实上,auto没有什么实际用处。内部变量已经默认为自动型变量。
    2.静态型变量
    外部变量和内部变量都可以定义为静态型变量。
    如果在定义一个内部变量时,在定义语句最前面加上static存储类型限定词,那么该变量将是一个静态型变量。该变量将在静态数据区分配存储空间。这种变量作用域虽然只在函数内部,但是该变量将一直在静态数据区占据存储空间,直到程序运行结束。
    定义外部变量时,如果不加存储类型限定词,它将在静态数据区分配存储空间。它的作用域除了本文件以外,其他文件通过extern语句声明后也可访问。
    但是,如果在定义一个外部变量时,加上static限定词,其作用域将变窄,该变量只在本文件中可见,在其他文件中将不可见,此时在其他文件中即使用extern声明也不能扩展其作用域。这是一个外部静态型变量,也在静态数据区分配存储空间。
    注意:对于函数的作用域也是这样,如果在函数定义时加上了static限定词,那么该函数也只在其定义文件内可见(“可见”的意思就是在在该范围内可以使用)。在其他文件中即使声明了也不可以调用。另外,对于函数声明而言可以省略extern关键字。
    一 个文件中加了static的同名外部变量将隐藏其他文件中定义的未加static的外部变量。也就是说,static变量能够屏蔽其他文件中的同名外部变 量,这功能有点像函数的内部变量能够屏蔽同名的外部变量一样。但是,不同文件中如具有未加static的多个同名外部变量则是非法的。
     
    static限定词常用于外部变量,也可用于函数。正常情况下,函数名字是全局的,对程序的任何部分都是可见的。如果在定义一个函数时用static限定,该函数将在其定义文件以外不可见。
    static 限定词同样能够应用于内部变量。此时,该变量将是一个内部静态型变量。内部静态型变量就像自动变量一样是属于某个特定函数的内部变量。但是,同自动型变量 不同,它们一直在内存中存在,而不是随着函数的每次调用而存在,随着函数调用结束而消失。这意味着内部静态型变量提供了单个函数内部私有的、持久的存储。 也就是说内部静态型变量只在函数被调用时起作用,但是它将在程序的整个运行时间内一直占据内存空间。
    3.寄存器型变量
    register 限定词通知编译器--程序中的变量将频繁使用。它的意思是建议编译器将程序中用register限定的变量放置在计算机的内部寄存其中,这样可能得到更小 更快的程序。但是,编译器将根据实际情况考虑是否采纳该建议--是否将register变量处理为寄存器变量最终决定权还是在编译器。
    如下使用register:
    register int x;/*x必须是内部变量*/
    register char ch;/*ch必须是内部变量*/
    register只能用于限定自动型变量和函数的形式参数。也就是说register只对内部变量起作用,而且只能限定内部非静态型变量,不能限定内部静态型变量。
    register也可以应用于形式参数,格式如下:
    f(register unsigned m,register long n) /*register应用于形式参数*/
    {
         register int i; /* register应用于内部变量*/
    }
    在传统C中,register变量的使用有诸多限制,它决定于硬件的实现方式。在每一个函数中只有少数几个变量可以保存在寄存器中,而且也只有特定的类型才行。过量的register变量看起来是无害的,但是超量以后,编译器将忽略新的register变量。另外不管register变量实际上是否被编译器设置为寄存器型变量,都不可能取得该变量的地址。 寄存器型变量的类型和数量的多少随计算机不同而异。register变量一般只能够设置几个。传统C的register类型限定于char、int等类 型。像float、double、数组等是不可以设定为register型变量的。但是,在最新C99标准中,任何类型都可以定义为register变 量,register声明的目的只是告诉编译器以尽快的速度处理该变量,编译器不见得非把它处理为register变量。
     
    4.外部型变量
    如extern用于变量定义语句前面,那么该语句就只能是一个声明语句了,他不再是一个变量定义语句。它仅仅是一个声明--声明该变量已经在别的地方定义,只是告诉编译器该变量的类型。
    extern int sp;/* sp在别的地方定义,并分配存储单元,本语句只是声明它已经定义过*/
    该语句声明了sp在别的地方已经定义,并分配了存储空间,本语句只是说明sp已经定义过的类型为int,并不再为它分配内存空间。这样声明以后,在本文件余下部分就可以使用sp了。
  • 相关阅读:
    Google Earth 使用的经纬度格式及转换
    ADO.NET Entity Framework 一个简单数据绑定例子
    Oracle 异常 ORA01861: literal does not match format string(字符串格式不匹配)
    备份和还原 甲方 Oracle 数据库 问题一大堆
    使用 xsd.exe 命令工具 将 xsd架构 生成 类文件
    简单的源代码统计工具(统计源代码行数、工数、成本、质量指标统计)
    Google KML 起步教程笔记(二)高级 KML 文档与MIME 类型
    SQL Server 2008 中的空间数据存储
    PowerCmd 很好用的命令行工具,也许大家早就知道。
    Google Earth 本地地图缓存文件路径和KML文件路径
  • 原文地址:https://www.cnblogs.com/pengdonglin137/p/3239525.html
Copyright © 2011-2022 走看看