如何避免過多使用全局變量
來自:CSDN,作者:Marc Pony
鏈接:https://blog.csdn.net/maple_2014/article/details/109541104
1、設計函數(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ù)以傳遞指針類型的參數(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、 定義一個函數(shù)以獲取/設置靜態(tài)局部變量,其作用域限定于該函數(shù),實現(xiàn)類似全局變量的效果,將全局變量隱藏起來
3、在一個.c文件里定義靜態(tài)全局變量,其作用域限定于該文件,在該文件下定義初始化/獲取/設置該靜態(tài)全局變量的函數(shù),在對應的.h文件里對初始化、獲取、設置函數(shù)進行聲明,實現(xiàn)類似全局變量的效果,將全局變量隱藏起來
方法2,3的源代碼如下:
globals.h定義SET/GET宏及對初始化、獲取、設置函數(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)全局變量,定義初始化、獲取、設置靜態(tài)局部變量/靜態(tài)全局變量的函數(shù)。
#include?
#include?"globals.h"
//初始化值
void?initial_xxx(void)
{
?MP?MPDataTemp;?//臨時結構體,如果結構體較大時,可以考慮用malloc創(chuàng)建一個
?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;??//靜態(tài)局部變量,作用域只在本函數(shù),存儲于全局數(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;
}
//設置值
//(1)形參用結構體指針,可以有效避免分配過大的棧空間導致棧溢出(結構體有可能很大)
void?set_motion_params(MP*?p)
{
?memcpy(&sg_MPData,?p,?sizeof(MP));
}
test.c用于測試:
(1)靜態(tài)局部變量+init/set/get函數(shù)實現(xiàn)類似全局變量功能
(2)靜態(tài)全局變量+init/set/get函數(shù)實現(xiàn)類似全局變量功能
#include?
#include?
#include?"globals.h"
void?main(void)
{
?MP?MPData,?MPData2,?*p?=?NULL;
?//(1)靜態(tài)局部變量+init/set/get函數(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)局部結構體拷貝
?//p?=?get_or_set_xxx(NULL,?GET);??//指針操作可以直接修改靜態(tài)局部結構體的變量,不好管理(修改靜態(tài)局部結構體的變量只通過函數(shù)get_or_set_xxx),所以不采用此方式
?//(2)靜態(tài)全局變量+init/set/get函數(shù)實現(xiàn)類似全局變量功能
?init_motion_params();
?memcpy(&MPData,?get_motion_params(),?sizeof(MP));??//將靜態(tài)全局結構體拷貝
?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)全局結構體的變量,不好管理(修改靜態(tài)全局結構體的變量只通過函數(shù)set_motion_params),所以不采用此方式
}版權申明:內(nèi)容來源網(wǎng)絡,版權歸原創(chuàng)者所有。除非無法確認,都會標明作者及出處,如有侵權,煩請告知,我們會立即刪除并致歉!
評論
圖片
表情
