c語言中如何避免過多使用全局變量
關(guān)注、星標(biāo)公眾號(hào),直達(dá)精彩內(nèi)容
文章來源:技術(shù)讓夢(mèng)想更偉大
整理:李肖遙
1、設(shè)計(jì)函數(shù)以傳遞指針類型的參數(shù)
全局變量滿天飛的代碼:
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();
}
設(shè)計(jì)函數(shù)以傳遞指針類型的參數(shù),無需使用全局變量:
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、 定義一個(gè)函數(shù)以獲取/設(shè)置靜態(tài)局部變量,其作用域限定于該函數(shù),實(shí)現(xiàn)類似全局變量的效果,將全局變量隱藏起來
3、在一個(gè).c文件里定義靜態(tài)全局變量,其作用域限定于該文件,在該文件下定義初始化/獲取/設(shè)置該靜態(tài)全局變量的函數(shù),在對(duì)應(yīng)的.h文件里對(duì)初始化、獲取、設(shè)置函數(shù)進(jìn)行聲明,實(shí)現(xiàn)類似全局變量的效果,將全局變量隱藏起來
方法2,3的源代碼如下:
globals.h定義SET/GET宏及對(duì)初始化、獲取、設(shè)置函數(shù)的聲明。
#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定義靜態(tài)全局變量,定義初始化、獲取、設(shè)置靜態(tài)局部變量/靜態(tài)全局變量的函數(shù)。
#include?
#include?"globals.h"
//初始化值
void?initial_xxx(void)
{
?MP?MPDataTemp;?//臨時(shí)結(jié)構(gòu)體,如果結(jié)構(gòu)體較大時(shí),可以考慮用malloc創(chuàng)建一個(gè)
?MPDataTemp.a?=?0.0;
?MPDataTemp.b[0]?=?0.0;
?MPDataTemp.b[1]?=?0.0;
?get_or_set_xxx(&MPDataTemp,?SET);
}
//獲取或設(shè)置值
//(1)形參用結(jié)構(gòu)體指針,可以有效避免分配過大的棧空間導(dǎo)致棧溢出(結(jié)構(gòu)體有可能很大)
MP?*get_or_set_xxx(MP*?p,?int?flag)
{
?static?MP?s_MPData;??//靜態(tài)局部變量,作用域只在本函數(shù),存儲(chǔ)于全局?jǐn)?shù)據(jù)區(qū),內(nèi)存空間較棧空間大得多
?if?(flag?==?SET)
?{
??memcpy(&s_MPData,?p,?sizeof(MP));
?}
?return?&s_MPData;
}
static?MP?sg_MPData;//靜態(tài)全局變量,作用域只在本文件
//初始化值
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;
}
//設(shè)置值
//(1)形參用結(jié)構(gòu)體指針,可以有效避免分配過大的棧空間導(dǎo)致棧溢出(結(jié)構(gòu)體有可能很大)
void?set_motion_params(MP*?p)
{
?memcpy(&sg_MPData,?p,?sizeof(MP));
}
test.c用于測(cè)試:
(1)靜態(tài)局部變量+init/set/get函數(shù)實(shí)現(xiàn)類似全局變量功能
(2)靜態(tài)全局變量+init/set/get函數(shù)實(shí)現(xiàn)類似全局變量功能
#include?
#include?
#include?"globals.h"
void?main(void)
{
?MP?MPData,?MPData2,?*p?=?NULL;
?//(1)靜態(tài)局部變量+init/set/get函數(shù)實(shí)現(xiàn)類似全局變量功能
?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));??//將靜態(tài)局部結(jié)構(gòu)體拷貝
?//p?=?get_or_set_xxx(NULL,?GET);??//指針操作可以直接修改靜態(tài)局部結(jié)構(gòu)體的變量,不好管理(修改靜態(tài)局部結(jié)構(gòu)體的變量只通過函數(shù)get_or_set_xxx),所以不采用此方式
?//(2)靜態(tài)全局變量+init/set/get函數(shù)實(shí)現(xiàn)類似全局變量功能
?init_motion_params();
?memcpy(&MPData,?get_motion_params(),?sizeof(MP));??//將靜態(tài)全局結(jié)構(gòu)體拷貝
?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();?//指針操作可以直接修改靜態(tài)全局結(jié)構(gòu)體的變量,不好管理(修改靜態(tài)全局結(jié)構(gòu)體的變量只通過函數(shù)set_motion_params),所以不采用此方式
}
來源:https://blog.csdn.net/maple_2014/article/details/109541104
???????????????? ?END ?????????????????
關(guān)注我的微信公眾號(hào),回復(fù)“加群”按規(guī)則加入技術(shù)交流群。
點(diǎn)擊“閱讀原文”查看更多分享,歡迎點(diǎn)分享、收藏、點(diǎn)贊、在看。
評(píng)論
圖片
表情
