文章目录

  • 1、设计函数以传递指针类型的参数
  • 2、 定义一个函数以获取/设置静态局部变量,其作用域限定于该函数,实现类似全局变量的效果,将全局变量隐藏起来
  • 3、在一个.c文件里定义静态全局变量,其作用域限定于该文件,在该文件下定义初始化/获取/设置该静态全局变量的函数,在对应的.h文件里对初始化、获取、设置函数进行声明,实现类似全局变量的效果,将全局变量隐藏起来

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),所以不采用此方式
}

  相关参考资料:
1.结构体直接赋值的实现
2.为何不建议使用全局变量
3.代码规范——全局变量使用规范

c语言中如何避免过多使用全局变量相关推荐

  1. C语言中数据类型的大小以及全局变量和局部变量

    一.数据类型 char //字符数据类型 short //短整型 int //整形 long //长整型 long long //更长的整形 float //单精度浮点型 double //双精度浮点 ...

  2. C语言中全局变量和局部变量,作用域与生命周期的相关问题。

    C语言中变量分为局部变量和全局变量: 在程序的开头定义的是全局变量,在函数内部定义的是局部变量. 在这里涉及2个概念,作用域与生命周期. 作用域指的是描述变量在哪段代码中有效:生命周期指的是变量什么时 ...

  3. C++中不允许重复定义全局变量

    文章目录 1 C++中不允许重复定义全局变量 1 C++中不允许重复定义全局变量 C++中不允许重复定义全局变量: 在C语言中,重复定义多个同名的全局变量是合法的. 在C++中,不允许定义多个同名的全 ...

  4. c语言中.和-区别,c语言中-和.的区别

    对于c语言中"->"和"."的区别总结如下: 1.A.B则A为对象或者结构体: 2.A->B则A为指针,->是成员提取,A->B是提取A ...

  5. c语言全局变量符号,C语言中的 @ 符号是什么意思?

    标签:assign   inter   res   ted   访问内存   变量   出现   read_only   his Global Variable Address Modifier (@ ...

  6. 初始化全局变量实例说明C语言中初始化和未初始化的全局变量所在不同的段

    本文是一篇关于初始化全局变量的帖子 实例说明C语言中初始化和未初始化的全局变量地点不同的段 一个程序: Makefile: objs := bss.oall: bss bss: $(objs)gcc ...

  7. A13在c语言中是合法变量吗,C语言中局部变量和全局变量等在内存中的存放位置.doc-资源下载在线文库www.lddoc.cn...

    C语言中局部变量和全局变量_等在内存中的存放位置.doc C 语言中局部变量和全局变量 变量的存储类别static,extern,auto,register 8.8 局部变量和全局变量在讨论函数的形参 ...

  8. c语言中全局变量内存,C语言——全局变量和局部变量在内存中的区别——及编译后的内存分区【栈-堆-全局存储区-文字常量区-程序代码区】...

    目录: 一:全局变量 二:局部变量 三:C语言经过编译之后将内存分为以下几个区域 (1)栈(stack) (2)堆(heap) (3)全局(静态)存储区 (4)文字常量区 (5)程序代码区 四:区别 ...

  9. C语言中局部变量和全局变量 变量的存储类别

    C语言中局部变量和全局变量 变量的存储类别(static,extern,auto,register)   局部变量和全局变量 在讨论函数的形参变量时曾经提到,形参变量只在被调用期间才分配内存单元,调用 ...

最新文章

  1. 三、CXF对Interceptor拦截器的支持
  2. C#面向对象(一):明确几个简单的概念作为开胃菜
  3. Oracle 原理:用户和权限,Profile,系统权限,对象权限,角色
  4. MySQL的root默认密码修改
  5. vi 多窗口同步滚动--适用于人工文件比较
  6. 我的世界服务器防挂系统,[管理|机制]AFKKicker —— 防挂机!定时要求输入验证码 防止挂机[1.7.10-1.12.2]...
  7. [深度学习]为什么梯度反方向是函数值下降最快的方向?
  8. 《十天学会单片机和C语言编程》
  9. java xml特殊字符转义_Java中将xml文件转化为json遇到特殊字符会报错!
  10. LCDM--商品潜在互补性发现模型
  11. $(document).ready
  12. sql2000下 分页存储过程(一)
  13. Android长截屏(滚动截屏)实现原理
  14. NBA球员数据的爬取
  15. php网站友链直显代码,友情链接代码有哪些 怎么写
  16. 世界杯梦幻阵容HTML5代码,2018俄罗斯世界杯法国队23人大名单一览表
  17. TJX公司:一家不但股价便宜,产品价格也非常便宜的美国低价零售商
  18. 数据可视化工具-Vue-DataV入门
  19. WebMagic爬取码市、猪八戒、一品威客外包数据
  20. Dango Web 开发指南 学习笔记 1

热门文章

  1. seo之h1 h2 h3
  2. Vivado实现异步时钟FIFO -IP核使用
  3. 009仓储物流中心里的人机工程学设计
  4. 关于python多线程,线程锁,线程池开发接口测试脚本真实实例,用于测试时间节约
  5. java memory copy_Java Unsafe.copyMemory java.lang.IllegalArgumentException
  6. 邯郸学院计算机怎样百度,邯郸学院怎么样?为你深度解读邯郸学院。
  7. ehcache 默认大小_ehcache基本原理
  8. 前端显示403的错误
  9. 常用数据库连接URL地址大全
  10. 利用计算机技术执行去自动化,电力调度运行中计算机技术的应用价值与效果