C语言中变量和函数的作用域和链接属性

作用域

  1. 代码块作用域: 代码块指的是使用“{}”包围起来的部分。

    1. 在代码块中定义的变量,代码块之外是不能访问的。
    2. 代码块嵌套之后的变量作用域,子代码块中定义的同名变量会覆盖父代码块中的同名变量。
    3.  #include <stdio.h>
      int main(){
      {
      int i=0;
      printf("%d\n",i);//0
      {
      int i=1;
      printf("%d\n",i);//1
      }
      }
      }
  2. 函数原型作用域: 函数原型作用域仅包括函数原型形式参数所在的括号。该作用于主要强调声明函数时不能使用相同名称的形式参数。

  3. 函数作用域: 函数作用域指的就是函数体的部分。K&R C的函数体不包含函数参数,所以在函数体内定义和函数参数同名变量会替代函数参数。ANSI C修改了该问题,函数参数在函数体的最外层作用域之内。

    1. 函数作用域内定义的变量,在函数之外不能进行访问。
  4. 文件作用域: 源文件所在的范围。

    1. 所有代码块之外定义的标识符就有文件作用域。(全局变量)
    2. 函数名不属于任何任何代码块,因此也具有文件作用域。

链接属性

  • 当组成一个程序的所有源文件被编译之后,所有目标文件以及那些从一个或多个函数库中引用的函数链接在一起,组成可执行文件。问题是当相同的标识符出现在不同的源文件时该怎么办?标识符的链接属性用来处理不同源文件中出现的标识符。标识符的链接属性和它的作用域有关但并不相同。
  1. none(无): 总是被当做单独个体,也就是说该标识符在不同源文件中的多次声明之间毫无关系,分属不同的实体。

    1. 代码块之内定义的变量默认具有none连接属性。通过extern修饰符可以修改为外部链接属性,这样就可以访问其他源文件中定义的外部变量了。static修饰符不能修改连接属性和作用域,只修改存储类型。
      #include <stdio.h>
      int main(){
      {
      static int i=0;
      printf("%d\n",i);//0
      }
      printf("%d\n",i);//error: ‘i’ undeclared (first use in this function)
      }
  2. internal(内部): 在同一个源文件中的所有声明指向同一实体,不同源文件指向不同实体。全局变量和函数可以通过static修饰符从外部链接属性改为内部链接属性。

  3. external(外部):在所有源文件中指向同一实体。全局变量和函数默认具有全局作用域,可以通过extern将从未显式声明链接属性的标识符修改为外部链接属性。

    1. static关键字可以将全局变量和函数修改为内部连接属性。
    2. 全局变量默认为外部链接属性:
      main.c
      #include <stdio.h>
      int i;
      int main(){return 0;};
      test.c
      #include <stdio.h>
      int i=0;
      gcc -c main.c test.c //success
      gcc -o main main.o test.o //multiple definination of "i"
      main.c修改:
      #include <stdio.h>
      extern int i;//通过使用extern将该全局变量声明为外部链接属性,使用外部定义的变量。
      int main(){return 0;}
      gcc -o main main.o test.o //success
    3. 函数通过extern关键字修饰为全局连接属性,指的是该函数可能在其他源文件中进行定义。
      main.c
      #include <stdio.h>
      extern int printHello();//仅指明该函数是在外部函数中声明定义。
      int main(){
      printHello();
      return 0;
      }
      test.c
      #include <stdio.h>
      int printHello(){
      printf("hello\n");
      return 0;
      }

