📜  C |存储类和类型限定符|问题7(1)

📅  最后修改于: 2023-12-03 15:13:46.942000             🧑  作者: Mango

C语言中存储类和类型限定符

在C语言中,存储类和类型限定符是用于描述变量和函数的属性的关键字。它们可以帮助程序员控制变量和函数在内存中的位置和生命周期,以及它们在程序中的可见性和访问权限。在本文中,我们将介绍C语言中常用的存储类和类型限定符。

存储类

C语言中有4种存储类,分别是:auto、register、static和extern。

auto存储类

auto存储类是默认的存储类,如果没有显式指定存储类,变量就会被默认定义为auto类型。auto变量的生命周期是在定义它的函数结束时结束,变量的作用域是定义它的函数块内。

#include <stdio.h>

int main()
{
    auto int a = 10;
    printf("%d\n", a); // 输出10
    return 0;
}
register存储类

register存储类和auto存储类很相似,也是用于定义局部变量的。但是,register变量会尽可能的存储在CPU寄存器中,以提高程序的执行效率。当然,这只是建议编译器这样做,并不是必须这样做。register变量的生命周期和作用域同样是在定义它的函数块内。

#include <stdio.h>

int main()
{
    register int a = 10;
    printf("%d\n", a); // 输出10
    return 0;
}
static存储类

static存储类用于定义静态变量和函数,静态变量和函数的作用域仅限于定义它们的文件内。静态变量和函数在程序开始执行时就已经初始化了,并且在程序运行期间一直存在。如果static变量没有被显式初始化,它们会被自动初始化为0。

#include <stdio.h>

void func();

int main()
{
    func();
    func();
    func();
    return 0;
}

void func()
{
    static int count = 0;
    count++;
    printf("函数调用次数: %d\n", count);
}

上面的代码中,count变量是一个静态变量,每次调用func函数,count值会自增。由于它是一个静态变量,因此在程序运行期间它的值会一直保存下来。输出结果如下:

函数调用次数: 1
函数调用次数: 2
函数调用次数: 3
extern存储类

extern存储类用于声明全局变量和函数。它告诉编译器变量或函数是在别的文件中定义的,不要为它们分配内存空间,仅仅是告诉编译器这个变量或函数已经存在。因此,它的作用是扩展变量和函数的作用域。

#include <stdio.h>

extern int a;

int main()
{
    printf("%d\n", a); // 输出10
    return 0;
}

int a = 10;

上面的代码中,定义了一个全局变量a,并在main函数中使用了extern关键字声明这个变量。当编译器遇到extern声明时,它会去寻找变量的实际定义,如果找到了,就将变量链接到该定义上。输出结果如下:

10
类型限定符

类型限定符是用于改变变量的基本类型的关键字。C语言中有两种类型限定符,分别是const和volatile。

const类型限定符

const类型限定符用于定义常量。将变量定义为const类型后,变量的值就不能被修改了。const变量通常是全局变量或者函数中的局部静态变量。

#include <stdio.h>

int main()
{
    const int a = 10;
    printf("%d\n", a); // 输出10
    // a = 20;  // 试图修改const变量的值,编译器会报错
    return 0;
}
volatile类型限定符

volatile类型限定符用于定义易变的变量,即该变量的值可能随着程序的运行而发生改变。通常,这种变量都是由硬件中断或其他线程修改的,而程序本身却没有直接控制该变量的值。为了确保程序访问该变量时能够及时获取到其最新的值,需要使用volatile类型限定符。

#include <stdio.h>

volatile int flag = 0;

void isr()
{
    flag = 1;
}

int main()
{
    printf("开始监听flag...\n");
    while (!flag);
    printf("flag被修改了!\n");
    return 0;
}

上面的代码中,flag变量是一个volatile变量。在main函数中,程序会不断地循环等待flag变量的值被修改。isr函数会在某个时刻修改flag变量的值。由于flag变量是volatile类型,因此main函数能够及时感知到变量的值被修改了。输出结果如下:

开始监听flag...
flag被修改了!
总结

在C语言中,存储类和类型限定符可以用来控制变量和函数的属性,帮助程序员实现更灵活、更高效的程序设计。程序员需要根据实际情况选择合适的存储类和类型限定符,以满足程序的需求。