且听风吟

Don't panic! I'm a programmer.

C程序设计语言读书笔记

| Comments

函数与程序结构

为什么要使用函数?

  • 隐藏实现细节
  • 对同一段逻辑,尽可能实现代码复用

函数之间的通信可以通过传递参数,函数返回值和外部变量进行。
关于函数返回值:
默认函数返回值为int类型 如果返回值为一个表达式,那么表达式的值在返回之前将被转换为函数的类型,这个操作可能会丢失信息,所以某些编译器会给出警告信息。

函数声明
如果函数声明中不包含参数,如

double atof();

那么编译器为了兼容老版本的C语言策划你工序,将不会对atof的参数做任何假设,并且会关闭所有的参数检查。所以,如果函数带有参数,则要声明它们;如果没有参数,则使用void进行声明。

变量类型

  • 外部变量

    C语言可以看成是一系列的外部对象构成,这些外部对象包括函数和变量。外部变量可以在全局范围内访问,与内部变量相比,它有更大的作用域和生命周期。任何函数都可以访问一个外部变量,但前提是,这个变量需要通过某种方式声明

  • 自动变量

    在函数内部声明的变量,包括函数参数称为自动变量,它们在函数每次调用时初始化,函数调用完成后自动销毁。

  • 静态变量

    用static声明外部变量和函数,可以将其声明的对象的作用域限定为被编译原文件的剩余部分,通过static声明外部对象,可以达到隐藏外部对象的目的。被static声明的函数的函数名除了对该函数声明的所在的文件可见外,其他文件无法访问。

    static也可用于声明内部变量,它同自动变量一样是局部变量,与自动变量不同的是,不管其所在的函数是否被调用,它一直存在,一直占据存储空间。

  • 寄存器变量 register声明告诉编译器,它所声明的变量在程序中使用的频率较高,暗示将这个变量放在寄存器中,从而执行速度更快,但是,编译器可以选择忽略这个声明。

    register声明只适用于自动变量以及函数的形式参数。

作用域
外部变量和函数的作用域从声明它的地方开始,到其所在的文件末尾结束。

变量的声明与定义
—> 变量的声明只是说明变量的属性和性质,并不分配存储单元;
—> 变量的定义表示要分配存储单元。
变量的声明有两种:

  1. 定义声明(defining declaration)

    在声明一个变量的时候就为这个变量分配存储空间,这构成了对这个变量的定义。

  2. 引用声明(referencing declaration)

    不会分配存储空间,只是告诉编译器要使用这个变量。
    变量只能定义一次,但是可以被声明多次。举例如下:

     int tern = 1; // 定义声明,声明tern的同时定义tern,导致内存空间的分配
     main() {
      extern int tern; // 引用声明,不会分配内存空间
      int tern = 2; // 错误,重复定义
    
      extern int var;
     }
    
     int var = 5;
    

    关键字extern表明这是一个引用声明,只做引用,不做定义。extern主要用在:

    1. 每个需要访问外部变量的函数中,都必须用extern关键字声明相应的外部变量(如上例的tern);
    2. 要在外部变量的定义之前使用该变量(如上例的var变量);
    3. 外部变量的定义在一个文件中,而在其他文件中需要通过extern声明来访问它。

函数的声明与定义
函数的声明(函数原型)与定义是分开的。函数在使用前必须要先声明,如果没有函数原型,那么在函数第一次使用的时候会被隐式声明:该函数的返回值被假定为int型,而对函数参数不做任何假设。

初始化
外部变量和静态变量默认初始化为0,自动变量和寄存器变量的初值没有定义。
外部变量和静态变量的初始化表达式必须是常量表达式,且只初始化一次。自动变量和寄存器变量的初始化表达式可以不是常量表达式,且在每次进入函数或者程序块时都要被初始化一次。

Reference: