C语言之链接属性

C  2023年8月27日 am8:08发布1年前 (2023)更新 91es.com站长
114 0 0

前言

对于C语言链接属性,比较模糊,因此今天回归一下课本上的知识,并记录一下,方便自己回顾。

正文

链接属性

链接属性用于认定不同文件的标识符(比如变量名、函数名)是否是同一个实体。

通俗地说,就是在两个不同文件中的变量、函数声明是否指向同一个实体。比如:a、b文件同时声明了变量c,链接属性就指定了这两处变量c是否是同一个c。

链接属性一共有三种:external(外部链接),internal(内部链接)和 none(无链接)。

  1. external链接属性的变量可被所有源文件所访问,只需要申明一下(比如 extern int a)

  2. internal链接属性的变量只能在其定义的源文件内访问

  3. none链接属性的变量只在其作用域开始到结束内可被访问(可以看成函数内定义的变量)

external

对于external属性的标识符,不同文件中出现的多个同名称标识符指向同一个实体。

在C语言中,用extern关键字在声明中指定以引用其他文件中定义的相同标识符。

internal

对于internal属性的标识符,仅在当前文件内该标识符指向同一个实体。

在C语言中,用static关键字在声明中指定让标识符变为该文件私有。

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

none

对于none属性的标识符,在每个声明位置都是一个新的实体。

C语言中,没有对应的关键字。

默认的链接属性

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

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

  2. static修饰的变量拥有internal链接属性;

  3. 其余标识符的默认链接属性为none;

int a;
void fun_b(){
}

上面代码中,变量a和函数fun_b默认链接属性是external。

void fun_b(){
    //局部变量,只在函数fun_b中有效
    int c;
}

上面代码中,变量c默认链接属性为none。

static

static可以链接链接属性,但是,这只对缺省链接属性为external的生命才有改变链接属性的效果。

static int a;
static void fun_b(){
    //默认链接属性为none,static修改无效
    static int c;
}

上面变量a和函数fun_b的链接属性被改变为internal。

但static修饰局部变量c,那可能达不到效果!

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

extern

extern关键字的规则更为复杂。一般而言,它的标识符(变量)指定为external链接属性,就可以表示所有源文件都可以访问这个实体。

int func(){
    //b是在别的源文件申明了
    //加上extern,也就是可以访问其他源文件的b
    extern int b; 
}

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

当一个extern关键字用于源文件中标识符(变量)的第一次声明,那该标识符具有external链接属性。但是,如果extern用于第二次或以后得声明时,并不会改变第一次声明所指定的链接属性。

static int i;//internal链接属性
int func(){
    extern int i; //此时用extern修饰,也不会改变链接属性,依旧是internal
}

例子

PS :VS环境下

1. a.h [空文件]
2. a.c
3. hello.c

a.c

# 默认是external链接属性
#等同于 extern int b = 125
int b = 125;
static int c = 999;

hello.c

#include<stdio.h>
//引入定义的头文件
#include "a.h"

int main(void){
    extern int b;
    //会提示找不到int c,因此int c在a.cpp中有static修饰
    extern int c;
    printf("b=%d\n", b);    
    printf("c=%d\n", c);

    getchar();
    return 0;
}

因为c是在a.cpp中定义为static,也就是internal链接属性,在hello.cpp中使用extern时是无法改变第一次声明的链接属性,因此上面编译是报错。

参考文章

  1. C语言链接属性

  2. C语言---链接属性

  3. C语言external-internal-none链接属性浅析

  4. C和指针

 历史上的今天

  1. 2021: Android FileObserver对文件或文件夹监听(0条评论)
  2. 2020: Android startActivity去掉自带的动画效果(0条评论)
  3. 2019: 周作人:苦雨(0条评论)
版权声明 1、 本站名称: 91易搜
2、 本站网址: 91es.com3xcn.com
3、 本站内容: 部分来源于网络,仅供学习和参考,若侵权请留言
3、 本站申明: 个人流水账日记,内容并不保证有效

暂无评论

暂无评论...

随机推荐

周国平:时光村落里的往事

一人分两种,一种人有往事,另一种人没有往事。有往事的人爱生命,对时光流逝无比痛惜,因而怀着一种特别的爱意,把自己所经历的一切珍藏在心灵的谷仓里。世上什么不是往事呢?此刻我所看到、听到、经历到的一切,无不转瞬即逝,成为往事。所以,珍惜往事的人便满怀爱怜地注视一切,注视即将被收割的麦田,正在落叶的...

C语言之链接属性

前言对于C语言的链接属性,比较模糊,因此今天回归一下课本上的知识,并记录一下,方便自己回顾。正文链接属性链接属性用于认定不同文件的标识符(比如变量名、函数名)是否是同一个实体。通俗地说,就是在两个不同文件中的变量、函数声明是否指向同一个实体。比如:a、b文件同时声明了变量c,链接属性就指...

java.lang.ClassNotFoundException

在工作中遇到Caused by: java.lang.ClassNotFoundException: Didn’t find class “XXX” on path: DexPathList[[zip file“/data/app/net.sourceforge.simcpux-2.apk”],n...

无效的UTF-8字符串引发的问题

前言最近在调试多媒体时,出现特别奇怪的问题,也就是扫描磁盘中文件时被中断了,之前都是好的。记录于此,方便自己查阅。好记性不如烂笔头正文部分异常日志如下。 signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr -------- Abort...

[NDK开发]Android JNI开发之动态注册

前言我们第一篇文章 《[NDK开发]Android JNI 开发之第一个 JNI实例》就是静态注册的。除了有静态注册,还有动态注册。静态注册静态注册:先由Java得到本地方法的声明,然后再通过JNI实现该声明方法。优点: 理解和使用方式简单, 属于傻瓜式操作, 使用相关工具按流程操作就...

gcc编译器相关介绍

前言简单记录gcc编译器相关内容正文gcc (GNU Compiler)是GNC推出的多平台编译器,可以将C语言、C++源程序编译成可以执行的文件。gcc支持后缀.c C语言源代码.h 程序所包含的头文件.i 已经预处理过的C源代码文件.s 汇编语言源代码文件.o 编译后的目标...