如何避免过多使用全局变量

ACM比赛整理

共 2827字,需浏览 6分钟

 · 2022-03-09

来自:CSDN,作者:Marc Pony

链接:https://blog.csdn.net/maple_2014/article/details/109541104

1、设计函数以传递指针类型的参数

全局变量满天飞的代码:

typedef struct MotionParameters
{
 float a;
 float b;
 float c;
}MP;
MP g_MPData;

void fun0(void)
{
 g_MPData.a = 0;
}
void fun1(void)
{
 g_MPData.b = 1;
 fun0();
}
void fun2(void)
{
 g_MPData.c = 2;
 fun1();
}
void main(void)
{
 fun2();
}

设计函数以传递指针类型的参数,无需使用全局变量:

typedef struct MotionParameters
{
 float a;
 float b;
 float c;
}MP;

void fun0(MP *p)
{
 p->a = 0;
}
void fun1(MP *p)
{
 p->b = 1;
 fun0(p);
}
void fun2(MP *p)
{
 p->c = 2;
 fun1(p);
}
void main(void)
{
 MP MPData;
 fun2(&MPData);
}

2、 定义一个函数以获取/设置静态局部变量,其作用域限定于该函数,实现类似全局变量的效果,将全局变量隐藏起来

3、在一个.c文件里定义静态全局变量,其作用域限定于该文件,在该文件下定义初始化/获取/设置该静态全局变量的函数,在对应的.h文件里对初始化、获取、设置函数进行声明,实现类似全局变量的效果,将全局变量隐藏起来

方法2,3的源代码如下:

globals.h定义SET/GET宏及对初始化、获取、设置函数的声明。

#ifndef _H_GLOBALS_H
#define _H_GLOBALS_H

#define SET 1
#define GET 0
typedef struct MotionParams
{
 float a;
 float b[2];
}MP;

void initial_xxx(void);
MP *get_or_set_xxx(MP* p, int flag);

void init_motion_params(void);
MP *get_motion_params(void);
void set_motion_params(MP* p);

#endif

globals.c定义静态全局变量,定义初始化、获取、设置静态局部变量/静态全局变量的函数。

#include 
#include "globals.h"

//初始化值
void initial_xxx(void)
{
 MP MPDataTemp; //临时结构体,如果结构体较大时,可以考虑用malloc创建一个

 MPDataTemp.a = 0.0;
 MPDataTemp.b[0] = 0.0;
 MPDataTemp.b[1] = 0.0;
 get_or_set_xxx(&MPDataTemp, SET);
}

//获取或设置值
//(1)形参用结构体指针,可以有效避免分配过大的栈空间导致栈溢出(结构体有可能很大)
MP *get_or_set_xxx(MP* p, int flag)
{
 static MP s_MPData;  //静态局部变量,作用域只在本函数,存储于全局数据区,内存空间较栈空间大得多

 if (flag == SET)
 {
  memcpy(&s_MPData, p, sizeof(MP));
 }
 return &s_MPData;
}


static MP sg_MPData;//静态全局变量,作用域只在本文件

//初始化值
void init_motion_params(void)
{
 sg_MPData.a = 0.0;
 sg_MPData.b[0] = 0.0;
 sg_MPData.b[1] = 0.0;
}

//获取值
MP *get_motion_params(void)
{
 return &sg_MPData;
}

//设置值
//(1)形参用结构体指针,可以有效避免分配过大的栈空间导致栈溢出(结构体有可能很大)
void set_motion_params(MP* p)
{
 memcpy(&sg_MPData, p, sizeof(MP));
}

test.c用于测试:

  • (1)静态局部变量+init/set/get函数实现类似全局变量功能

  • (2)静态全局变量+init/set/get函数实现类似全局变量功能

#include 
#include 
#include "globals.h"

void main(void)
{
 MP MPData, MPData2, *p = NULL;

 //(1)静态局部变量+init/set/get函数实现类似全局变量功能
 initial_xxx();

 MPData.a = 1.0;
 MPData.b[0] = 2.0;
 MPData.b[1] = 3.0;
 get_or_set_xxx(&MPData, SET);

 memcpy(&MPData2, get_or_set_xxx(NULL, GET), sizeof(MP));  //将静态局部结构体拷贝
 //p = get_or_set_xxx(NULL, GET);  //指针操作可以直接修改静态局部结构体的变量,不好管理(修改静态局部结构体的变量只通过函数get_or_set_xxx),所以不采用此方式


 //(2)静态全局变量+init/set/get函数实现类似全局变量功能
 init_motion_params();

 memcpy(&MPData, get_motion_params(), sizeof(MP));  //将静态全局结构体拷贝

 MPData.a = 4.0;
 MPData.b[0] = 5.0;
 MPData.b[1] = 6.0;

 set_motion_params(&MPData);

 memcpy(&MPData2, get_motion_params(), sizeof(MP));
 // p = get_motion_params(); //指针操作可以直接修改静态全局结构体的变量,不好管理(修改静态全局结构体的变量只通过函数set_motion_params),所以不采用此方式
}


版权申明:内容来源网络,版权归原创者所有。除非无法确认,都会标明作者及出处,如有侵权,烦请告知,我们会立即删除并致歉!

浏览 19
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报