• c语言static与extern的用法(转)


    一,static和extern:
        大工程下我们会碰到很多源文件。
                   
                   
                    文件a.c
    static int i; //只在a文件中用
    int j;    //在工程里用
    static void init()         //只在a文件中用
    {
    }
    void callme()          //在工程中用
    {
       static int sum;
    }
    上面的全局i变量和init()函数只能用在a.c文件中,全局变量sum的作用域只在callme里。变量j和函数callme()的全局限扩充到整个工程文件。所以可以在下面的b.c中用extern关键字调用。extern告诉编译器这个变量或者函数在其他文件里已经被定义了。
    文件b.c
    extern int j;     //调用a文件里的
    extern void callme();  //调用a文件里的
    int main()
    {
      ...
    }
    extern的另外用法是当C和C++混合编程时如果c++调用的是c源文件定义的函数或者变量,那么要加extern来告诉编译器用c方式命名函数:
    文件A.cpp调用a.c里面的变量i和函数callme()
    extern "C"  //在c++文件里调用c文件中的变量
    {
       int j;
       void callme();
    }
    int main()
    {
       callme();
    }
    二,static法则:
        A、若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;
        B、若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;
        C、设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题;

    auto 局部变量

         auto 变量是用堆栈(stack)方式占用储存器空间,因此,当执行此区段是,系统会立即为这个变量分配存储器空间,而程序执行完后,这个堆栈立即被系统收回.在大括号{}内声明.
         自动变量就是指在函数内部定义使用的变量。他只是允许在定义他的函数内部使用它。在函数外的其他任何地方都不能使用的变量。自动变量是局部变量,即它的区域性是在定义他的函数内部有效。当然这说明自动变量也没有链接性,因为它也不允许其他的文件访问他。由于自动变量在定义他的函数的外面的任何地方都是不可见的,所以允许我们在这个函数外的其他地方或者是其他的函数内部定义同名的变量,他们之间不会发生冲突的。因为他们都有自己的区域性,而且它没有链接性(即:不允许其他的文件访问他的)。来看看自动量的持续性。计算机在执行这个函数的时候,创建并为它分配内存,当函数执行完毕返回后,自动变量就会被销毁。这个过程是通过一个堆栈的机制来实现的。为自动变量分配内存就压栈,而函数返回时就退栈。

    static 静态变量


    一、局部静态变量
    局部变量按照存储形式可分为三种auto, static, register。
    与auto类型(普通)局部变量相比, static局部变量有三点不同:
    1. 存储空间分配不同
    auto类型分配在栈上, 属于动态存储类别, 占动态存储区空间, 函数调用结束后自动释放, 而static分配在静态存储区, 在程序整个运行期间都不释放. 两者之间的作用域(有效范围)相同, 但生存期不同.
    2. static局部变量在所处模块在初次运行时进行初始化工作, 且只操作一次。
    3. 对于局部静态变量, 如果不赋初值, 编译期会自动赋初值0或空字符, 而auto类型的初值是不确定的.
    特点: static局部变量的”记忆性”与生存期的”全局性”
    所谓”记忆性”是指在两次函数调用时, 在第二次调用进入时, 能保持第一次调用退出时的值. 

    注意事项:
    1. “记忆性”, 程序运行很重要的一点就是可重复性, 而static变量的”记忆性”破坏了这种可重复性, 造成不同时刻至运行的结果可能不同.
    2. “生存期”全局性和唯一性. 普通的local变量的存储空间分配在stack上, 因此每次调用函数时, 分配的空间都可能不一样, 而static具有全局唯一性的特点, 每次调用时, 都指向同一块内存, 这就造成一个很重要的问题 ---- 不可重入性!!!


    二、外部静态变量/函数
    在C中static有了第二种含义:用来表示不能被其它文件访问的全局变量和函数。, 但为了限制全局变量/函数的作用域, 函数或变量前加static使得函数成为静态函数。但此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件(所以又称内部函数)。注意此时, 对于外部(全局)变量, 不论是否有static限制, 它的存储区域都是在静态存储区, 生存期都是全局的. 此时的static只是起作用域限制作用, 限定作用域在本模块(文件)内部.
    使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名。


    extern 变量

    外部变量 定义在程序外部,所有的函数很程序段都可以使用.

    外部变量可能会在某一程序段被重新定义,以段内变量为参考值.

    static extern 变量

    静态外部变量和外部变量差别在于,外部变量生命可以同时给多个文件使用,而静态外部变量则只能给声明此变量的文件使用.

    register 变量

    寄存器变量,是由寄存器分配空间,访问速度比访问内存快,加快执行速度.寄存器大小有限.

    在c语言当中可以使用寄存器变量来优化程序的性能,最常见的是在一个函数体当中,将一个常用的变量声明为寄存器变量: register int ra; 如果可能的话,编译器就会为它分配一个单独的寄存器,在整个函数执行期间对这个变量的操作全都是对这个寄存器进行操作,这时候就不用频繁地去访存了,自然就提高了性能。
    不能用于全局变量。现在的情况是VC忽略用户定义的REGISTER,因此定义一个REGISTER变量与不定义一个REGISTER是一样的,编译器进行相同的优化,因为MS认为,REGISTER是系统中宝贵的资源,应该由系统统一调配,而且认为VC编译器的优化能力要大于一般的程序员。因此也有人说register关键字在PC机(x86CPU)无用,编译器按自动变量处理。
    注意: register是不能取址的。
    register   int   j;   int   *p   =   &j;是错的,因为无法对寄存器的定址。

  • 相关阅读:
    个人作业——软件工程实践总结&个人技术博客
    Vue实现表格导出Excel
    个人作业——软件测评
    结对第二次—某次疫情统计可视化的实现
    结对第一次—疫情统计可视化(原型设计)
    代码规范
    软工实践寒假作业(2/2)
    软工实践寒假作业(1/2)
    个人作业——软件工程实践总结&个人技术博客
    Android 自定义控件
  • 原文地址:https://www.cnblogs.com/zhihaowang/p/10128641.html
Copyright © 2020-2023  润新知