服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C语言链接属性的实践应用

C语言链接属性的实践应用

2022-10-25 13:46p0ise C/C++

C语言中链接属性决定如何处理在不同文件中出现的标示符,下面这篇文章主要给大家介绍了关于C语言链接属性的实践应用,文中通过示例代码介绍的非常详细,需要的朋友可以参考下

什么是链接属性

链接属性与C语言中各个目标文件及函数的链接过程有关,用于认定不同文件的标识符(即程序中定义的各种名称,包括变量名、函数名)是否是同一个实体。更通俗地说,就是在两个不同文件中的变量、函数声明是否指向同一个实体。比如:a、b文件同时声明了变量c,链接属性就指定了这两处变量c是否是同一个c。

简单来说,链接属性的作用就是让你能在a文件中决定要不要访问b文件中的变量、函数。

链接属性的分类

链接属性有三种:

  • external - 外部链接
  • internal - 内部链接
  • none - 无链接

对于external属性的标识符,不同文件中出现的多个同名称标识符指向同一个实体。在C语言中,用extern关键字在声明中指定以引用其他文件中定义的相同标识符

对于internal属性的标识符,仅在当前文件内该标识符指向同一个实体。在C语言中,用static关键字在声明中指定让标识符变为该文件私有(只有对原本缺省的链接属性为external的标识符,才能用static关键字改变其链接属性为internal)。

对于none属性的标识符,在每个声明位置都是一个新的实体。C语言中,没有对应的关键字。

默认的链接属性

标识符的默认的链接属性与其出现的位置有关。

  • 程序的全局变量、所有函数默认的链接属性为external。

  • 其余标识符的默认链接属性为none。

在以下例子中,b、c、f的链接属性就是external:

?
1
2
3
4
5
6
7
typedef char *a;
int b;
int c(int d)
{
    int e;
    int f(int g);
}

实践应用

extern

在a文件中想要使用b文件中定义的external属性标识符,可使用extern关键字在a文件中声明。

即使该标识符所在位置默认链接属性为external,也建议使用extern关键字显式说明,有利于增加程序可读性。

static

在a文件定义了一个全局标识符,但不想被其他文件访问,可以对该标识符加上static关键字。

在a、b文件中定义了同样的标识符,通过static关键字可以避免多重定义问题。

再次提醒:只有对原本缺省的链接属性为external的标识符,才能用static关键字改变其链接属性为internal

一些细节

  • 对于external属性的标识符,你可以在多个不同源文件中声明,但是你只能在一处初始化。否则就会出现重复定义的问题:multiple definition of 'a';
  • extern关键字声明的标识符用于访问其他文件中定义的同名的标识符,因此无法进行初始化。如果你对extern声明的变量进行初始化就会生成警告:warning: ‘a’ initialized and declared ‘extern’
  • 如果在其他文件中不存在相应的标识符定义,却在当前文件中使用了extern声明,会报错:undefined reference to 'a',原理同2。
  • external属性的标识符总是静态存储类型。
  • static关键字还有改变存储类型的作用,因此,其作用与上下文环境有关,只有对于默认链接属性为external的标识符,才有改变链接属性的作用。
  • C++中,const变量隐含的具有internal属性,C中并不具有这一性质。

思考题

internal和none属性除了作用域不同还有什么区别?

以下代码一定程度上阐释了部分区别:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
static int i; // definition
              // static storage
              // internal linkage
 
void f(void)
{
    extern int i; // declaration
                  // refers to the static i at file scope
                  // note that even though the specifier is extern
                  // its linkage is intern (this is legal in both C/C++)
    {
        int i; // definition
               // automatic storage
               // no linkage
    }
}

实际上链接属性和作用域是两个概念。之所以产生以上问题,因为internal属性标识符出现的位置都是在文件作用域,而none往往在代码块作用域。此处想引起读者对内链接更深入的思考,见问题2。

文件作用域已经能让程序访问同一文件变量,那么再进行内部链接的意义在哪?

同一个标识符在链接中只能存在一个,那么通过内部链接的方式可以隔绝同名外部链接,且限定了外部编译单元不能访问该文件全局标识符。

a.c:

?
1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
 
static int a=3;
 
int main(void)
{
    extern int a;
    printf("a=%d\n", a);
    return 0;
}

b.c:

?
1
int a=1;

编译后结果为:

?
1
a=3

以上仅为不完善的个人猜想,抛开隔绝外部链接这一点不谈,就内部链接这一名称而言,笔者对为什么要在同一个文件内部使用链接的设计仍然存疑,但目前该话题的答案超出了笔者的理解,因此更深入的讨论暂时留白。

拓展:感兴趣的同学可以尝试学习链接相关知识,或许会找到更确定的答案。

参考

总结 

到此这篇关于C语言链接属性的文章就介绍到这了,更多相关C语言链接属性内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://www.cnblogs.com/p0ise/p/c-language-linkage.html

延伸 · 阅读

精彩推荐
  • C/C++C++ 中重载和运算符重载加号实现矩阵相加实例代码

    C++ 中重载和运算符重载加号实现矩阵相加实例代码

    这篇文章主要介绍了C++ 中重载和运算符重载加号实现矩阵相加实例代码的相关资料,需要的朋友可以参考下...

    Limerence4892021-05-05
  • C/C++c++实现扫雷小游戏代码分享

    c++实现扫雷小游戏代码分享

    这篇文章主要介绍了c++实现扫雷小游戏并附上代码分享,代码不能够实现当所查坐标周围雷的数量为0时,直接展开周围坐标,但有一点的知识性参考价值,...

    LazyEveryday7062022-09-28
  • C/C++C++中运算符重载的规则语法实例

    C++中运算符重载的规则语法实例

    今天小编就为大家分享一篇关于C++中运算符重载的规则语法实例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小...

    Struggler097742021-07-12
  • C/C++判断一个无向图是否为连通图的方法

    判断一个无向图是否为连通图的方法

    今天小编就为大家分享一篇关于判断一个无向图是否为连通图的方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟...

    baiduoWang7582021-07-24
  • C/C++C++结构体作为函数参数传参的实例代码

    C++结构体作为函数参数传参的实例代码

    这篇文章主要介绍了C++结构体作为函数参数传参的实例代码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参...

    ywl4708120878242021-10-08
  • C/C++基础C语言编程时易犯错误有哪些

    基础C语言编程时易犯错误有哪些

    基础C语言编程时易犯错误有哪些?这篇文章主要介绍了C语言编程时常见的错误,感兴趣的小伙伴们可以参考一下...

    leng5283722021-04-20
  • C/C++C++双向循环列表用法实例

    C++双向循环列表用法实例

    这篇文章主要介绍了C++双向循环列表,实例分析了C++双向循环列表的创建、输出、添加、删除、移动的相关操作技巧,具有一定参考借鉴价值,需要的朋友可以...

    G05619432021-03-02
  • C/C++C++线程之thread详解

    C++线程之thread详解

    这篇文章主要为大家详细介绍了C++线程中的thread,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带...

    早睡的叶子10752022-10-24