C语言处理全局变量过多、高内聚、低耦合的一种方式

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 <memory.h>
#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 <stdlib.h>
#include <memory.h>
#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),所以不采用此方式
}
  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值