如何避免过多使用全局变量
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),所以不采用此方式
}
评论
金融研究 | 使用Python测量关键审计事项的「信息含量」
Tips: 公众号推送后内容只能更改一次,且只能改20字符。如果内容出问题,或者想更新内容, 只能重复推送。为了更好的阅读体验,建议阅读本文博客版, 链接地址https://textdata.cn/blog/2023-01-13-information-content-of-critical-aud
大邓和他的Python
0
词向量(更新) | 使用MD&A2001-2022语料训练Word2Vec模型
buTips: 公众号推送后内容只能更改一次,且只能改20字符。 如果内容出问题,或者想更新内容, 只能重复推送。 为了更好的阅读体验,建议阅读本文博客版, 链接地址https://textdata.cn/blog/2023-03-24-load-w2v-and-expand-your-concpe
大邓和他的Python
0
金融研究(更新) | 使用Python构建关键审计事项的「信息含量」
Tips: 公众号推送后内容只能更改一次,且只能改20字符。如果内容出问题,或者想更新内容, 只能重复推送。为了更好的阅读体验,建议阅读本文博客版, 链接地址https://textdata.cn/blog/2023-01-13-information-content-of-critical-aud
大邓和他的Python
0
偷偷告诉你如何一台电脑开多个微信!
大家好,我是轩辕。前几天在粉丝群里,有人问我是怎么在一台电脑上同时登录两个微信的?正好之前写过一篇文章,分析过原理,分享给没看过的小伙伴学习一下。手机端多开微信估计很多人都知道,像华为、小米等手机系统都对此做了支持,不过在运行Windows系统的电脑上怎么启动两个微信呢?其实很简单,你只需要写一个批
编程技术宇宙
0
测试新人,如何快速上手一个陌生的系统!
大家好,我是狂师!作为刚入行不久的测试新人,面对一个陌生的系统时,可能会感到有些手足无措。面对一个全新的系统系统,如何快速上手并展开有效的测试工作是一个重要的挑战。本文将探讨测试新人如何通过一系列步骤和策略,快速熟悉并掌握新系统的测试要点,从而提高测试效率和质量。本文旨在为测试新手提供一份指导,帮助
测试开发技术
0
光纤详解:光纤跳线如何分类,多向单模转换?
本文来自“光纤详解:光纤跳线如何分类,多向单模转换?”,光纤跳线作为光网络布线最基础的元件之一,被广泛应用于光纤链路的搭建中。如今,光纤制造商根据应用场景的不同推出众多类型的光纤跳线,如MPO/LC/SC/FC/ST光纤跳线,单工/双工光纤跳线,单模/多模光纤跳线等,它们之间各有特色,且不可替代。本
架构师技术联盟
0
如何计算数据中心的冷却需求?
今日分享 【导读】数据中心的冷却要求受多种因素影响,包括设备的热量输出、占地面积、设施设计和电气系统功率额定值等等……众所周知,环境因素会严重影响数据中心设备。过多的热量积聚会损坏服务器,可能导致其自动关闭。经常在高于可接受的温度下运行服务器会缩短其使用
数据中心运维管理
0
5000w+ 的大表如何拆?亿级别大表拆分实战复盘
前言笔者是在两年前接手公司的财务系统的开发和维护工作。在系统移交的初期,笔者和团队就发现,系统内有一张5000W+的大表。跟踪代码发现,该表是用于存储资金流水的表格,关联着众多功能点,同时也有众多的下游系统在使用这张表的数据。进一步的观察发现,这张表还在以每月600W+的数据持续增长,也就是说,不超
码农编程进阶笔记
0