C语言中变量和函数的作用域和链接属性的更多相关文章

  1. c语言中变量和函数作用域深究

    首先,函数的作用域和访问权限基本可以参考 C语言中的作用域,链接属性和存储类型 也存在例外情况,比如内联函数 static inline,使用static 修饰 inline之后外部文件也可以访问内联 ...

  2. C/C++——C++变量的作用域与生命周期,C语言中变量的作用域和生命周期

    全局变量 作用域:全局作用域(全局变量只需在一个源文件中定义,就可以作用于所有的源文件.) 生命周期:程序运行期一直存在 引用方法:其他文件中要使用必须用extern 关键字声明要引用的全局变量. 内 ...

  3. C语言中变量、全局变量与变量的作用域

    什么是变量: 变量常量都是表征数据的一种形式:常量用来表示数据的值: 变量不仅可以用来表示数据的值:还可以用来存放数据:因为变量对应着一定的内存单元: 变量和常量必须先定义后使用. 变量名和常量名都是 ...

  4. C语言中变量的存储类型

    在C语言中,对变量的存储类型说明有以下四种: auto 自动变量register   寄存器变量extern 外部变量static   静态变量 自动变量和寄存器变量属于动态存储方式,外部变量和静态变 ...

  5. C语言中的作用域、链接属性与存储属性

    C语言中的作用域.链接属性与存储属性 一.作用域(scope) 代码块作用域 表示{}之间的区域,下例所示,a可以在不同的代码块里面定义. #include<stdio.h> int ma ...

  6. C语言中返回字符串函数的四种实现方法 2015-05-17 15:00 23人阅读 评论(0) 收藏

    C语言中返回字符串函数的四种实现方法 分类: UNIX/LINUX C/C++ 2010-12-29 02:54 11954人阅读 评论(1) 收藏 举报 语言func存储 有四种方式: 1.使用堆空 ...

  7. C语言中返回字符串函数的四种实现方法

    转自C语言中返回字符串函数的四种实现方法 其实就是要返回一个有效的指针,尾部变量退出后就无效了. 有四种方式: 1.使用堆空间,返回申请的堆地址,注意释放 2.函数参数传递指针,返回该指针 3.返回函 ...

  8. C语言中文件定位函数总结

    C语言中文件定位函数主要是:fseek, ftell, fsetpos, fgetpos. 先来讲前两个函数,这是最基本的定位函数: fseek函数:能把文件指针移动到文件任何位置,其原型是:int ...

  9. 关于javascript中变量及函数的提升

    javascript中变量以及函数的提升,在我们平时的项目中其实还是挺常用的,尤其是大型项目中,不知不觉就会顺手添加一些变量,而有时候自己的不小心就会酿成一些不必要错误,趁有时间整理一下自己对于js中 ...

随机推荐

  1. Django使用xadmin集成富文本编辑器Ueditor(方法二)

    一.xadmin的安装与配置1.安装xadmin,其中第一种在python3中安装不成功,推荐第二种或者第三种 方式一:pip install xadmin 方式二:pip install git+g ...

  2. [Linux] nginx记录多种响应时间

    官网介绍$request_time – Full request time, starting when NGINX reads the first byte from the client and ...

  3. August 04th, 2019. Week 32nd, Sunday

    Making peace with what you don't have, that's what it's all about. 人生在世,不如意者十之八九,保持平常心,命里无时莫强求. Ever ...

  4. Codeforces Round #593 (Div. 2)

    传送门 A. Stones 签到. B. Alice and the List of Presents 单独考虑每个数的贡献即可. 答案为\((2^{m}-1)^n\). C. Labs 构造就类似于 ...

  5. IDEA如何打包可运行jar,外部引用jar包版

    背景: 有时候,我们会用IDEA来开发一些小工具,需要打成可运行的JAR包:或者某些项目不是WEB应用,纯粹是后台应用,发布时,也需要打成可运行的JAR包.并且,如果依赖第三方jar时,又不希望第三方 ...

  6. misc-3-1

    无后缀,用winhex发现是rar,添加后缀解压,依据是无后缀,丢到kali,是一个流量数据包 TCP追踪流在第五个数据包发现flag.rar 导出对象 选择HTTP 找到flag.rar 然后丢到你 ...

  7. flask中的endpoint、自定义转化器、与djnago中session区别、利用装饰器实现登录认证

    flask路由中的endpoint 与自定义转化器 ''' endpoint主要用于 反向解析, 例如:login函数中配的路由是/login,其中endpoint='lg' 则在其他函数,可以用 u ...

  8. 《3D_Deep_Learning_for_Robot_Perception.pdf》

    https://github.com/PrincetonVision/marvin

  9. C#位运算实际作用之操作整型某一位

    1.前言 前几天写了两篇关于c#位运算的文章 c#位运算基本概念与计算过程 C#位运算实际运用 在文中也提到了位运算的实际作用之一就是合并整型,当时引用了一个问题: C# 用两个short,一个int ...

  10. P3376 网络最大流模板(Dinic + dfs多路增广优化 + 炸点优化 + 当前弧优化)

    ### P3376 题目链接 ### 这里讲一下三种优化的实现以及正确性. 1.dfs多路增广优化 一般的Dinic算法中是这样的,bfs() 用于标记多条增广路,以至于能一次 bfs() 出多次 d ...