【请阅】基础篇:C/C++ 作用域和链接性

【知识点1】静态变量作用域和链接性

首先看代码

int global = 1000;
static int one_file = 50;
int main()
{
    ...
}
void function1(int n)
{
    static int count = 0;
    int llama = 0;
    ...
}
void function2(int q)
{
    ...
} 

C++为静态存储持续性变量提供了3种链接性:
1)外部链接性,如变量global
2)内部链接性,如变量one_file
3)无链接性, 如变量count

三种链接性的对应作用域:
要点1:外部链接性,如变量global可以在程序的其他文件中使用它;
要点2:内部链接性,如变量one_file只能在包含上述代码的文件中使用它;
要点3:无链接性,如变量count其作用域只在function1()函数中使用,和自动变量llama一样。但和llama不同的是,即使函数function1()没有被执行,变量count也存在于内存中


【知识点2】单定义规则
  1. What?是什么
    C++有“单定义规则”(One Definition Rule,ODR),规则指出变量只能有一次定义。

  2. How?解决办法
    C++提供了两种声明办法:
    1)定义声明:它给变量分配存储空间;

    2)引用声明:它不给变量分配存储空间,因为它引用已有的变量。使用关键字extern声明但不进行初始化

    先看看代码的声明,代码如下:

double up; //这个是自动变量up,此处为声明并初始化为0(C++对静态变量的初始化自动设定为0),外部链接属性;
extern int blem; //引用声明,其他某个文件对其定义
extern char gr = 'z'; //此处为定义,因为初始化并分配了空间

【知识点3】全局变量(附const)

首先看代码:

/** 此处代码定义为全局变量 **/
const char* const months[12]=
{
    "January","February","March","April","May","June",
    "July","August","September","October","November","December"
}
  1. 全局变量months含义
    1)months代表一个常量数据,可以让多个函数使用同一个数据块;
    2)months全局变量的第一个const防止字符串被修改,第二个const确保数组中每个指针始终指向它最初指向的字符串。

  2. 问题:全局变量局部变量什么情况下该用?
    要点1:全局变量代表着所有的函数能访问全局变量,省去传递参数的麻烦;

    要点2:全局变量的易访问性质,代表可以对数据进行不必要的访问,就不能保证数据的完整性——程序不可靠

    要点3:使用局部变量意味着,在需要知晓时才传递数据,而不在各种情况下使用全局变量的数据。

  3. const修饰的全局常量months能被其他文件使用吗?
    解答:
    不能。C++认为,全局const的链接性为内部的;因此所有文件都可以使用相同的声明,但不能使用。

若要想months的链接性为外部的,则必须使用extern来覆盖默认的内部链接性。

int global = 0; //常规外部变量
extern const char* const months[12]= //全局常量
{
    "January","February","March","April","May","June",
    "July","August","September","October","November","December"
}

在这种情况下,其他文件使用该常量months必须使用extern来声明它。
注意:与常规外部变量global不同,其也具有外部链接性,但是在当前文件中不必使用extern来声明。


【知识点4】函数和语言链接性
  1. 函数链接性

    C/C++定义:一个函数内不能定义另一个函数。默认情况下,函数的链接性为外部的,可以在文件之间共享,意味着所有函数的存储持续性都自动为静态的,即在整个程序执行期间都一直存在。

    函数设定为文件只在一个文件内使用,要求在函数原型和函数定义中使用关键字static

    static int private(double x);
    ...
    static int private(double x)
    {
      ...
    }

    这意味着:该函数只在这个文件中可见,也可以在其他文件中定义同名的函数。在定义静态函数的文件中,静态函数将涵盖外部定义,因此即使在外部定义了同名的函数,该文件仍将使用静态函数。

  2. 编译器怎么找函数
    假设函数在某个文件A中调用了一个函数F,该函数F原型在该文件A中指出是静态的,则编译器将只在该文件中查找函数定义。否则,编译器将在所有的程序文件中查找。
    如果编译器找到两个定义,则编译器发出错误信息。
    假如编译器在所有的程序文件中都没找到,则将搜索库中的函数。此时意味着:如果定义了一个与库函数同名的函数,编译器将使用程序员定义的版本,而不是库函数

  3. 语言链接性
    —>存在的问题:
    举例:针对函数spiff(int)
    C编译器:将其翻译成_spiff,即C语言链接性;

    C++编译器:将其翻译成_spiff_i,将函数spiff(double,double)翻译成_spiff_d_d,即C++语言链接性;

    —>解决的办法:
    使用函数原型指出要使用的约定:

extern "C" void spiff(int);
extern void spiff(int);
extern "C++" void spiff(int);
 第一个:使用C语言链接性;
 第二个:默认使用C++语言链接性;
 第三个:显示指出使用C++语言链接性。

end
下一篇预告:new与delete基础篇

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值