c——static extern

2016-12-01 10:22:05来源:http://blog.csdn.net/mardax/article/details/51477085作者:mardax人点击

第七城市

概述


static:翻译为“静态的”是static让人混淆的主要原因,static使用在不同的地方有不同的用处和含义,因此static没有准确的中文对应术语,直接使用英文static更适宜extern:翻译为“外部的”或“外部链接”

修饰外部对象


static修饰外部对象应该翻译为“内部的”,与extern的“外部的”相对应
static修饰外部对象时,外部对象作用域仅限于当前所在文件,不可被其他文件引用或链接,所以其他文件中可继续使用同名static外部名字extern修饰外部对象时,外部对象作用域贯穿整个程序,可被当前文件以外其他文件引用或链接,所以其他文件中不可使用同名extern外部名字

static


static int g_static_food1;  //static外部对象定义并默认初始化
static int g_static_food2 = 5; //static外部对象定义并显式初始化

结论:
static外部对象只有定义,没有声明static外部对象作用域仅限于当前文件,不可被其他文件引用或者链接,所以其他文件中可重复使用g_static_food1或g_static_food2外部名字,它们表示不同名字static外部对象可以显示初始化和默认初始化,默认初始化为0

extern


int g_food1;  //外部对象定义并默认初始化
int g_food2 = 5; //外部对象定义并显式初始化
extern int g_food3; //外部对象声明
extern int g_food4 = 8; //外部对象定义并显式初始化

结论:
声明外部对象必须显式使用extern,初始化发生在定义中,所以带初始化式的外部对象为定义(不管是否使用extern)extern外部对象作用域贯穿于整个程序,可以被其他文件引用或者链接,所以其他文件中不可重复使用g_food1或g_food2或g_food4外部名字,它们表示同一名字,否则会报“重复定义”错误extern外部对象可以显示初始化和默认初始化,默认初始化为0

修饰外部函数


static修饰外部函数应该翻译为“内部的”,与extern的“外部的”相对应
static修饰外部函数时,外部函数作用域仅限于当前所在文件,不可被其他文件引用或链接,所以其他文件中可继续使用同名static外部名字extern修饰外部函数时,外部函数作用域贯穿整个程序,可被当前文件以外其他文件引用或链接,所以其他文件中不可使用同名extern外部名字

static


//static函数声明
static void staticEat2();
static void staticEat2();
//static函数定义
static void staticEat1()
{
cout << "static void staticEat1()" << endl;
staticEat2();
}
//static函数定义
static void staticEat2()
{
cout << "static void staticEat2()" << endl;
}

结论:
static修饰函数声明和定义时,如果同时包含声明和定义,声明必须显式static,定义optional static,如果只包含定义,定义必须显式staticstatic函数作用域仅限于当前所在文件,不可被其他文件引用或者链接,所以其他文件中可以重复使用staticEat1或staticEat2名字,它们表示不同名字,所以对于static函数,使用头文件和实现文件实现函数声明和函数实现分离没有意义,因为static函数声明只会在当前文件链接函数实现,不会去其他文件链接函数实现static函数作为内部函数,只供当前文件调用,不使用声明和定义的分离设计,当前文件中直接提供函数定义,static函数声明可作为static函数在当前文件的前置声明使用

extern


//extern函数声明
void externEat2();
extern void externEat2();
//extern函数定义
extern void externEat1()
{
cout << "extern void externEat1()" << endl;
externEat2();
}
//extern函数定义
void externEat2()
{
cout << "extern void externEat2()" << endl;
}

结论:
extern修饰函数声明和定义都可以省略extern,不像extern修饰外部对象(外部对象含默认初始化,无法简单通过是否含有初始化式区分声明和定义),外部函数可以简单的通过是否包含函数体区分声明和定义,所以函数的声明和定义默认都是externextern函数作用域贯穿整个程序,可以被其他文件引用或者链接,所以其他文件中不可重复使用externEat1或externEat2名字,它们表示同一名字,所以对于extern函数,经常使用头文件和实现文件实现函数声明和函数实现分离,使用时候只需包含相关头文件即可,extern函数会去整个程序链接,包含相关lib库
注:名字遵循先声明后使用原则,该原则适用于所有名字

修饰局部对象


static修饰局部对象应该翻译为“静态的”,extern意为“外部的”或“外部链接”,自然不可修饰局部对象
//static局部对象
void staticTest()
{
static int staticFood1;
static int staticFood2 = 5;
}

结论:
static改变局部对象的存储区域,不改变局部对象的作用域,static修饰的局部对象存储于静态数据区,没有static修饰的局部对象存储于栈空间static局部对象的初始化发生于程序启动后,早于main函数,static局部对象默认初始化为0
第七城市

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台