關注+星標公眾號,不錯過精彩內容
作者 |?Marc Pony
鏈接: https://blog.csdn.net/maple_2014/article/details/109541104
全局變量滿天飛的代碼:
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的源代碼如下:
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),所以不采用此方式
}------------?END?------------
關注公眾號回復“加群”按規則加入技術交流群,回復“1024”查看更多內容。
點擊“閱讀原文”查看更多分享。