变量c中static的作用

static的作用  时间:2021-02-28  阅读:()

C语言中 static的字面意思很容易把我们导入歧途其实它的作用有三条。 1先来介绍它的第一条也是最重要的一条 隐藏。

当我们同时编译多个文件时所有未加static前缀的全局变量和函数都具有全局可见性。为理解这句话我举例来说明。我们要同时编译两个源文件一个是a.c另一个是main.c。下面是a.c的内容char a = 'A' ; // global variablevoid msg()

{printf("Hello\n") ;

}

下面是main.c的内容int main(void)

{extern char a; // extern variable must be declared before useprintf("%c ", a) ;

(void)msg() ;return 0;

}

程序的运行结果是

A Hello

你可能会问为什么在a.c中定义的全局变量a和函数msg能在main.c中使用前面说过所有未加static前缀的全局变量和函数都具有全局可见性其它的源文件也能访问。此例中 a是全局变量 msg是函数并且都没有加static前缀因此对于另外的源文件main.c是可见的。

如果加了static就会对其它源文件隐藏。例如在a和msg的定义前加上static main.c就看不到它们了。利用这一特性可以在不同的文件中定义同名函数和同名变量而不必担心命名冲突。 Static可以用作函数和变量的前缀对于函数来讲 static的作用仅限于隐藏而对于变量 static还有下面两个作用。 2 static的第二个作用是保持变量内容的持久。存储在静态数据区的变量会在程序刚开始运行时就完成初始化也是唯一的一次初始化。共有两种变量存储在静态存储区全局变量和static变量只不过和全局变量比起来 static可以控制变量的可见范围说到底static还是用来隐藏的。虽然这种用法不常见但我还是举一个例子。

#include <stdio.h>int fun(void) {static int count = 10; //事实上此赋值语句从来没有执行过return count--;

}int count = 1 ;int main(void)

{printf("global\t\tlocal static\n") ;for( ; count <= 10; ++count)printf("%d\t\t%d\n", count, fun() ) ;

return 0;

}

程序的运行结果是global local static

1 10

2 9

3 8

4 7

5 6

6 5

7 4

8 3

9 2

10 1

3 static的第三个作用是默认初始化为0。其实全局变量也具备这一属性 因为全局变量也存储在静态数据区。在静态数据区 内存中所有的字节默认值都是0x00某些时候这一特点可以减少程序员的工作量。比如初始化一个稀疏矩阵我们可以一个一个地把所有元素都置0然后把不是0的几个元素赋值。如果定义成静态的就省去了一开始置0的操作。再比如要把一个字符数组当字符串来用但又觉得每次在字符数组末尾加’ \0’太麻烦。如果把字符串定义成静态的就省去了这个麻烦 因为那里本来就是’ \0’ 。不妨做个小实验验证一下。

#include <stdio.h>int a;int main(void)

{int i ;static char str[10] ;printf("integer: %d; string: (begin)%s(end)", a, str) ;return 0;

}

程序的运行结果如下integer: 0; string: (begin) (end)

最后对static的三条作用做一句话总结。首先static的最主要功能是隐藏其次因为static变量存放在静态存储区所以它具备持久性和默认值0。

另外

一、 c程序存储空间布局

C程序一直由下列部分组成

1正文段——CPU执行的机器指令部分一个程序只有一个副本只读防止程序由于意外事故而修改自身指令

2初始化数据段数据段——在程序中所有赋了初值的全局变量存放在这里。

3非初始化数据段bss段——在程序中没有初始化的全局变量 内核将此段初始化为0。

4栈——增长方向 自顶向下增长 自动变量以及每次函数调用时所需要保存的信息返回地址环境信息 。

5堆——动态存储分。

|-----------|

| |

|-----------|

|栈|

|-----------|

| | |

| |/ |

| |

| |

| /| |

| | |

|-----------|

|堆|

|-----------|

|未初始化|

|-----------|

|初始化|

|-----------|

|正文段|

|-----------|

二、 面向过程程序设计中的static

1.全局静态变量

在全局变量之前加上关键字static全局变量就被定义成为一个全局静态变量。

1 内存中的位置静态存储区静态存储区在整个程序运行期间都存在

2初始化未经初始化的全局静态变量会被程序自动初始化为0 自动对象的值是任意的除非他被显示初始化

3作用域全局静态变量在声明他的文件之外是不可见的。准确地讲从定义之处开始到文件结尾。

定义全局静态变量的好处

<1>不会被其他文件所访问修改

<2>其他文件中可以使用相同名字的变量不会发生**。

2.局部静态变量

在局部变量之前加上关键字static局部变量就被定义成为一个局部静态变量。

1 内存中的位置静态存储区

2初始化未经初始化的全局静态变量会被程序自动初始化为0 自动对象的值是任意的除非他被显示初始化

