在C语言中,对变量的存储类型说明有以下四种:

  auto          自动变量 (动态存储)

register     寄存器变量(动态存储)

extern       外部变量(静态存储)

static         静态变量(静态存储)

所谓存储类型是指变量占用内存空间的方式,也称为存储方式。

这4种类型 不允许重复定义 如: extern static int a=200;是错误的;只能指定一中存储类型;如;static int a =200;或者是 extern int a;

变量的存储方式可分为“静态存储”和“动态存储”两种。

静态存储变量:在定义时候存储单元里一直保持不变;直到程序结束。

动态存储变量:在程序执行时候;使用他的时候才分配内存单元,使用完毕后立即释放,再使用在分配。

从以上分析可知,静态存储变量是一直存在的,而动态存储变量则时而存在时而消失。

一个变量属于哪一种存储方式,并不能仅从其变量作用域(文件,函数体,代码块,函数声明)来判断,还应有明确的存储类型说明;

如:static int a=20;

变量说明的完整形式应为:【存储类型说明符】【 数据类型说明符】【 变量名,变量名....

一、从作用域看:

1)全局变量
具有全局作用域。全局变量只需在一个源文件中定义,就可以作用于所有的源文件。
当然,其他不包含全局变量的定义的源文件需要用extern关键字再次声明这个全局变量。

2)静态局部变量(只对自己函数体内有效可见)
静态局部变量具有局部作用域,它只被初始化一次,自从第一次被初始化直到程序运行结束一直存在,
它和全局变量的区别在于全局变量对所有函数都是可见的,
而静态局部变量只对定义自己的函数体始终可见。

局部变量也只有局部作用域,它是自动对象(auto),它在程序运行期间不是一直存在,
而是只在函数执行期间存在,函数的一次调用执行结束后,变量被撤销,
其所占用的内存也被收回。

静态全局变量也具有全局作用域,它与全局变量的区别在于如果程序包含多个文件的话,
它作用于定义它文件里,不能作用到其他文件里,
即被static关键字修饰过的变量具有文件作用域。
这样即使两个不同的源文件都定义了相同名字的静态全局变量,它们也是不同的变量。

二、从分配空间看:
全局变量,静态局部变量,静态全局变量都在静态存储区分配空间,而局部变量在栈里分配空间。
全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式。
这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序,
当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一个源程序的其他源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其他源文件中引起错误。

(1)静态变量会放在程序的静态数据存储区(全局可见)中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。
(2)变量用static告知编译器,自己仅仅在变量的作用范围内可见。这一点是它与全局变量的区别。
从以上分析可以看出,把全局变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。因此static这个说明符在不同的地方所起的作用是不同的。应予以注意:

Tips:

A.若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块之间的耦合度。

B.若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块之间的耦合度。

C.设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题,因为他们都放在静态数据存储区,全局可见;

D.如果我们需要一个可重入的函数,那么我们一定要避免函数中使用static变量(这样的函数被称为:带“内部存储器”功能的函数)。

E.函数中必须要使用static变量情况:比如当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。

附加说明:

变量的存储类型
auto int a = 10;自动变量 系统默认都是自动变量默认不会初始化;会产生随机数
static int a=20; 默认会被初始化;并仅仅初始化一次;生命周期整个程序
extern int a; 外部变量(全局变量) 默认会被初始化;并仅仅初始化一次 生命周期整个程序
register int a; 存放在cpu寄存器当中;不能用static 修饰;并且只能是局部变量、要求性能高的时候用
如:
register int y = 10; //错误
int get(){
register int x = 10; //正确
}
函数的局部变量
{
作用域只在函数体内;//压到栈 ,使用完后会被弹出释放;
}

文件main.c

#include <stdio.h>
/*
auto 自动变量
register 寄存器变量
extern 外部变量
static 静态变量
*/
int a = 100; //全局变量 其他文件可以用extern调用
//register int x = 10; //错误
extern void get();
static int name2 = 490; //全局静态变量 其他文件无法使用
int main()
{

get(); //分配1次 栈的空间有可能不是同一个
get(); //分配1次 栈的空间有可能不是同一个
get(); //分配1次 栈的空间有可能不是同一个

return 0;
}

文件1:

#include <stdio.h>
int abc = 2; //默认auto类型 //

static int name = 8890;
//extern static int name2; //错误;不允许定义2个存储类型
void get(){
extern int a;//引用全局变量
int aa = a;
a++;
auto int b = 20;
b++;
static int c = 20;//静态局部变量
c++;
register int r =30;
r++;
name++;
abc++;
printf("a=%d b=%d c=%d r=%d name=%d abc=%d\n",aa,b,c,r,name,abc);
}

//局部变量在栈上
/* 用户空间
(栈【局部变量】、堆、数据段【全局变量(静态全局,静态局部,动态变量)】、代码段)
*/
//全局变量在数据段存储
/* 数据段包括两部分(静态存储区、动态存储区)
静态存储区

全局变量(非静态,静态的全局;静态局部变量)
静态变量(全局和局部2种静态)
data初始化区
bss未出化区

全部变量: auto int a; static int a; 函数内部的局部静态变量static int b;
静态变量就分全局和局部2种;


*/

