zoukankan      html  css  js  c++  java
  • static和extern

    1. 声明与定义

    声明:让变量类型与命名为编译器所知(变量);告知编译器函数签名(函数);

    定义:用于为变量分配存储空间(变量);函数主体具体的实现(函数);

    2. static

      一般局部变量是存储在栈区的,局部变量的生命周期在其所在的语句块执行结束时便结束了。但如果用static修饰局部变量,那么这个变量就不会存储在栈区而是放在静态数据区,其生命周期会一直持续到整个程序结束,该变量只在初次运行时进行初始化,且只进行一次。

    特点:

    1. 函数体内static变量的作用范围为该函数内,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;
    2. 声明为static变量为全局(C++是namespace内全局)变量;
    3. 在命名空间内的static函数只可被该命名空间的其它函数调用;
    4. 在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;
    5. 在类中的static成员函数只能访问类的static成员变量,不能访问类中非static变量,不接受this指针。

    如果是static修饰的全局变量,且实现的函数写在头文件(h)中,在其他文件也可以访问,如下:

    3. extern

    当在某个文件定义了一个全局变量,如果要在另一个文件去使用该变量,如果再次去定义,则会出现重复定义的问题,这个时候就需要使用到声明,对该变量的声明告诉编译器该变量在其他文件中已经定义,在此处要去引用它。

    4. extern C

    在解释extern C之前,先介绍函数签名;

    4.1  函数签名(function signature)

    • C函数签名:函数名
    • C++的函数签名:包含了一个函数的信息,包括函数名、参数类型、参数个数、顺序以及它所在的类和命名空间。

    由于C ++具有重载的函数名,而C没有重载,因此C ++编译器不能仅使用函数名作为要链接的唯一ID,因此它通过添加有关自变量的信息来破坏名称。假如某个函数的原型为void fun(int x, int y),该函数被C编译器编译后在符号库中的名字为_fun,而C++编译器则会产生namespace::_fun_int_int之类的名字。namespace::_fun_int_int这样的名字是包含了命名空间、函数名以及形参,C++就是靠这种机制来实现函数重载的。 不同的编译器厂商的名称修饰方法可能不同,所以不同的编译器对于同一个函数签名可能对应不同的修饰后名称。

    4.2 extern C

    extern “C”修饰的函数或者变量是按照C语言方式编译和链接的。以此来实现C和C++的混合编译。

    (1) 在C++中引用C语言中的函数和变量,在包含C语言头文件时(假设为cExample.h),需进行以下处理: 

    /* c语言头文件:cExample.h */ 
    #ifndef C_EXAMPLE_H 
    #define C_EXAMPLE_H 
    extern int add(int x, int y); 
    #endif
    
    /* c语言的实现文件:cExample.c */ 
    #include "cExample.h" 
    int add(int x, int y) 
    { 
      return x + y; 
    }
    
    /* c++实现文件,调用add:cppFile.cpp */ 
    extern "C" 
    { 
      #include "cExample.h"; 
    }
    int main() 
    { 
      add(2, 3); 
      return 0; 
    } 

    (2) C中引用C++语言中的函数或者变量时,C++的头文件需要加上extern “C”,但是C语言中不能直接引用声明了extern “C”的该头文件,应该仅在C中将C++中定义的extern “C”函数声明为extern类型。

    /* c++头文件cppExample.h */ 
    #ifndef CPP_EXAMPLE_H 
    #define CPP_EXAMPLE_H 
    extern "C" int add(int x, int y); 
    #endif
    
    /* c实现文件cFile.c */ 
    extern int add(int x, int y); 
    int main() 
    { 
      add(2, 3); 
      return 0; 
    }

    参考文献:


    若我所见不同 独守一角青空。

  • 相关阅读:
    iris中间件
    go并发设计模式 --资源生成器模式
    Navicate
    golang sftp传输文件
    升级python
    在centos上面开机自启动某个程序
    文件MD5
    python模块之logging
    python之八大排序方法
    python生成器
  • 原文地址:https://www.cnblogs.com/ZWJCNBLOG/p/11567107.html
Copyright © 2011-2022 走看看