const、static、extern用法

const的用法:

1、在C语言中,const修饰的变量是"常变量",在编译阶段检查常变量有没有做左值(不可以为左值),其他处理和普通变量相同。

2、在C++中,const修饰的变量为"常量",在编译阶段,把用到常量的地方替换成常量初始化的值(常量:(1)常量一定要初始化;(2)不可以做左值;(3)不能间接修改常量的值;);

3、在C++中,const修饰的成员变量也不能在类定义处初始化,只能通过构造函数初始化列表进行,并且必须有构造函数(const数据成员只在某个对象生存期内是常量,而对于整个类而言却是可变的。因为类可以创建多个对象,不同的对象其const数据成员的值可以不同。所以不能在类的声明中初始化const数据成员,因为类的对象没被创建时并且编译器不知道const数据成员的值);

4、在C++中,cosnt成员方法主要目的是防止成员函数修改对象的内容。即const成员函数不能修改成员变量的值,但可以访问成员变量。

static的用法:

修饰变量:

1、静态全局变量:在全局变量前,加上关键字static,该变量就被定义成为一个静态全局变量。                                                       特点:(1)该变量在全局数据区分配内存;(2)未经初始化的静态全局变量会被程序自动初始化为0(自动变量的值是随机的,除非它被显式初始化);(3)静态全局变量在声明它的整个文件都是可见的(golbal转变为local),而在文件之外(extern)是不可见的;(4)定义全局变量就可以实现变量在文件中的共享;(5)静态全局变量不能被其它文件所用; (6)其它文件中可以定义相同名字的变量,不会发生冲突;

2、静态局部变量: 在局部变量前,加上关键字static,该变量就被定义成为一个静态局部变量。在函数体内定义了一个变量,每当程序运行到该语句时都会给该局部变量分配栈内存。但程序结束时,系统就会收回栈内存,局部变量也相应失效。但如果想对变量的值进行保存,想法是定义一个全局变量来实现。但这样变量已经不再属于函数本身了,不再仅受函数的控制,给程序的维护带来不便。静态局部变量正好可以解决这个问题。静态局部变量保存在全局数据区,而不是保存在栈中,每次的值保持到下一次调用,直到下次赋新值。(1)该变量在全局数据区分配内存(栈到数据存储区);(2)静态局部变量在程序执行到该对象的声明处时被首次初始化,即以后的函数调用不再进行初始化;(3)静态局部变量一般在声明处初始化,如果没有显式初始化,会被程序自动初始化为0;(4)它始终驻留在全局数据区,直到程序运行结束。但其作用域为局部作用域,当定义它的函数或语句块结束时,其作用域随之结束;

3、2静态成员变量:在类内数据成员的声明前加上关键字static,该数据成员就是类内的静态数据成员。                                             特点:(1)而静态数据成员被当作是类的成员。无论这个类的对象被定义了多少个,静态数据成员在程序中也只有一份拷贝,由该类型的所有对象共享访问。(2)静态数据成员存储在全局数据区,属于本类的所有对象共享,所以,它不属于特定的类对象,在没有产生类对象时其作用域就可见,即在没有产生类的实例时,我们就可以操作它; (3)由于它不属于特定的类对象,在没有产生类对象时其作用域就可见,所以要在类外初始化(类作用域);(4)静态成员变量没有进入程序的全局名字空间,因此不存在与程序中其它全局名字冲突的可能性;(5)可以实现信息隐藏。静态数据成员可以是private成员,而全局变量不能;

修饰函数:

1、普通全局方法:静态函数,在函数的返回类型前加上static关键字,函数即被定义为静态函数。静态函数与普通函数不同,它只能在声明它的文件当中可见(golbal转变为local),不能被其它文件使用。(1)静态函数不能被其它文件所用;(1)其它文件中可以定义相同名字的函数,不会发生冲突;

2、静态成员方法:静态成员方法为类的全部服务而不是为某一个类的具体对象服务。thiscall调用约定转变为cdcall调用约定,与普通函数相比,静态成员函数由于不是与任何的对象相联系,因此它不具有this指针(不依赖对象调动)。它无法访问属于类对象的非静态数据成员,也无法访问非静态成员函数,它只能调用其余的静态成员函数。 (1)出现在类体外的函数定义不能指定关键字static;(2)静态成员之间可以相互访问,包括静态成员方法访问静态成员变量和访问静态成员方法;(3)非静态成员函数可以任意地访问静态成员函数和静态数据成员;(4)静态成员函数不能访问非静态成员函数和非静态数据成员;(5)静态成员方法在类外定义实现;

C和C++的相互调用:"extern C"

extern 基本解释:extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。通过这种行为它告诉编译器:该变量/函数的定义已经存在在某个地方了,让编译器到其他的模块去寻找它的定义。另外,extern也可用来进行链接指定。

1、C++调用C,在C++中写入extern   “C“。使用extern“C”主要是因为C++语言在编译的时候为了实现多态,会将函数名和函数结合起来形成另外一种函数名(总之就是说编译后的函数名与你之前自己声明时的函数名会不一样),而C语言中无多态的概念当然也就不会有这种奇异的名字变化问题。这是问题就出现了,当你要在C++中调用C函数时,由于名字的不同,所以它会找不到所调用的这个函数的定义,因而会出错。     为了解决这一C与C++的矛盾冲突,就有了extern "C'。

2、C调用C++:使用extern "C"则是告诉编译器依照C的方式来编译封装接口,当然接口函数里面的C++语法还是按C++方式编译。

//普通函数 
// C++ Code
extern "C" int foo( int x );
int foo( int x )
{
   //...
}
/*
这样,编译器会将foo函数编译成类似_foo符号,而不会编译成类似_foo_int符号
则C可以这样调用C++函数
*/
// C Code
int foo( int x );
void cc( int x )
{
    foo( x );
    //...
}
//**************************************************************************************
/*
如果想调用重载的C++函数,则须封装单独的接口共C调用。
*/
// C++ Code
void foo( int x );
void foo( float x );

extern "C" void foo_i( int x )
{
    foo( x );
}
extern "C" void foo_f( float x )
{
    foo( x );
}
/*
则C中可这样调用
*/
// C Code
void foo_i( int x );
void foo_f( float x );
void ccc( int x1, float x2 )
{
    foo_i( x1 );
    foo_f( x2 );
    // ...
} 
//**************************************************************************************
/*
C中想调用C++中的成员函数(包括虚函数),则需要提供一个简单的包装(wrapper)。
*/
// C++ code:
class C
{
  ...
  virtual double f(int);
};
extern "C" double call_C_f(C* p, int i) // wrapper function
{
return p->f(i);
}
/*
然后,你就可以这样调用 C::f():
*/
//C code
double call_C_f(struct C* p, int i);//声明
void ccc(struct C* p, int i)
{
   double d=call_C_f(p,i);
 ...
}

3、C(不清楚是那种编译器(C/C++)):#ifdef_cplusplus

在cpp的代码之中会看到这样的代码: 特别是C++中引入C的头文件,这些C头文件中出现很多如下代码。

#ifdef __cplusplus extern "C" { #endif
/*
一段代码
*****************************
*****************************
*****************************
*****************************
*/
#ifdef __cplusplus } #endif  

其中__cplusplus是C++编译器的保留宏定义.就是说C++编译器认为这个宏已经定义了。所以关键是extern "C" {},extern "C"是告诉C++编译器件括号里的东东是按照C的obj文件格式编译的,要连接的话按照C的命名规则去找.

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值