温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

C语言链接属性怎么应用

发布时间:2022-03-19 13:34:19 来源:亿速云 阅读:137 作者:小新 栏目:开发技术

小编给大家分享一下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:

    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属性除了作用域不同还有什么区别?

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

    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:

    #include <stdio.h>
    
    static int a=3;
    
    int main(void)
    {
        extern int a;
        printf("a=%d\n", a);
        return 0;
    }

    b.c:

    int a=1;

    编译后结果为:

    a=3

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

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

    以上是“C语言链接属性怎么应用”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!

    向AI问一下细节

    免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

    AI