`

c static

阅读更多

这是转载来的,不知道原出处,还望见谅……

在C语言中,static的字面意思很容易把我们导入歧途,其实它的作用有三条。

(1)先来介绍它的第一条也是最重要的一条:隐藏。

当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。为理解这句话,我举例来说明。我们要同时编译两个源文件,一个是a.c,另一个是main.c。

下面是a.c的内容

char a = 'A'; // global variable
void msg()
{
     printf("Hello\n");
}

下面是main.c的内容

int main(void)
{    
    extern char a;    // extern variable must be declared before use
     printf("%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 storage duration),或静态范围(static extent)。虽然他的值在函数调用之间保持有效,但是其名字的可视性仍限制在其局部域内。静态局部对象在程序执行到该对象的声明处时被首次初始化。

  扩展分析:

  术语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.h

      system("PAUSE");
      return 0;
    }

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



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

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

void fun (void)
{
static s_cnt = 1;
...// 其他代码
}

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

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

void fun (void)
{
static s_cnt;
s_cnt = 1;
... //其他代码
}
这样每次进来都是s_cnt都是1..
摘抄地址:
分享到:
评论

相关推荐

    C语言static的用法

    ### C语言中的`static`关键字用法详解 在C语言编程中,`static`关键字具有非常重要的作用。本文将从不同角度对`static`在C语言中的应用进行深入解析,并结合具体的示例来帮助理解其背后的逻辑。 #### 一、`static`...

    c语言static

    "C语言static关键字详解" static关键字是C语言中一个非常重要的关键字,它的作用是多方面的。在本文中,我们将详细阐述static关键字的三个主要作用:隐藏、保持变量内容的持久和默认初始化为0。 隐藏 static...

    c语言static用法总结

    在C语言中,`static`关键字有着特殊的意义,它可以用于变量和函数,影响它们的存储方式和作用域。以下是对`static`关键字在C语言中用法的详细解释: 1. **全局静态变量** - 全局变量通常在程序的整个生命周期中都...

    c static关键字

    c static关键字

    c语言中static_用法总结

    ### C语言中Static关键字的用法总结 #### 一、引言 在C语言中,`static`关键字是一个非常重要的概念,它可以帮助开发者更好地管理内存和控制变量的作用域。本文将详细介绍`static`关键字的不同用途及其对程序行为...

    C语言中static变量使用方法

    ### C语言中static变量使用方法详解 在C语言编程中,`static`关键字扮演着一个非常重要的角色,尤其是在处理变量的存储方式、作用域以及生命周期方面。本文将深入探讨C语言中`static`变量的使用方法,包括静态局部...

    单片机C语言static属性和数码管显示程序

    static从英文上翻译是静态的意思,在C语言中static所起的作用也正是静态。对于局部变量而言,其作用域是局部的如某一子函数体,程序在每次执行时调用该子函数时,其声明的局部变量都会重新赋值。那如果我们想让程序...

    C语言中static的作用.pdf

    ### C语言中`static`的关键作用 在C语言中,`static`关键字具有重要的功能,主要体现在以下几个方面:修饰局部变量、全局变量以及函数。接下来将详细解释这些用途及其背后的原理。 #### 1. 修饰局部变量 当`...

    C例子:static关键字

    该程序是我写的博客“一起talk C栗子吧(第一百二十六回:C语言实例--static关键字)”的配套程序,共享给大家使用

    C语言static修饰函数详细解析

    在C语言中,`static` 关键字是一个非常重要的存储类修饰符,它可以用来修饰变量和函数,赋予它们特殊的属性。下面将详细解析`static`修饰函数时的含义和用法。 1. 隐藏作用(内部链接) 当`static`关键字用于修饰...

    C/C++中static,const,inline三种关键字详细总结

    一、关于staticstatic 是C++中很常用的修饰符,它被用来控制变量的存储方式和可见性,下面我将从 static 修饰符的产生原因、作用谈起,全面分析static 修饰符的实质。 static 的两大作用: 一、控制存储方式 static...

    c语言中 static 变量声明作用

    C语言中static变量声明的作用 在C语言中,static关键字有三个主要作用:隐藏、保持变量内容的持久和默认初始化为0。下面我们将详细解释每个作用。 1. 隐藏作用 static关键字的首要功能是隐藏。它可以使变量或函数...

    C语言中static用法大全

    ### C语言中static用法详解 #### 一、C程序存储空间布局 C语言程序的存储空间主要分为以下几个部分: 1. **正文段**: 包含CPU执行的机器指令部分,一个程序通常只有一个副本,这部分内容是只读的,以防止程序因...

    c语言中static用法总结.pdf

    ### C语言中`static`关键字的深入解析 #### 一、C程序的存储空间布局 在深入了解`static`关键字之前,我们首先需要了解C程序是如何组织其存储空间的。一个典型的C程序通常由以下几个部分组成: 1. **正文段**:这...

    c中static用法

    在C语言中,static关键字的使用涉及了变量、函数的作用域以及内存管理等重要的编程概念。static关键字主要有三个作用:隐藏、保持变量内容的持久以及默认初始化为0。下面分别详细解释这三条作用: 1. 隐藏作用 在...

    C语言中static详述

    在C语言中,static的字面意思很容易把我们导入歧途,其实它的作用有三条。 一、Static的功能 1、隐藏 当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。为理解这句话,我举例来说明...

    c语言中static用法总结[借鉴].pdf

    "C语言中static用法总结" 一、C语言程序存储空间布局 C语言程序由五个部分组成:正文段、初始化数据段、非初始化数据段、栈和堆。其中,正文段包含 CPU 执行的机器指令,初始化数据段包含已初始化的全局变量,非...

    c语言中static使用方法

    ### C语言中Static使用方法详解 #### 一、C程序存储空间布局 C语言程序的存储空间主要由以下几个部分组成: 1. **正文段**:这部分存储的是CPU执行的机器指令,一个程序通常只有一个副本,并且是只读的,以防止...

    c语言中static的用法详细示例分析

    static在c里面可以用来修饰变量,也可以用来修饰函数。先看用来修饰变量的时候。变量在c里面可分为存在全局数据区、栈和堆里。其实我们平时所说的堆栈是栈而不是堆,不要弄混。 代码如下:int a ;int main(){ int b ...

Global site tag (gtag.js) - Google Analytics