C语言中【变量】的存储类型共有4种类型的更多相关文章

  1. C语言中变量的存储类型

    在C语言中,对变量的存储类型说明有以下四种: auto 自动变量register   寄存器变量extern 外部变量static   静态变量 自动变量和寄存器变量属于动态存储方式,外部变量和静态变 ...

  2. C语言中变量的存储方式

    变量可以分为全局变量.静态全局变量.局部变量和静态局部变量变量的声明有两种情况:1)一种是需要建立存储空间的(定义性声明).例如int a 在生命的时候就已经建立了存储空间.2)另一种是不需要建立存储 ...

  3. C/C++——C++变量的作用域与生命周期,C语言中变量的作用域和生命周期

    全局变量 作用域:全局作用域(全局变量只需在一个源文件中定义,就可以作用于所有的源文件.) 生命周期:程序运行期一直存在 引用方法:其他文件中要使用必须用extern 关键字声明要引用的全局变量. 内 ...

  4. C语言中变量和函数的作用域和链接属性

    C语言中变量和函数的作用域和链接属性 作用域 代码块作用域: 代码块指的是使用"{}"包围起来的部分. 在代码块中定义的变量,代码块之外是不能访问的. 代码块嵌套之后的变量作用域, ...

  5. C语言中变量、全局变量与变量的作用域

    什么是变量: 变量常量都是表征数据的一种形式:常量用来表示数据的值: 变量不仅可以用来表示数据的值:还可以用来存放数据:因为变量对应着一定的内存单元: 变量和常量必须先定义后使用. 变量名和常量名都是 ...

  6. C语言中变量的作用域和生命周期

    变量的类型: 1. 局部变量和全局变量 局部变量也称为内部变量. 局部变量是在函数内作定义说明的.其作用域仅限于函数内, 离开该函数后再 使用这种变量是非法的. 全局变量也称为外部变量,它是在函数外部 ...

  7. c语言中变量和函数作用域深究

    首先,函数的作用域和访问权限基本可以参考 C语言中的作用域,链接属性和存储类型 也存在例外情况,比如内联函数 static inline,使用static 修饰 inline之后外部文件也可以访问内联 ...

  8. C语言中变量名及函数名的命名规则与驼峰命名法

    一.C语言变量名的命名规则:(可以字母,数字,下划线混合使用) 1. 只能以字母或下划线开始:2. 不能以数字开始:3. 一般小写:4. 关键字不允许用(eg:int float=2//error  ...

  9. 【转载】java 中变量的存储位置

    原文链接点这里,感谢博主分享 * 寄存器:最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制. * 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出 ...

随机推荐

  1. C# vb .net实现HSL调整特效滤镜

    在.net中,如何简单快捷地实现Photoshop滤镜组中的HSL调整呢?答案是调用SharpImage!专业图像特效滤镜和合成类库.下面开始演示关键代码,您也可以在文末下载全部源码: 设置授权 第一 ...

  2. C#混音同时录制采集声卡和麦克风话筒

    在项目中,我们可能需要同时录制声卡的声音和麦克风的声音,比如直播间,在线教学.那么如何实现呢?当然是采用SharpCapture!下面开始演示关键代码,您也可以在文末下载全部源码: 设置授权 第一步: ...

  3. bat计算指定文件MD5并输出txt

    @echo off set Name1=*.ADS set Name2=GM_RSSPI* set Name3=equipment* set Name4=protocols* REM 设置输出文件名 ...

  4. webapp之登录页面当input获得焦点时,顶部版权文本被顶上去 的解决方法

    如上图,顶部版权是用绝对定位写的,被顶上去了,解决方法是判断屏幕大小,改变footer的定位方式: <script> var oHeight = $(document).height(); ...

  5. ElementUI 源码定制防坑指南

    背景 我司OA系统公文管理模块Office在线编辑使用的是金格IWebOffice中间件[PPAPI插件,通过<object>标签加载],IWebOffice在chrome中设置div盒子 ...

  6. saleae逻辑分析仪-串口

    安装软件 下载:https://www.saleae.com 连线 逻辑分析仪CHx分别连接UART的rx和tx 配置Logic 选择串口 设置波特率 还可以自定义显示方式 打开串口助手 波特率和Lo ...

  7. 用c#监控网络流量

    using System; using System.Text; using System.Net; using System.Net.Sockets; using System.Runtime.In ...

  8. Python 依赖版本控制 (requirements.txt 文件生成和使用)

    requirements.txt 最好配合虚拟空间使用, 虚拟空间的使用请参考 Python 虚拟空间的使用 - 难以想象的晴朗. requirements.txt 可以保证项目依赖包版本的确定性, ...

  9. curl-手册

    Manual -- curl usage explained Related: Man Page FAQ LATEST VERSION   You always find news about wha ...

  10. 系统调用IO和标准IO

    目录 1. 系统调用IO(无缓冲IO) 系统调用 常用系统调用IO函数 open close read write lseek ioctl 2. 标准IO(带缓冲IO) 概述 缓冲与冲洗 常用标准IO ...