3作用域作用域仍为局部作用域 当定义它的函数或者语句块结束的时候作用域随之结束。

注 当static用来修饰局部变量的时候它就改变了局部变量的存储位置从原来的栈中存放改为静态存储区。但是局部静态变量在离开作用域之后并没有被销毁而是仍然驻留在内存当中直到程序结束只不过我们不能再对他进行访问。

当static用来修饰全局变量的时候它就改变了全局变量的作用域在声明他的文件之外是不可见的 但是没有改变它的存放位置还是在静态存储区中。

3.静态函数

在函数的返回类型前加上关键字static 函数就被定义成为静态函数。

函数的定义和声明默认情况下是extern的但静态函数只是在声明他的文件当中可见不能被其他文件所用。

定义静态函数的好处

<1>其他文件中可以定义相同名字的函数不会发生**

<2>静态函数不能被其他文件所用。

存储说明符auto register extern static对应两种存储期 自动存储期和静态存储期。auto和register对应自动存储期。具有自动存储期的变量在进入声明该变量的程序块时被建立它在该程序块活动时存在退出该程序块时撤销。

关键字extern和static用来说明具有静态存储期的变量和函数。用static声明的局

部变量具有静态存储持续期static storageduration 或静态范围staticextent 。虽然他的值在函数调用之间保持有效但是其名字的可视性仍限制在其局部域内。静态局部对象在程序执行到该对象的声明处时被首次初始化。

扩展分析:

术语static有着不寻常的历史.起初在C中引入关键字static是为了表示退出一个块后仍然存在的局部变量。随后 static C中有了第二种含义用来表示不能被其它文件访问的全局变量和函数。为了避免引入新的关键字所以仍使用static关键字来表示这第二种含义。最后

C++重用了这个关键字并赋予它与前面不同的第三种含义表示属于一个类而不是属于此类的任何特定对象的变量和函数(与Java中此关键字的含义相同) 。

C语言程序可以看成由一系列外部对象构成这些外部对象可能是变量或函数。而内部变量是指定义在函数内部的函数参数及变量。外部变量定义在函数之外因此可以在许多函数中使用。 由于C语言不允许在一个函数中定义其它函数 因此函数本身只能是“外部的” 。

由于C语言代码是以文件为单位来组织的在一个源程序所有源文件中一个外部变量或函数只能在某个文件中定义一次而其它文件可以通过extern声明来访问它定义外部变量或函数的源文件中也可以包含对该外部变量的extern声明 。

而static则可以限定变量或函数为静态存储。如果用static限定外部变量与函数则可以将该对象的作用域限定为被编译源文件的剩余部分。通过static限定外部对象可以达到隐藏外部对象的目的。因而 static限定的变量或函数不会和同一程序中其它文件中同名的相冲突。如果用static限定内部变量则该变量从程序一开始就拥有内存不会随其所在函数的调用和退出而分配和消失。

C语言中使用静态函数的好处

1. 静态函数会被自动分配在一个一直使用的存储区直到退出应用程序实例避免了调用函数时压栈出栈速度快很多。

2. 关键字“static” 译成中文就是“静态的” 所以内部函数又称静态函数。但此处“static”的含义不是指存储方式而是指对函数的作用域仅局限于本文件。 使用内部函数的好处是不同的人编写不同的函数时不用担心自己定义的函数是否会与其它文件中的函数同名 因为同名也没有关系。c语言中static的语义

1. static变量:

1) .局部a.静态局部变量在函数内定义,生存期为整个源程序但作用域与自动变量相同只能在定义该变量的函数内使用。退出该函数后 尽管该变量还继续存在但不能使用它。b.对基本类型的静态局部变量若在说明时未赋以初值则系统自动赋予0值。而对自动变量不赋初值则其值是不定的。

2) .全局

全局变量本身就是静态存储方式 静态全局变量当然也是静态存储方式。但是他们的作用域非静态全局变量的作用域是整个源程序多个源文件可以共同使用  而静态全局变量则限制了其作用域 即只在定义该变量的源文件内有效 在同一源程序的其它源文

件中不能使用它。

2. static函数也叫内部函数

只能被本文件中的函数调用而不能被同一程序其它文件中的函数调用。区别于一般的非静态函数外部函数static在c里面可以用来修饰变量也可以用来修饰函数。

先看用来修饰变量的时候。变量在c里面可分为存在全局数据区、栈和堆里。其实我们平时所说的堆栈是栈而不包含对不要弄混。int a ;main()

