C语言中static关键字的含义以及用法

1. 存储类别

        在函数内部和全局变量中,static关键字用于指定静态存储类别。静态存储类别意味着该变量的内存只会分配一次,并且在程序运行期间都存在,直到程序结束。局部static变量只能在函数内部访问,静态全局变量只能在当前源文件中访问。
        在C中,有四种存储类别: auto, register, extern,static。存储类别指的是变量在内存中的存储方式。当我们在函数内部或者模块内部定义一个变量时,会使用auto关键字(默认的存储类别),这意味着该变量的值只在当前函数或块内可见,在函数结束后该变量也会被销毁。如果我们希望变量在函数调用结束后仍然可以保持其状态,那么就需要使用static关键字。使用static关键字定义的变量内存只会分配一次,并在程序运行期间一直存在,直到其值被手动更改或程序结束。

        在全局变量中,使用static关键字可以将该变量的作用域限制在当前源文件范围内。这意味着其他源文件无法访问该变量。

#include <stdio.h>

void increment(void);

int main() {
    for(int i = 0; i < 3; i++){
        increment();
    }
    return 0;
}

void increment(void) {
    static int count = 0;
    count++;
    printf("Count: %d\n",count);
}

运行上述代码会输出如下结果:

Count: 1
Count: 2
Count: 3

        这个程序定义了一个名为increment的函数。该函数中有一个静态局部变量count。每次调用increment函数,该变量会自增1并打印出其当前值。由于变量count被定义为static,因此变量的值会在每次函数调用之间保持不变。使用static关键字时需要注意,因为static变量的初始化只会发生一次,而且不保证其初始值是零。所以,除非你非常确定需要一个特殊的初始值,否则使用static变量时应该自己设定初值。

2. 作用域

        在函数内部,嵌套函数中,或者块级作用域内部定义的static变量的作用域只限于当前的作用域内。因此,它们与同名的全局变量或者局部变量不会发生冲突。static关键字也可以用于控制变量和函数的作用域。在函数内部,通过使用static关键字来定义局部静态变量或函数,这些变量只在当前函数内部可见。

        外部变量和函数的作用域通常是整个程序的生命周期,在其他模块中可以访问这些变量和函数。但是,如果我们使用static关键字在函数或者全局变量前面定义,就可以将它们的作用域限制在当前源文件内。也就是说,其他文件无法访问这些static变量或函数。

#include <stdio.h>

void printMessage();
static void innerMessage();
static int x = 10;

int main() {
    printMessage();
    innerMessage();
    printf("x from main : %d\n",x);
    return 0;
}

void printMessage() {
    printf("This is a message from printMessage.\n");
}

static void innerMessage() {
    printf("This is a message from innerMessage.\n");
}


        这个程序定义了一个名为printMessage的外部函数,以及一个名为innerMessage的内部函数。在innerMessage函数中,使用static关键字来定义一个名为x的静态变量。在main函数中,我们调用printMessage和innerMessage函数,并尝试打印静态变量x的值。

        由于innerMessage函数是由static关键字定义的内部函数,因此在其他源文件中无法访问它。同样,静态变量x的作用域也被限制在当前源文件内,因此在main函数中可以访问该变量,但在其他源文件中无法访问。

3. 函数的属性

        在函数的声明或者定义中使用static关键字,可以将该函数限制在当前源文件内可见,也被称为内部函数。在函数声明或定义中,使用static关键字修饰函数,可以将该函数定义为内部函数。这意味着外部程序无法使用该函数,得在模块内部才能访问,函数也不会被暴露在头文件中。定义一个内部函数避免了名称冲突,因为该函数名对外部程序是不可见的,不会与其他模块中的同名函数冲突。

#include <stdio.h>

static void messageFromStaticFunction() {
    printf("This is a message from static function.\n");
}

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

        这个程序定义了一个名为messageFromStaticFunction的内部函数,并在main函数中调用该函数。使用static关键字在函数声明或者定义中限制了内部函数messageFromStaticFunction的可见性,外部程序无法访问该函数。

4. 结构体成员

        在结构体中定义成员变量时,使用static关键字可以将该成员变量与整个结构体数据共享,而不是各自独立赋值。在结构体定义中,可以使用static关键字来定义一个静态成员变量。静态成员变量与结构体共享内存,而不是由每个实例分配独立内存。这个类似于在类中定义静态成员变量。静态成员变量是结构体的开销,所以使用它们需要权衡好内存和性能,适用于在整个生命周期内被多次访问的数据。

#include <stdio.h>

typedef struct {
    int len;
    static char name[10];
} Person;

int main() {
    Person p1, p2;
    p1.len = 10;
    p2.len = 5;
    printf("Length of p1: %d \n", p1.len);
    printf("Length of p2: %d \n", p2.len);
    p1.name[0] = 'A';
    p2.name[0] = 'B';
    printf("Name of p1: %c \n", p1.name[0]);
    printf("Name of p2: %c \n", p2.name[0]);
    return 0;
}

        这个程序定义了一个Person结构体,包括一个成员变量len和一个静态成员变量name。由于name是一个静态成员,因此结构体内的每个实例都共享相同的内存空间,该变量不需要手动初始化,可以直接访问。如果不把static关键字放在name之前,那么每个实例都需要一个独立的name数组,造成内存浪费,并且容易出现溢出

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不懂c语言的小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值