天天看点

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

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

首先看代码

int global = ;
static int one_file = ;
int main()
{
    ...
}
void function1(int n)
{
    static int count = ;
    int llama = ;
    ...
}
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[]=
{
    "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 = ; //常规外部变量
extern const char* const months[]= //全局常量
{
    "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基础篇