{int b ;int c* = (int *)malloc(sizeof(int) ) ;

}a是全局变量 b是栈变量 c是堆变量。static对全局变量的修饰可以认为是限制了只能是本文件引用此变量。有的程序是由好多.c文件构成。彼此可以互相引用变量但加入static修饰之后只能被本文件中函数引用此变量。static对栈变量的修饰可以认为栈变量的生命周期延长到程序执行结束时。一般来说栈变量的生命周期由OS管理在退栈的过程中栈变量的生命也就结束了。但加入static修饰之后变量已经不在存储在栈中而是和全局变量一起存储。 同时离开定义它的函数后不能使用但如再次调用定义它的函数时它又可继续使用 而且保存了前次被调用后留下的值。static对函数的修饰与对全局变量的修饰相似只能被本文件中的函数调用而不能被同一程序其它文件中的函数调用。static声明的变量在C语言中有两方面的特征

1) 、变量会被放在程序的全局存储区中这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。

2) 、变量用static告知编译器 自己仅仅在变量的作用范围内可见。这一点是它与全局变量的区别。

--test.h

------------------------------------------------static void test() ;

------------------------------------------------test.c

------------------------------------------------

#include "test.h"

#include <stdio.h>

#include <stdlib.h>

static void test()

{printf("test. . . . \n") ;

}

main.c

-------------------------------------------------

#include <stdio.h>

#include <stdlib.h>

#include "test.h"int main(int argc, char *argv[] )

{test() ; //如果去掉这个调用程序将可以编译相当于只申明了一个静态函数没有使用它的话不会去找它的实现

//如果不去掉它 将无法编译通过因为静态函数的生命期是本main.c文件 而在此文件中找不到test()的实现。

//如果在此要调用test() ,必须将test.c中的test()实现移到main.c or test.hsystem("PAUSE") ;return 0;

}

----------------------------------------------------------

我认为你改了之后是可以的. .

假设一个函数内定义个静态变量,并在它定义时就给了初值,如:void fun (void)

{static s_cnt = 1 ;

. . .//其他代码

}

那么是在编译的时候赋值给这个静态变量,以后每次调用都不会再让他等于1,而是继续上一次的值

但如果在定义时没有给初值(默认是0) ,但在下一句赋值,如:void fun (void)

{static s_cnt;s_cnt = 1 ;

. . . //其他代码

}

这样每次进来都是s_cnt都是1. .

王小玉网-美国洛杉矶2核4G 20元/月,香港日本CN2 2核2G/119元/季,美国300G高防/80元/月!

 活动方案:美国洛杉矶 E5 2696V2 2核4G20M带宽100G流量20元/月美国洛杉矶E5 2696V2 2核4G100M带宽1000G流量99元/季香港CN2 E5 2660V2 2核2G30M CN2500G流量119元/季日本CN2E5 2660 2核2G30M CN2 500G流量119元/季美国300G高防 真实防御E5 2696V2 2核2G30M...

妮妮云80元/月,香港站群云服务器 1核1G

妮妮云的来历妮妮云是 789 陈总 张总 三方共同投资建立的网站 本着“良心 便宜 稳定”的初衷 为小白用户避免被坑妮妮云的市场定位妮妮云主要代理市场稳定速度的云服务器产品,避免新手购买云服务器的时候众多商家不知道如何选择,妮妮云就帮你选择好了产品,无需承担购买风险,不用担心出现被跑路 被诈骗的情况。妮妮云的售后保证妮妮云退款 通过于合作商的友好协商,云服务器提供2天内全额退款,超过2天不退款 物...

cera:秋季美国便宜VPS促销,低至24/月起,多款VPS配置,自带免费Windows

介绍:819云怎么样?819云创办于2019,由一家从2017年开始从业的idc行业商家创办,主要从事云服务器,和物理机器819云—-带来了9月最新的秋季便宜vps促销活动,一共4款便宜vps,从2~32G内存,支持Windows系统,…高速建站的美国vps位于洛杉矶cera机房,服务器接入1Gbps带宽,采用魔方管理系统,适合新手玩耍!官方网站:https://www.8...

static的作用为你推荐
微信对骂群微信被踢出群本人会知道吗?google地球打不开谷歌地球现在为什么打不开了flash导航条如何添加FLASH导航条手机区号有的手机号中间的号码是地区区号,那是什么卡ps抠图技巧photoshop抠图技巧办公协同软件最好用的协同办公软件是哪个办公协同软件免费的多人协同办公软件哪些,我了解的有钉钉、企业微信,其他的还有么?分词技术怎样做好百度分词技术和长尾词优化网站优化方案网站优化方法有哪些服务器连接异常手机WIFI检查显示主服务器连接异常,怎么办
域名邮箱 上海vps 中国域名交易中心 万网域名管理 mediafire下载工具 轻量 国内php空间 中国智能物流骨干网 太原联通测速平台 共享主机 33456 上海服务器 路由跟踪 smtp服务器地址 photobucket 防cc攻击 卡巴斯基官网下载 广州服务器托管 镇江高防服务器 美国asp空间 更多