6.1 全局变量

本文介绍了全局变量的定义、初始化、作用域以及被隐藏的情况。强调了静态本地变量的特点,即在函数退出时仍保留其值。同时讨论了函数输入输出中返回指针的安全性,建议避免使用全局变量进行函数间通信,以保证线程安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.全局变量

  • 定义在函数外面的变量
  • 全部变量有 全局的生存期和作用域
    • 它们与任何函数都无关
    • 在任何函数内部都可以使用它们

2.全局变量初始化

  • 没有做初始化的全局变量会得到0值
    • 指针会得到NULL值
  • 只能用编译时刻已知的值来初始化全局变量
  • 它们的初始化发生在main函数之前
#include<stdio.h>

int f(void);

int gAll;
// int gAll = f(); //[Error] initializer element is not constant

//int g2 = gAll;//[Error] initializer element is not constant

//const int g1 = 12;
//int g3 = g1;//[Error] initializer element is not constant

//int g4 = g5;// [Error] 'g5' undeclared here (not in a function)
//const int g5 = 5;

int main(int argc, const char *argv)
{
    printf("gAll = %d\n", gAll); // gAll = 0

    return 0;   
} 

int f(){
    gAll +=2;
}

3.被隐藏的全局变量

  • 函数内部存在 与 全局变量 同名的变量,则全局变量被隐藏
#include<stdio.h>

int f(void);

int gAll;


int main(int argc, const char *argv)
{
    printf("gAll = %d\n", gAll); // gAll = 0
    f();
    printf("after call f(), gAll = %d\n", gAll); // after call f(), gAll = 0

    return 0;   
} 

int f(){
    int gAll = 12;
    printf("f() gAll = %d\n", gAll); // f() gAll = 12
}

4.静态本地变量

  • 在本地变量定义时 加上static修饰符 就成为静态本地变量
  • 当函数离开的时候,静态本地变量会继续存在 并保持其值
  • 静态本地变量的初始化 只会在第一次进入这个函数时做,以后进入函数时 会保值上次离开的值
#include<stdio.h>

int f(void);


int main(int argc, const char *argv)
{
    f();// in f all = 1    again in f all = 3


    f();// in f all = 3    again in f all = 5

    return 0;   
} 

int f(){
    static int all = 1;
    printf("in %s all = %d\n", __func__, all);
    all +=2;
    printf("again in %s all = %d\n", __func__, all);

    return all;
}
  • 静态本地变量实际上是特殊的全局变量
  • 它们位于相同的内存区域
  • 静态本地变量 具有全局的生存期,函数内的局部作用域
#include<stdio.h>

int f(void);
int gAll = 12;


int main(int argc, const char *argv)
{
    f();
    return 0;   
} 

int f(){
    int k = 0;
    static int all = 1;

    // 从地址看,静态本地变量是 全局的 
    printf("&gAll=%p\n", &gAll);// &gAll=0000000000403010
    printf("&all=%p\n", &all); //   &all=0000000000403014
    printf("&k=%p\n", &k);//          &k=000000000022FE1C

    printf("in %s all=%d\n", __func__, all); // in f all=1
    all += 2;
    printf("after +2, in %s all=%d\n", __func__, all); // after +2, in f all=3

    return all;
}

5. 关于函数输入输出的问题

5.1 返回指针的函数

  • 返回本地变量的地址是危险的
  • 返回全局变量 或 静态本地变量的地址 是安全的
  • 返回在 函数内malloc的内存是安全的,但是容易造成问题
  • 最好的做法是 返回传入的指针
#include<stdio.h>

int* f(void);
void g(void);

int main(int argc, const char *argv)
{
    int *p = f();
    printf("*p=%d\n", *p); // *p=12

    g(); // k=24
    printf("*p=%d\n", *p); // *p=24
    return 0;
}


// 返回本地变量的地址是危险的 
int* f(void)
{
    int i = 12;
    return &i; // [Warning] function returns address of local variable [-Wreturn-local-addr]
}

void g(void)
{
    int k = 24;
    printf("k=%d\n", k);
}

5.2 tips

  • 不要使用全局变量来在函数间传递参数和结果
  • 尽量避免使用全局变量
  • 使用全局变量和静态本地变量的函数 是 线程不安全的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值