話說extern和static
阿新 • • 發佈:2018-07-27
自動 關於 變量覆蓋 call stdio.h c++的函數 ble 相關 定義
存儲位置:同樣存放在靜態區中。
特點:
以前對extern、static的一些東西一直模棱兩可。今天好好來梳理了一番。。
static關鍵字
被static修飾的變量或函數稱之為靜態成員、函數。
存儲位置:static修飾的變量存放在靜態區(全局區)。通常有以下特點:
- 修飾的變量只能在本源文件中訪問
- 存放在此的變量在程序結束後由os自動釋放,生存周期隨程序
- 僅能在編譯時期定義初始化一次. 以後操作都是在上次操作結果基礎上進行
- 若是未初始化的靜態變量,os將默認為其賦值為0或者空字符
靜態局部變量與靜態全局變量不同的一點:
- 雖然靜態局部變量在函數調用結束後仍然存在,但其他函數不能引用它
全局變量
定義在函數體外部的變量稱之為全局變量。
特點:
- 和上面static修飾的變量有相似的4個特點
- 造成和局部變量的名字空間汙染,和局部變量同名將被局部變量覆蓋
與靜態變量的區別:
- 全局變量可以被其他源文件(利用extern關鍵字)所訪問和修改
關於extern
作用:將被修飾變量聲明為外部變量
- 聲明的變量可以訪問其它源文件的變量(前提是這個變量的具有外部鏈接屬性)
- 同樣也可用來修飾函數聲明,以此調用其他源文件的定義的函數
- 指示C或者C++函數的調用規範
比如在C++中調用C庫函數,就需要在C++程序中用extern “C”聲明要引用的函數。這是給鏈接器用的,告訴鏈接器在鏈接的時候用C函數規範來鏈接。主要原因是C++和C程序編譯完成後在目標代碼中命名規則不同。
//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++函數,又該怎麽辦?
- 若只是簡單的調用C++的函數、重載函數時。將要調用的函數封裝即可
//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;
}
- 若想要訪問C++代碼中的類對象。 此時就需要將整個類都封裝起來,對外提供C形式接口,和C++相關方法封裝在自定義的結構中
stu.h:
#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:
//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
結果:
話說extern和static