static关键字

19 篇文章 0 订阅

static关键字

static 三大用法

  1. 静态全局变量
  2. 静态局部变量
  3. 静态函数

1. 静态全局变量

一个进程在内存中的布局如下图所示:

这里写图片描述

其中

.text 段 存储进程执行程序的二进制文件

.data 段 存储进程中已初始化的全局变量

.bss 段 存储进程中未初始化的全局变量

将一个全局变量用 static 修饰以后, 它的存储位置并没有什么不同, 还是在 .data 或者 .bss

但是这个变量现在只能在定义它的源文件内使用, 别的源文件无法访问, 即使用 extern 关键字声明了, 也不可以

举例如下:

test.h

#pragma once

#include <stdio.h>

void printStr();

test01.c

#include "test.h"

// 1. 静态全局变量
static const char* hello = "hello";

void printStr()
{
    printf("%s\n", hello);
}

test02.c

#include "test.h"

extern char* hello;

int main()
{
    printf("%s\n", hello);
    printStr();
}

此时我们执行代码
这里写图片描述

明显在 test02.c 中找不到变量 hello, 因为 hello 在 test01.c 中被 static 修饰了, 它就只能在 test01.c 中被使用

2. 静态局部变量

我们知道, 普通的局部变量存储在栈上, 每次调用函数, 局部变量在栈上的位置也不一定相同; 局部变量还可以在堆上申请内存, 但是用完要记得释放内存

局部变量被 static 修饰以后, 叫做静态局部变量, 它和普通局部变量有以下区别

  1. 存储位置

    静态局部变量存储在 .data 区, 所以, 虽然它是局部变量, 但是生命周期是整个程序 (注意: 因为静态局部变量如果没有初始化, 编译器会默认初始化它, 因此它不会存在 .bss 区)

  2. 访问权限

    仍然只能在它的作用域以内访问, 虽然生命周期是全局的, 但是访问权限还是局部的

  3. 初始化和赋值

    静态局部变量如果没有被用户初始化,则会被编译器自动赋值为0,以后每次调用静态局部变量的时候都用上次调用后的值

    每次函数调用静态局部变量的时候都修改它然后离开,下次读的时候从全局存储区读出的静态局部变量就是上次修改后的值

举例如下:

test01.c

#include "test.h"

void test()
{
    int count = 0;
    // 2. 静态局部变量
    static int s_count = 0;
    printf("count = %d, s_count = %d\n", count, s_count);
    count++;
    s_count++;
}

test02.c

#include "test.h"

int main()
{
    test();
    test();
    test();
    test();
}

结果:

这里写图片描述

我们发现, 普通局部变量, 每次调用都是 0, 而静态局部变量, 每次调用都是上次调用后的值.

注意: 由于static局部变量的这种特性,使得含静态局部变量的函数变得不可重入(即每次调用可能会产生不同的结果)

这在多线程编程时可能会有线程安全问题, 需要多加注意 !!!

3. 静态函数

有时候, 我们编写一些小的函数是为了实现另一个大的函数, 我们只想把大的那个暴露出去用, 而小的就不想暴露给外界, 这时候我们可以用 static 修饰这些小函数

因为 static 修饰的函数只在本源文件中有效

例如:

test.h

#pragma once

#include <stdio.h>

// 静态函数
static void func01();
void func02();

test01.c

#include "test.h"

// 3. 静态函数
static void func01()
{
    printf("static func01");
}

void func02()
{
    func01();
    printf("func02");
}

test02.c

#include "test.h"

int main()
{
    func01();
    func02();
}

结果:

这里写图片描述

我们发现, 即使 .h 头文件中声明了函数 func01() , 但编译时仍然会说找不到定义

我的 Makefile 也是没问题的

.PHONY:clean

main:test01.c test02.c
    gcc $^ -o $@ 

clean:
    rm -rf main

在这里, static 函数就相当于 C++ 中的 private 成员函数

static 函数可以很好地解决不同源文件中函数同名的问题,因为一个源文件中的 static 函数对于其他源文件是不可见的

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值