首页 > 其他分享 >c语言中的链接性和作用域

c语言中的链接性和作用域

时间:2024-10-01 20:14:05浏览次数:8  
标签:case 函数 作用域 语言 全局变量 链接 定义

什么是链接性

链接性 指的是标识符(如变量、函数)在多个翻译单元(通常是多个源文件)之间共享和可见的能力。链接性决定了标识符的作用范围,即它能在多大范围内被访问或引用

链接性

  • 无链接性:标识符只能在局部作用域内使用,通常用于局部变量
  • 内部链接性:标识符只能在定义它的文件内使用,使用 static 关键字声明
  • 外部链接性:标识符可以在多个文件之间共享,默认情况下全局变量和函数具有外部链接性,使用 extern 关键字引用

什么是作用域

作用域是指一个变量或函数在程序中可以被访问的范围,可以简单理解为使用范围

链接性与作用域的关系

链接性决定了标识符在 多个翻译单元 之间的可见性,而作用域决定了标识符在 单个翻译单元 内的可见性

作用域

块作用域

块作用域是在代码块(如 {} 中)内部定义的变量,只在该块内可见

比如if语句,while语句等等,这里需要注意的是 switch-case 语句,它整个就是一个块作用域,如果重复定义一个变量会报错,示例如下

  char c;
  ...
  switch (c) { // 整个switch-case是一个块作用域
    case 'a':
      int count = 1; // 第一次定义count
      break;
    case 'b':
      int count = 2; // 第二次定义count
      break;
  }

在这个示例中,每个case都是属于同一个作用域,所以count相当于在这个作用域内定义了多次,解决方法有两种,一个是在switch-case语句的外部定义,还有一种就是给case加上一个块作用域,独立于switch-case的这个大的作用域

// 法1
  int count; // 在外部定义
  switch (c) {
    case 'a': ...
    case 'b': ...
  }

  // 法2
  switch (c) {
    case 'a': {...} // 形成单独的作用域
    case 'b': {...}
  }

函数作用域

函数作用域是指所有在函数内定义的变量(包括局部变量和静态局部变量)的可见性和生命周期仅限于该函数

简单来说,就是你在函数内定义的变量就只能在该函数内使用,外面的访问不了

还有一个是,在函数内定义的标签(如 goto 标签)具有函数作用域,这意味着标签只在定义它的函数内有效,示例如下

  #include <stdio.h>

  void func() {
      goto label; // label 只能在 func 函数内使用
      label: 
      printf("This is a label.\n");
  }

  int main() {
      func();
      printf("%s", label); // 错误:label 在这里不可见
      return 0;
  }

文件作用域

在文件顶部定义的全局变量和函数在整个文件中可见。它们在文件外不可见,除非使用 extern 关键字, 默认为 外部链接

简单来说,就是定义在函数外部的变量,能被所有函数访问

外部作用域

使用extern关键字修饰的全局变量在多个文件中可见

需要注意的是,只能有一个定义,但可以有多个声明

通过这种方式,你可以在多个源文件中共享同一个全局变量

静态作用域

使用 static 关键字修饰的全局变量或函数只在定义它的文件内可见,全局变量 加上static修饰还是全局变量,static关键字只是改变了它的链接性,将外部链接改为内部链接

在函数内部使用static修饰局部变量,则该变量只会初始化一次,它的值会被保留下来

文件作用域对比静态作用域

他们的主要区别就在于链接性上面,当你在多个源文件中定义同名的变量、函数等,会发生命名冲突,这时候可以使用static限制这些全局变量的链接性

特征 文件作用域 (File Scope) 静态作用域 (Static Scope)
可见性 在定义文件中可见,其他文件通过 extern 声明可访问 变量在其定义的块内可见,外部不可见
链接性 默认外部链接,使用 static 限制为文件内链接 静态作用域不涉及链接性
命名冲突 同名全局变量/函数在不同文件中会导致冲突 同名局部变量在同一函数内会导致冲突
解决方法 使用 static 或命名约定 使用不同名称

