零基础C语言:第十二讲(链接属性、4种不同类型的作用域、定义和声明)

252 阅读4分钟

「这是我参与2022首次更文挑战的第12天,活动详情查看:2022首次更文挑战

  • 当变量被定义在程序的不同位置时,他的作用范围是不一样的,这个作用范围就是作用域。

4种不同类型的作用域

  • C语言编译器可以确认4种不同类型的作用域:

    • 代码块作用域

      • 代码块就是位于花括号之间的语句:如函数体、函数体内的复合语句
      • 在代码块中定义的变量,具有代码块作用域。作用范围是从变量定义的位置开始,到标志该代码块结束的右大括号‘}’结束
      • 尽管函数的形式参数不在大括号内定义,但其同样具有代码块作用域,隶属于包含函数体的代码块。
      • 举例
      • 结果
    • 文件作用域

      • 任何在代码块之外声明的标识符都具有文件作用域,作用范围是从它们的声明位置开始,到文件的结尾处都是可以访问的。
      • 另外,函数名也具有文件作用域,因为函数名本身也是在代码块之外。
      • 举例
      • 结果
    • 原型作用域

      • 原型作用域只适用于那些在函数原型中声明的参数名。函数声明时可以不写参数的名字(但参数类型是必须要写上的),其实函数原型的参数名还可以随便写一个名字,不必与形式参数相匹配(当然,这样做没有任何意义)。
      • 举例
    • 函数作用域

      • 函数作用域只适用于goto语句的标签,作用将goto语句的标签限制在同一个函数内部,以及防治出现重名标签。

定义和声明

  • 定义和声明

    • 当一个变量被定义的时候,编译器为变量申请内存空间并填充一些值。(即申请一个具体的坑存放数据)
    • 当一个变量被声明的时候,编译器就知道该变量被定义在其他地方。(声明是告诉编译器这个变量定义过,找不到不要报错,接着往下找)
    • 声明是通知编译器该变量名及相关的类型已存在,不需要再为此申请内存空间。
    • 局部变量即是定义又是声明。
    • 定义只能来一次,否则就叫做重复定义某个同名变量;而声明可以有很多次。

链接属性

  • 链接属性

    • 编译:将源代码生成机器代码(目标文件),后缀由c变为o
    • 链接:将目标文件以及相关的库文件(如使用stdio.h中的printf函数,后缀lib)进行合并链接得到可执行程序,后缀exe
    • external:多个文件中声明的通名标识符表示用一个实体
    • internal:单个文件中声明的同名标识符表示同一个实体
    • none:声明的同名标识符被当作独立而不同的实体
    • 只有具备文件作用域的标识符才能拥有external或internal的链接属性,其他作用域的标识符都是none属性。(即函数名和全局变量才具有)
    • 默认情况下,具有文件作用域的标识符拥有external属性。也就是说该标识符允许跨文件访问。对于external属性的标识符,无论在不同文件中声明多少次,表示的都是同一个实体。
    • 举例(创建一个项目)

      • 项目构造
      • a.c、b.c和c.c(使用了extern关键字)
      • main.c
    • 结果
    • 使用static关键字可以使得原先拥有external属性的标识符变为internal属性。这里有两点需要注意:

      • 使用static关键字修改链接属性,只对具体文件作用域的标识符生效(对于拥有其他作用域的标识符是另一种功能)
      • 链接属性只能修改一次,也就是说一旦将标识符的链接属性变为internal,就无法变回external了。
      • 举例(在上面代码的main函数内修改count,出现报错)