話說extern和static

之前對extern、static的一些東西一直模棱兩可。今天好好來梳理了一番。。ios

static關鍵字

被static修飾的變量或函數稱之爲靜態成員、函數。
存儲位置:static修飾的變量存放在靜態區(全局區)。一般有如下特色:函數

  • 修飾的變量只能在本源文件中訪問
  • 存放在此的變量在程序結束後由os自動釋放,生存週期隨程序
  • 僅能在編譯時期定義初始化一次. 之後操做都是在上次操做結果基礎上進行
  • 如果未初始化的靜態變量,os將默認爲其賦值爲0或者空字符

靜態局部變量與靜態全局變量不一樣的一點:this

  • 雖然靜態局部變量在函數調用結束後仍然存在,但其餘函數不能引用它

全局變量

定義在函數體外部的變量稱之爲全局變量。
存儲位置:一樣存放在靜態區中。
特色:spa

  • 和上面static修飾的變量有類似的幾個特色
  • 形成和局部變量的名字空間污染,和局部變量同名將被局部變量覆蓋

與靜態變量的區別:code

  • 全局變量能夠被其餘源文件(利用extern關鍵字)所訪問和修改

關於extern

做用:將被修飾變量聲明爲外部變量對象

  • 聲明的變量能夠訪問其它源文件的變量(前提是這個變量的具備外部連接屬性)
  • 一樣也可用來修飾函數聲明,以此調用其餘源文件的定義的函數
  • 指示C或者C++函數的調用規範
    好比在C++中調用C庫函數,就須要在C++程序中用extern 「C」聲明要引用的函數。這是給連接器用的,告訴連接器在連接的時候用C函數規範來連接。主要緣由是C++和C程序編譯完成後在目標代碼中命名規則不一樣。
    例子: C++程序調用C語言函數 f()
//f.c

#include <stdio.h>
void f(int* a )
 {   
     printf("f.c : this is test\n" );
     printf("f.c : a=%d\n", ++*a);
 }
//main.cpp

#include <iostream>
using namespace std;
extern "C" void f( int*);
int main( )
{
     int a = 10;
     f(&a);
     cout<<"now"<<a<<endl;
    return 0;
}

如果反過來讓C語言調用C++函數,又該怎麼辦?

1. 若只是簡單的調用C++的函數、重載函數時。將要調用的函數封裝便可blog

//C++ Code
#include <iostream>
using namespace std;
void f(int i)
{
    cout<<"f:i= "<<i<<endl;
}
void f(double d)
{
    cout<<"f:d= "<<d<<endl;
}
extern "C" void f_i(int i)
{
    f(i);
}
extern "C" void f_d(double d)
{
    f(d);
}
//C  Code
#include <stdio.h>
int main( )
 {
    f_i(10);
    f_d(10.111);
    return 0;
 }

2. 若想要訪問C++代碼中的類對象。 此時就須要將整個類都封裝起來,對外提供C形式接口,和C++相關方法封裝在自定義的結構中接口

stu.h:get

#ifndef __STU_H_
#define __STU_H_

typedef struct C_Stu C_Stu;
#ifdef __cplusplus
extern "C" {
#endif //__cpluscplus

    C_Stu* getInstance(void);   
    void releaseInstance( C_Stu** pp);
    void Call_Stu_func(C_Stu* p);
#ifdef __cplusplus
};
#endif //__cpluscplus
#endif //__STU_H_

C Code:io

//C Code
#include <stdio.h>
#include "stu.h"

int main( )
 {  
    C_Stu* p = getInstance();
    Call_Stu_func(p);
    releaseInstance(&p);
 }

C++ Code:

//
#include <iostream>
using namespace std;

class Stu
{   
public:
    Stu()  {cout<<"Stu()"<<endl;}

    virtual void func()
    {  cout<<"virtual func"<<endl; }

    ~Stu() { cout<<"~Stu()"<<endl; }
};

#ifdef __cplusplus
extern "C" {
#endif //__cpluscplus
    typedef struct C_Stu{
        Stu s;
    }C_Stu;
    C_Stu* getInstance(void)
    {
        return new C_Stu;
    }
    void releaseInstance(C_Stu** pp)
    {
        delete *pp;
        *pp = NULL;
    }

    void Call_Stu_func(C_Stu* p)
    {
        p->s.func();
    }
#ifdef __cplusplus
};
#endif //__cpluscplus

結果:

相關文章
相關標籤/搜索