我的理解是,全局变量的链接性是外部链接,即在多个文件中是可见的,但这个可见性被加上了一个限制,那就是extern关键字,所有由于这种多个文件的伪可见,所以会有命名冲突(同名的函数也是),但是静态作用域是不涉及链接性的,根本没有这个问题

标签:case,函数,作用域,语言,全局变量,链接,定义
From: https://www.cnblogs.com/dylaris/p/18443142

相关文章

  • 实验1 C语言输入输出和简单程序编写
    1.实验任务1#include<stdio.h>intmain(){printf("oo\n");printf("<H><H>\n");printf("IIII\n");return0;} 2.实验任务2//从键盘上输入三个数据作为三角形边长,判断其能否构成三角形//构成三......
  • 实验1 C语言输入输出和简单程序编写
    1.实验任务1task1_1.c#include<stdio.h>intmain(){printf("o\n");printf("<H>\n");printf("II\n");printf("o\n");printf("<H>\n");printf("II\n&q......
  • python - 合理的入门编程语言
    盗版资源我就一个人独享了,分享的大部分为“开源”,不小心则为侵权。当两国战争后,谁在乎“侵权”?编程语言心法参考:http://www.yinwang.org/blog-cn/2017/07/06/master-pl英语阅读速成:http://www.yinwang.org/blog-cn/2018/11/23/grammar文档部分:教程https://docs.python.org/3......
  • Oracle-失效链接清理
    1.查看失效的连接数SELECTcount(*)FROMgv$sessionWHEREinst_id=1andstatus='INACTIVE'2.查看总连接SELECTcount(*)FROMgv$sessionWHEREinst_id=13.查看失效链接SELECTSID,SERIAL#,   MODULE,STATUS   FROMV$SESSIONS   WHERES.USERNAMEISNO......
  • 【PostgreSQL】提高篇——如何创建和使用自定义函数和存储过程,包括 PL/pgSQL 语言的使
    数据库管理中,存储过程和自定义函数是非常重要的概念,尤其是在使用PostgreSQL这样的关系数据库管理系统时。它们允许开发者将复杂的业务逻辑封装在数据库中,从而提高应用程序的性能、可维护性和安全性。使用PL/pgSQL语言编写的存储过程和函数可以实现数据处理、事务控制和复......
  • Meta:LLM语言概念推理基准Linguini
    ......
  • 二维环境下的TDOA测距定位的MATLAB代码,带中文注释(附下载链接)
    文章目录程序介绍概述代码结构代码获取四个锚节点的情况n个锚节点自适应的情况程序介绍概述本MATLAB程序实现了基于时间差到达(TDOA)技术的二维测距定位,能够处理4个或任意数量(大于3个)的锚节点。在无线定位和导航系统中,TDOA是一种常用的定位方法,通过测量信号从未知点......
  • 初识C语言
    C语言人机交互的一门语言 一刚发明计算机时人们普遍用着二进制语言也就是0和1的组合,那时的人们要编程,要翻书对应其数字0和1代表的意义,后来人们将一些常见的0和1写成助记符于是就形成了汇编语言,然而汇编语言仍然不够省事,于是人们苦思冥想,想出了编译器这一转折性的app,人们......
  • JS进阶 1——作用域、解构、箭头函数
    JS进阶1——作用域、解构、箭头函数1.作用域局部作用域分为:函数作用域和块作用域函数作用域:在函数内部声明的变量只能在函数内部被访问块作用域:被{}包裹的代码成为代码块,代码块内部声明的变量外部将有可能无法访问var声明的不会产生块作用域全局作用域:<scri......
  • C++ 语言特性04 - decltype关键字
    一:概述        decltype是C++11引入的一个关键字,用于查询表达式的类型,而不对表达式进行求值。它的主要作用是在编译时确定变量或表达式的类型,非常适合在模板编程和泛型编程中使用。二:使用场景    1.获取变量的类型intx=10;decltype(x)y=20;//......