C 变量


变量用于在程序运行过程中保存数据。


变量使用前必须声明(declaration),也就是说明变量能保存的数据类型,同时确定了能使用该变量的运算符和函数。变量定义(definition)用于为变量分配内存。变量定义时也可以同时声明变量。

变量类型

  • 按变量作用域范围(scope)划分,变量分为局部变量(local variable)和全局变量(global variable)。
  • 按变量存储周期(storage duration)划分,变量分为动态变量(automatic variable)和静态变量(static variable)。

局部变量

局部变量(local variable)的作用域范围是函数内部。只有当函数被调用时局部变量才存在,函数退出时局部变量消失。

下面是局部动态变量的例子:

#include <stdio.h>

float getHeight() {
    // 局部变量height
    float height = 1.6f;
    return height;
}

int main(int argc, const char * argv[]) {
    float h = getHeight();
    printf("height : %f \n", h);  // 1.600000

    //float f = height; // error: use of undeclared identifier 'height'
    return 0;
}

上面例子中,float height = 1.6f;语句声明了一个局部变量height,只有getHeight函数中的语句可以访问height变量。main函数中不能访问height变量。

全局变量

全局变量(global variable)在函数外声明,程序的所有函数都可以访问全局变量。

如果使用全局变量的函数和定义全局变量的函数不在同一个.c文件中,使用全局变量的函数需要声明全局变量并在声明语句前面加上extern关键字,表示该变量在其它文件中定义。这时全局变量也称为外部变量(external variable)。外部变量必须在所有函数外定义一次并且只一次,用于为变量分配内存。

下面是全局变量的例子:

文件global.c:

float height = 1.5f;


文件use_global.c:

#include <stdio.h>

int main(int argc, const char * argv[]) {
    extern float height;
    //extern float height = 8; // error: 'extern' variable cannot have an initializer
    printf("height : %f \n", height); // 1.500000

    return 0;
}

在上面的例子中,global.c文件中定义了一个全局变量heightuse_global.c文件中使用extern float height;语句声明height变量的类型为float,使用extern关键字表示height变量在其它文件中定义。使用语句extern float height = 8;定义height变量时会报编译错误,height变量只能在所有函数外定义并只能定义一次。执行命令gcc -o global global.c use_global.c编译生成执行文件global。

动态变量

动态变量也是局部变量,见上面局部变量的例子。

静态变量

静态变量(static variable)在程序运行的过程中一直存在。

静态变量有3种使用情况:

  • 全局变量是一种静态变量,见上面全局变量的例子。
  • 在局部变量声明前加上static关键字,局部变量这时也成了静态变量。
  • 在全局变量前加上static关键字,全局变量这时成了只有文件作用域范围(file-scope)的变量,只能在定义该变量的.c文件中访问,在其它.c文件中不能访问该变量。

下面是静态局部变量的例子:

#include <stdio.h>

int counter() {
    // 局部变量count
    static int count = 0;
    count++;
    return count;
}

int main(int argc, const char * argv[]) {
    for (int i = 0; i < 5; i++)
        printf("%d ", counter()); // 1 2 3 4 5 

    return 0;
}

在上面的例子中,static int count = 0;语句定义了一个静态局部变量count,调用counter方法时,count变量只在第一次调用时初始化为0,后面的调用不重新初始化为0。


下面是文件作用域的全局变量的例子:

文件file_scope.c:

#include <stdio.h>

static float height = 2.1f;

void printHeight() {
    printf("height : %f \n", height); // 2.100000
}


文件use_file_scope.c:

#include <stdio.h>
extern void printHeight();

int main(int argc, const char * argv[]) {
    extern float height;
    //printf("height : %f \n", height); // error: linker command failed with exit code 1

    printHeight();

    return 0;
}

在上面的例子中,file_scope.c文件中使用语句static float height = 1.5f;定义了一个文件作用域的变量height。

执行命令gcc -o file_scope file_scope.c use_file_scope.c编译生成执行文件file_scope。

use_file_scope.c文件中使用语句printf("height : %f \n", height);访问height会报链接错误。